• API
• FAQ
• Tools
• Archive
SHARE
TWEET

# Untitled

a guest Mar 30th, 2020 137 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. "use strict";
2.
3. let c = document.getElementById("myCanvas");
4. let context = c.getContext("2d");
5.
6. const WIDTH = 500;
7. const HEIGHT = 500;
8.
9. // const CELL_WIDTH = 25;
10. // const CELL_HEIGHT = 25;
11. const CELL_HEIGHT_WIDTH = 25;
12. const CELL_WIDTH = CELL_HEIGHT_WIDTH;
13. const CELL_HEIGHT = CELL_HEIGHT_WIDTH;
14.
15. const MAX_CELL_X = WIDTH / CELL_WIDTH;
16. const MAX_CELL_Y = HEIGHT / CELL_HEIGHT;
17.
18. const TOP = "TOP";
19. const BOTTOM = "BOTTOM";
20. const RIGHT = "RIGHT";
21. const LEFT = "LEFT";
22.
23. let cells = [];
24. let path = [];
25. let finishedPath = [];
26.
27. function sleep(ms) {
28.   return new Promise(resolve => setTimeout(resolve, ms));
29. }
30.
31. function shuffle(array) {
32.   for (let i = array.length - 1; i > 0; i--) {
33.     const j = Math.floor(Math.random() * (i + 1));
34.     [array[i], array[j]] = [array[j], array[i]];
35.   }
36.   return array;
37. }
38.
39. function directionDeltaPos(direction) {
40.   switch (direction) {
41.     case TOP:
42.       return { dx: 0, dy: -1 };
43.     case BOTTOM:
44.       return { dx: 0, dy: 1 };
45.     case RIGHT:
46.       return { dx: 1, dy: 0 };
47.     case LEFT:
48.       return { dx: -1, dy: 0 };
49.     default:
50.       return null;
51.   }
52. }
53.
54. function oppositeDirection(direction) {
55.   switch (direction) {
56.     case TOP:
57.       return BOTTOM;
58.     case BOTTOM:
60.     case RIGHT:
61.       return LEFT;
62.     case LEFT:
63.       return RIGHT;
64.     default:
65.       return null;
66.   }
67. }
68.
69. function checkSizeConstraints(x, y) {
70.   return x >= 0 && y >= 0 && x < MAX_CELL_X && y < MAX_CELL_Y;
71. }
72.
73. class Wall {
74.   constructor(direction) {
75.     this.direction = direction;
76.     this.exists = true;
77.   }
78.
79.   draw(screenX, screenY) {
80.     if (this.exists) {
81.       switch (this.direction) {
82.         case TOP:
83.           context.moveTo(screenX, screenY);
84.           context.lineTo(screenX + CELL_WIDTH, screenY);
85.           break;
86.         case BOTTOM:
87.           context.moveTo(screenX, screenY + CELL_HEIGHT);
88.           context.lineTo(screenX + CELL_WIDTH, screenY + CELL_HEIGHT);
89.           break;
90.         case RIGHT:
91.           context.moveTo(screenX + CELL_WIDTH, screenY);
92.           context.lineTo(screenX + CELL_WIDTH, screenY + CELL_HEIGHT);
93.           break;
94.         case LEFT:
95.           context.moveTo(screenX, screenY);
96.           context.lineTo(screenX, screenY + CELL_HEIGHT);
97.           break;
98.         default:
99.           console.error(`Wall draw() error - x: \${screenX} y: \${screenY}`);
100.           break;
101.       }
102.       context.strokeStyle = "black";
103.       context.stroke();
104.     }
105.   }
106. }
107.
108. class Cell {
109.   walls = [new Wall(TOP), new Wall(RIGHT), new Wall(BOTTOM), new Wall(LEFT)];
110.
111.   constructor(x, y) {
112.     this.start = false;
113.     this.finish = false;
114.     this.visited = false;
115.     this.x = x;
116.     this.y = y;
117.     this.screenX = x * CELL_WIDTH;
118.     this.screenY = y * CELL_HEIGHT;
119.   }
120.
121.   disableWall(direction) {
122.     let wall = this.walls.find(wall => wall.direction === direction);
123.
124.     wall.exists = false;
125.   }
126.
127.   findWall(direction) {
128.     let wall = this.walls.find(wall => wall.direction === direction);
129.     return wall;
130.   }
131.
132.   draw() {
133.     if (this.visited) {
134.       context.fillStyle = "#00FFFF";
135.     } else {
136.       context.fillStyle = "#FFFFFF";
137.     }
138.
139.     if (this.start) context.fillStyle = "#0088FF";
140.     if (this.finish) context.fillStyle = "#8800FF";
141.
142.     context.fillRect(this.screenX, this.screenY, CELL_WIDTH, CELL_HEIGHT);
143.
144.     this.walls.map(wall => {
145.       if (wall.exists) {
146.         wall.draw(this.screenX, this.screenY);
147.       }
148.     });
149.   }
150. }
151.
152. function init() {
153.   for (let i = 0; i < MAX_CELL_X; i++) {
154.     for (let j = 0; j < MAX_CELL_Y; j++) {
155.       cells.push(new Cell(i, j));
156.     }
157.   }
158. }
159.
160. function drawCells(cells) {
161.   cells.map(cell => cell.draw());
162. }
163.
164. async function animateCells(cells) {
165.   for (let i = 0; i < cells.length; i++) {
166.     await sleep(10);
167.     cells[i].draw();
168.   }
169. }
170.
171. function resetCellsVisitedAttr() {
172.   cells.map(cell => (cell.visited = false));
173. }
174.
175. function generateMaze(cell) {
176.   cell.visited = true;
177.
178.   const directions = [TOP, BOTTOM, RIGHT, LEFT];
179.
180.   shuffle(directions);
181.
182.   directions.map(direction => {
183.     const nextX = cell.x + directionDeltaPos(direction).dx;
184.     const nextY = cell.y + directionDeltaPos(direction).dy;
185.
186.     let nextCell = cells.find(cell => cell.x === nextX && cell.y === nextY);
187.
188.     if (checkSizeConstraints(nextX, nextY) && nextCell.visited === false) {
189.       cell.disableWall(direction);
190.       nextCell.disableWall(oppositeDirection(direction));
191.
192.       generateMaze(nextCell);
193.     }
194.   });
195. }
196.
197. function solveMaze(cell) {
198.   cell.visited = true;
199.
200.   if (cell.finish) {
201.     finishedPath = [...path];
202.     return;
203.   }
204.
205.   const directions = [TOP, BOTTOM, RIGHT, LEFT];
206.   shuffle(directions);
207.
208.   directions.map(direction => {
209.     const nextX = cell.x + directionDeltaPos(direction).dx;
210.     const nextY = cell.y + directionDeltaPos(direction).dy;
211.     let nextCell = cells.find(cell => cell.x === nextX && cell.y === nextY);
212.     const wall = cell.findWall(direction);
213.
214.     if (
215.       checkSizeConstraints(nextX, nextY) &&
216.       !wall.exists &&
217.       !nextCell.visited
218.     ) {
219.       path.push(cell);
220.       solveMaze(nextCell);
221.       path.pop();
222.     }
223.   });
224. }
225.
226. function maze() {
227.   init();
228.   cells[0].start = true;
229.   cells[cells.length - 1].finish = true;
230.   generateMaze(cells.find(cell => cell.start));
231.
232.   resetCellsVisitedAttr();
233.   drawCells(cells);
234.   solveMaze(cells.find(cell => cell.start));
235.   animateCells(finishedPath);
236. }
237.
238. maze();
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy.
Top