Лабиринт без циклов

13 Sep 2016 | JavaScript

labyrinth

See on GitHub

index.php

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta charset="UTF-8">
    <style>
        * {
            padding: 0;
            margin: 0;
        }
    </style>
</head>
<body>

<div>
    <canvas id="field"></canvas>
</div>

<script src="app.js"></script>
</body>
</html>

app.js

// Field
var field;

// Field options
const CELLSIZE = 10;
const MAXROW = 57;
const MAXCOL = 135;

// Player
var successful = false;

var playerRow = 1;
var playerCol = 1;

var finishRow = MAXROW - 2;
var finishCol = MAXCOL - 2;

document.addEventListener('DOMContentLoaded', function () {
    // Create a field with initial elements
    field = makeStartFiled();

    // Paving the routes
    trace(1, 1);

    // Display the field
    renderField();
});

// Movement of the player
window.addEventListener("keydown", function (event) {
    var keyCode = event.keyCode;

    var newPlayerRow = playerRow;
    var newPlayerCol = playerCol;

    switch (keyCode) {
        case 87:
        case 38:
            // w, up
            newPlayerRow--;
            break;
        case 68:
        case 39:
            // d, right
            newPlayerCol++;
            break;
        case 83:
        case 40:
            // s, down
            newPlayerRow++;
            break;
        case 65:
        case 37:
            // a, left
            newPlayerCol--;
            break;
    }

    if (successful === false && field[newPlayerRow][newPlayerCol] === 0) {
        playerRow = newPlayerRow;
        playerCol = newPlayerCol;

        renderField();

        if (playerRow === finishRow && playerCol === finishRow) {
            successful = true;
            alert('Victory!');
        }
    }
});

function makeStartFiled() {
    var field = new Array();
    for (var row = 0; row < MAXROW; row++) {
        field[row] = new Array();

        for (var col = 0; col < MAXCOL; col++) {
            // Default value
            field[row][col] = 1;

            // Field borders
            if (row === 0 || row === MAXROW - 1 || col === 0 || col === MAXCOL - 1) {
                field[row][col] = 3;
            }

            // Turning points of the route
            if (field[row][col] === 1 && row % 2 === 0 && col % 2 === 0) {
                field[row][col] = 2;
            }

            // Place of appearance of the player
            if (row === playerRow && col === playerCol) {
                field[row][col] = 0;
            }
        }
    }

    return field;
}

function trace(headerRow, headerCol) {
    var newHeaderDirArr = [0, 1, 2, 3];

    do {
        var newHeaderRow1x = headerRow;
        var newHeaderRow2x = headerRow;
        var newHeaderCol1x = headerCol;
        var newHeaderCol2x = headerCol;

        var newHeaderDir = newHeaderDirArr[Math.floor(Math.random() * newHeaderDirArr.length)];
        newHeaderDirArr.splice(newHeaderDirArr.indexOf(newHeaderDir), 1);

        switch (newHeaderDir) {
            case 0:
                newHeaderRow1x = headerRow - 1;
                newHeaderRow2x = headerRow - 2;
                break;
            case 1:
                newHeaderCol1x = headerCol + 1;
                newHeaderCol2x = headerCol + 2;
                break;
            case 2:
                newHeaderRow1x = headerRow + 1;
                newHeaderRow2x = headerRow + 2;
                break;
            case 3:
                newHeaderCol1x = headerCol - 1;
                newHeaderCol2x = headerCol - 2;
                break;
        }

        if (
            1 <= newHeaderRow2x &&
            newHeaderRow1x <= MAXROW - 1 &&
            1 <= newHeaderCol2x &&
            newHeaderCol2x <= MAXCOL - 1 &&

            field[newHeaderRow1x][newHeaderCol1x] === 1 &&
            field[newHeaderRow2x][newHeaderCol2x] === 1
        ) {
            field[newHeaderRow1x][newHeaderCol1x] = 0;
            field[newHeaderRow2x][newHeaderCol2x] = 0;

            trace(newHeaderRow2x, newHeaderCol2x);
        } else if (newHeaderDirArr.length === 0) {
            return;
        }
    } while (newHeaderDirArr.length > 0);
}

function renderField() {
    var field_html = document.getElementById("field"),
        ctx = field_html.getContext('2d');

    field_html.width = MAXCOL * CELLSIZE;
    field_html.height = MAXROW * CELLSIZE;

    for (var row = 0; row < MAXROW; row++) {
        for (var col = 0; col < MAXCOL; col++) {
            // Free field
            if (field[row][col] === 0) {
                ctx.fillStyle = '#ffffff';
                ctx.fillRect(col * CELLSIZE, row * CELLSIZE, CELLSIZE, CELLSIZE);
            }

            // Inner borders
            if (field[row][col] === 1) {
                ctx.fillStyle = '#212121';
                ctx.fillRect(col * CELLSIZE, row * CELLSIZE, CELLSIZE, CELLSIZE);
            }

            // Turning points
            if (field[row][col] === 2) {
                ctx.fillStyle = '#212121';
                ctx.fillRect(col * CELLSIZE, row * CELLSIZE, CELLSIZE, CELLSIZE);
            }

            // Outer borders
            if (field[row][col] === 3) {
                ctx.fillStyle = '#212121';
                ctx.fillRect(col * CELLSIZE, row * CELLSIZE, CELLSIZE, CELLSIZE);
            }

            // Finish field
            if (row === finishRow && col === finishCol) {
                ctx.fillStyle = '#f44336';
                ctx.fillRect(col * CELLSIZE, row * CELLSIZE, CELLSIZE, CELLSIZE);
            }

            // Player position
            if (row === playerRow && col === playerCol) {
                ctx.fillStyle = '#4caf50';
                ctx.fillRect(col * CELLSIZE, row * CELLSIZE, CELLSIZE, CELLSIZE);
            }
        }
    }
}