-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmaze.js
293 lines (280 loc) · 7.89 KB
/
maze.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/* TODO:
-i think algo works well enough so... ✓
-draw actual maze using final grid ✓
-Add player + movement ✓
-finish function checkIfValid ✓
-fin?
*/
/*
-each cell: 50x50
-each cell contains a denary integer, when converted to binary will show which
walls are present.
*/
//Prevents arrow key scrolling:
window.addEventListener("keydown", function(e) {
// space and arrow keys
if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
e.preventDefault();
}
}, false);
//LOGIC (maze):
let visited = {} //object that holds visited cells, acts as global var
function generateMaze() {
var grid = [
// 0 1 2 3 4 5 6 7 8 9
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //0
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //1
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //2
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //3
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //4
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //5
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //6
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //7
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //8
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15], //9
]; // acts as global (due to 'var')
let initial = [Math.floor(Math.random()*10), Math.floor(Math.random()*10)];
let key = initial[0].toString()+initial[1].toString();
visited[parseInt(key)] = true;
backtracker(initial, grid);
return grid;
};
function backtracker(current, grid) {
let unvisitedCells = unvisited(current);
while (unvisitedCells.length > 0) {
let randChoice = Math.floor(Math.random()*unvisitedCells.length);
let chosen = unvisitedCells.splice(randChoice, 1);
chosen = chosen[0];
let tmpCheck = (chosen[0]).toString()+(chosen[1]).toString();
if (visited[parseInt(tmpCheck)] !== true) {
removeWall(current, chosen, grid);
let tmpKey = (chosen[0]).toString()+(chosen[1]).toString();
visited[parseInt(tmpKey)] = true;
backtracker(chosen, grid);
};
};
};
//e.g. unvisited([5, 4], dict)
function unvisited(cell) { // returns an array of unvisited cells/indexes (empty if all visited)
let out = [];
if (cell[0] !== 0) { //if cell not at the top of grid
let tmpKey = (cell[0]-1).toString()+(cell[1]).toString();
if (visited[parseInt(tmpKey)] !== true) {
out.push([cell[0]-1,cell[1]]);
};
};
if (cell[1] !== 9) { //if cell not at right edge of grid
let tmpKey = (cell[0]).toString()+(cell[1]+1).toString();
if (visited[parseInt(tmpKey)] !== true) {
out.push([cell[0],cell[1]+1]);
};
};
if (cell[0] !== 9) { //if cell not at bottom of grid
let tmpKey = (cell[0]+1).toString()+(cell[1]).toString();
if (visited[parseInt(tmpKey)] !== true) {
out.push([cell[0]+1,cell[1]]);
};
};
if (cell[1] !== 0) { //if cell not at left edge of grid
let tmpKey = (cell[0]).toString()+(cell[1]-1).toString();
if (visited[parseInt(tmpKey)] !== true) {
out.push([cell[0],cell[1]-1]);
};
};
return out;
};
function removeWall(current, chosen, grid) {
if (chosen[0] > current[0]) { //i.e. if chosen is below current
grid[current[0]][current[1]] -= 4;
grid[chosen[0]][chosen[1]] -= 1;
} else if (chosen[0] < current[0]) { //i.e. if chosen is above current
grid[current[0]][current[1]] -= 1;
grid[chosen[0]][chosen[1]] -= 4;
} else if (chosen[1] < current[1]) { //i.e. if chosen is to left of current
grid[current[0]][current[1]] -= 8;
grid[chosen[0]][chosen[1]] -= 2;
} else if (chosen[1] > current[1]) { //i.e. if chosen is to right of current
grid[current[0]][current[1]] -= 2;
grid[chosen[0]][chosen[1]] -= 8;
};
};
function fourBitBinary(number) {
let tmp = number.toString(2);
while (tmp.length < 4) {
tmp = "0" + tmp;
}
return tmp;
} // returns a four bit binary number (as a string)
//VISUALS:
//some global scope variables:
let playerX = 25;
let playerY = 25;
let gridLogic; // array that holds grid
let won = false;
function setup() {
let cnv = createCanvas(500, 500);
cnv.parent("mazeCanvas");
rect(0, 0, 500, 500);
noLoop(); //draw does not repeatedly execute
};
function draw() {
background(254);
gridLogic = generateMaze();
let x = 0;
let y = 0;
for (let array of gridLogic) {
for (let num of array) {
let binStr = fourBitBinary(num);
if (binStr[3] === "1") {
line(x, y, (x+50), y);
}
if (binStr[0] === "1") {
line(x, y, x, (y+50));
}
x += 50;
}
x = 0;
y += 50;
}
line(500, 0, 500, 500);
line(0, 500, 500, 500);
fill('red');
circle(playerX, playerY, 25);
fill('green');
triangle(475, 490, 460, 470, 490, 470);
};
function keyPressed() {
if (keyCode === 32) { //if spacebar was pressed:
won = false;
playerX = 25;
playerY = 25;
visited = {};
clear();
redraw();
} else if (won) {
return;
} else if (keyCode === RIGHT_ARROW && checkIfValid(2)) { //move right
noStroke();
fill(255);
circle(playerX, playerY, 30);
stroke(1);
fill('red');
playerX += 50;
circle(playerX, playerY, 25);
} else if (keyCode === LEFT_ARROW && checkIfValid(4)) { //move left
noStroke();
fill(255);
circle(playerX, playerY, 30);
stroke(1);
fill('red');
playerX -= 50;
circle(playerX, playerY, 25);
} else if (keyCode === UP_ARROW && checkIfValid(1)) { //move up
noStroke();
fill(255);
circle(playerX, playerY, 30);
stroke(1);
fill('red');
playerY -= 50;
circle(playerX, playerY, 25);
} else if (keyCode === DOWN_ARROW && checkIfValid(3)) { //move down
noStroke();
fill(255);
circle(playerX, playerY, 30);
stroke(1);
fill('red');
playerY += 50;
circle(playerX, playerY, 25);
}
let distance = dist(playerX, playerY, 475, 490);
if (distance <= 30) {
textSize(32);
text('You win!', 55, 180);
text('(Press space to play again)', 55, 230);
won = true;
}
}
//MOVEMENT CHECKS:
function checkIfValid(num) { //1 - up, 2 - right, 3 - down, 4 - left,
let xIndex = (playerX+25)/50 - 1;
let yIndex = (playerY+25)/50 - 1;
let binaryStr = fourBitBinary(gridLogic[yIndex][xIndex]);
console.log(xIndex, yIndex, gridLogic[yIndex][xIndex], binaryStr);
if (num === 1) {
if (binaryStr[3] === "1") {
return false;
} else {
return true;
}
} else if (num === 2) {
if (binaryStr[2] === "1") {
return false;
} else {
return true;
}
} else if (num === 3) {
if (binaryStr[1] === "1") {
return false;
} else {
return true;
}
} else if (num === 4) {
if (binaryStr[0] === "1") {
return false;
} else {
return true;
}
}
}
//Simulate a key press on button press.
function simulateKey(keyCode) {
if (keyCode === "SPACEBAR") { //if spacebar was pressed:
won = false;
playerX = 25;
playerY = 25;
visited = {};
clear();
redraw();
} else if (won) {
return;
} else if (keyCode === "RIGHT_ARROW" && checkIfValid(2)) { //move right
noStroke();
fill(255);
circle(playerX, playerY, 30);
stroke(1);
fill('red');
playerX += 50;
circle(playerX, playerY, 25);
} else if (keyCode === "LEFT_ARROW" && checkIfValid(4)) { //move left
noStroke();
fill(255);
circle(playerX, playerY, 30);
stroke(1);
fill('red');
playerX -= 50;
circle(playerX, playerY, 25);
} else if (keyCode === "UP_ARROW" && checkIfValid(1)) { //move up
noStroke();
fill(255);
circle(playerX, playerY, 30);
stroke(1);
fill('red');
playerY -= 50;
circle(playerX, playerY, 25);
} else if (keyCode === "DOWN_ARROW" && checkIfValid(3)) { //move down
noStroke();
fill(255);
circle(playerX, playerY, 30);
stroke(1);
fill('red');
playerY += 50;
circle(playerX, playerY, 25);
}
let distance = dist(playerX, playerY, 475, 490);
if (distance <= 30) {
textSize(32);
text('You win!', 55, 180);
text('(Press space to play again)', 55, 230);
won = true;
}
}