-
Notifications
You must be signed in to change notification settings - Fork 0
/
maze.ts
115 lines (90 loc) · 3.34 KB
/
maze.ts
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
const tile_size = 16;
class Edge {
left: number;
right: number;
constructor(left: number, right: number) {
this.left = left;
this.right = right;
}
}
//i can just use an array of pairs of connections.
class Maze {
width: number;
height: number;
edges: Edge[];
constructor(width: number, height: number) {
this.width = width;
this.height = height;
this.edges = <Edge[]> new Array();
this.generateMaze();
}
public generateMaze = () : void => {
let visited: boolean[] = new Array(this.width * this.height);
let stack: number[] = new Array();
for (let i = 0; i < visited.length; i++) {
visited[i] = false;
}
let current_cell: number = 0;
visited[current_cell] = true;
while(!visited.every((x) => x == true)) {
//get the neighbours and filter out the visited ones.
let neighbours: number[] = this.getNeighbours(current_cell).filter((x) => !visited[x]);
if (neighbours.length > 0) {
let chosen_neighbour = choose_random(neighbours);
stack.push(current_cell);
//link current_cell and chosen_neighbour together
this.edges.push(new Edge(current_cell, chosen_neighbour));
current_cell = chosen_neighbour;
visited[current_cell] = true;
} else {
current_cell = stack.pop();
}
}
}
//TODO: work out a quicker way of doing this.
public getNeighbours = (index: number) : number[] => {
let x = index % this.width;
let y = (index - x) / this.width;
let neighbours:number[] = new Array();
if (x > 0) {
neighbours.push((x - 1) + y * this.width);
}
if (y > 0) {
neighbours.push(x + (y - 1) * this.width);
}
if (x < this.width - 1) {
neighbours.push((x + 1) + y * this.width);
}
if (y < this.width - 1) {
neighbours.push(x + (y + 1) * this.width);
}
return neighbours;
}
public draw = (ctx:CanvasRenderingContext2D ) : void => {
//clear the screen
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 656, 656);
ctx.fillStyle = "white";
for (let i = 0; i < this.edges.length; i++) {
let x1 = this.edges[i].left % this.width;
let y1 = (this.edges[i].left - x1) / this.width;
ctx.fillRect(2*x1 *tile_size + tile_size, 2*y1*tile_size + tile_size, tile_size, tile_size);
let x2 = this.edges[i].right % this.width;
let y2 = (this.edges[i].right - x2) / this.width;
ctx.fillRect(2*x2*tile_size + tile_size, 2*y2*tile_size + tile_size, tile_size, tile_size);
ctx.fillRect((x1+x2)*tile_size + tile_size, (y1+y2)*tile_size + tile_size, tile_size, tile_size);
}
}
}
function choose_random(choices) {
var index = Math.floor(Math.random() * choices.length);
return choices[index];
}
window.onload = () => {
let canvas = <HTMLCanvasElement>document.getElementById("cnvs");
let ctx = canvas.getContext("2d");
let width = (canvas.width-tile_size)/(2*tile_size);
let height = (canvas.height-tile_size)/(2*tile_size);
let maze = new Maze(width, height);
maze.draw(ctx);
}