Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- "use strict";
- let c = document.getElementById("myCanvas");
- let context = c.getContext("2d");
- const WIDTH = 500;
- const HEIGHT = 500;
- // const CELL_WIDTH = 25;
- // const CELL_HEIGHT = 25;
- const CELL_HEIGHT_WIDTH = 25;
- const CELL_WIDTH = CELL_HEIGHT_WIDTH;
- const CELL_HEIGHT = CELL_HEIGHT_WIDTH;
- const MAX_CELL_X = WIDTH / CELL_WIDTH;
- const MAX_CELL_Y = HEIGHT / CELL_HEIGHT;
- const TOP = "TOP";
- const BOTTOM = "BOTTOM";
- const RIGHT = "RIGHT";
- const LEFT = "LEFT";
- let cells = [];
- let path = [];
- let finishedPath = [];
- function sleep(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
- }
- function shuffle(array) {
- for (let i = array.length - 1; i > 0; i--) {
- const j = Math.floor(Math.random() * (i + 1));
- [array[i], array[j]] = [array[j], array[i]];
- }
- return array;
- }
- function directionDeltaPos(direction) {
- switch (direction) {
- case TOP:
- return { dx: 0, dy: -1 };
- case BOTTOM:
- return { dx: 0, dy: 1 };
- case RIGHT:
- return { dx: 1, dy: 0 };
- case LEFT:
- return { dx: -1, dy: 0 };
- default:
- return null;
- }
- }
- function oppositeDirection(direction) {
- switch (direction) {
- case TOP:
- return BOTTOM;
- case BOTTOM:
- return TOP;
- case RIGHT:
- return LEFT;
- case LEFT:
- return RIGHT;
- default:
- return null;
- }
- }
- function checkSizeConstraints(x, y) {
- return x >= 0 && y >= 0 && x < MAX_CELL_X && y < MAX_CELL_Y;
- }
- class Wall {
- constructor(direction) {
- this.direction = direction;
- this.exists = true;
- }
- draw(screenX, screenY) {
- if (this.exists) {
- switch (this.direction) {
- case TOP:
- context.moveTo(screenX, screenY);
- context.lineTo(screenX + CELL_WIDTH, screenY);
- break;
- case BOTTOM:
- context.moveTo(screenX, screenY + CELL_HEIGHT);
- context.lineTo(screenX + CELL_WIDTH, screenY + CELL_HEIGHT);
- break;
- case RIGHT:
- context.moveTo(screenX + CELL_WIDTH, screenY);
- context.lineTo(screenX + CELL_WIDTH, screenY + CELL_HEIGHT);
- break;
- case LEFT:
- context.moveTo(screenX, screenY);
- context.lineTo(screenX, screenY + CELL_HEIGHT);
- break;
- default:
- console.error(`Wall draw() error - x: ${screenX} y: ${screenY}`);
- break;
- }
- context.strokeStyle = "black";
- context.stroke();
- }
- }
- }
- class Cell {
- walls = [new Wall(TOP), new Wall(RIGHT), new Wall(BOTTOM), new Wall(LEFT)];
- constructor(x, y) {
- this.start = false;
- this.finish = false;
- this.visited = false;
- this.x = x;
- this.y = y;
- this.screenX = x * CELL_WIDTH;
- this.screenY = y * CELL_HEIGHT;
- }
- disableWall(direction) {
- let wall = this.walls.find(wall => wall.direction === direction);
- wall.exists = false;
- }
- findWall(direction) {
- let wall = this.walls.find(wall => wall.direction === direction);
- return wall;
- }
- draw() {
- if (this.visited) {
- context.fillStyle = "#00FFFF";
- } else {
- context.fillStyle = "#FFFFFF";
- }
- if (this.start) context.fillStyle = "#0088FF";
- if (this.finish) context.fillStyle = "#8800FF";
- context.fillRect(this.screenX, this.screenY, CELL_WIDTH, CELL_HEIGHT);
- this.walls.map(wall => {
- if (wall.exists) {
- wall.draw(this.screenX, this.screenY);
- }
- });
- }
- }
- function init() {
- for (let i = 0; i < MAX_CELL_X; i++) {
- for (let j = 0; j < MAX_CELL_Y; j++) {
- cells.push(new Cell(i, j));
- }
- }
- }
- function drawCells(cells) {
- cells.map(cell => cell.draw());
- }
- async function animateCells(cells) {
- for (let i = 0; i < cells.length; i++) {
- await sleep(10);
- cells[i].draw();
- }
- }
- function resetCellsVisitedAttr() {
- cells.map(cell => (cell.visited = false));
- }
- function generateMaze(cell) {
- cell.visited = true;
- const directions = [TOP, BOTTOM, RIGHT, LEFT];
- shuffle(directions);
- directions.map(direction => {
- const nextX = cell.x + directionDeltaPos(direction).dx;
- const nextY = cell.y + directionDeltaPos(direction).dy;
- let nextCell = cells.find(cell => cell.x === nextX && cell.y === nextY);
- if (checkSizeConstraints(nextX, nextY) && nextCell.visited === false) {
- cell.disableWall(direction);
- nextCell.disableWall(oppositeDirection(direction));
- generateMaze(nextCell);
- }
- });
- }
- function solveMaze(cell) {
- cell.visited = true;
- if (cell.finish) {
- finishedPath = [...path];
- return;
- }
- const directions = [TOP, BOTTOM, RIGHT, LEFT];
- shuffle(directions);
- directions.map(direction => {
- const nextX = cell.x + directionDeltaPos(direction).dx;
- const nextY = cell.y + directionDeltaPos(direction).dy;
- let nextCell = cells.find(cell => cell.x === nextX && cell.y === nextY);
- const wall = cell.findWall(direction);
- if (
- checkSizeConstraints(nextX, nextY) &&
- !wall.exists &&
- !nextCell.visited
- ) {
- path.push(cell);
- solveMaze(nextCell);
- path.pop();
- }
- });
- }
- function maze() {
- init();
- cells[0].start = true;
- cells[cells.length - 1].finish = true;
- generateMaze(cells.find(cell => cell.start));
- resetCellsVisitedAttr();
- drawCells(cells);
- solveMaze(cells.find(cell => cell.start));
- animateCells(finishedPath);
- }
- maze();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement