-
Notifications
You must be signed in to change notification settings - Fork 2
/
conway_game_of_life.html
93 lines (79 loc) · 2.28 KB
/
conway_game_of_life.html
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
<!doctype html>
<script src="./code/18_http.js"></script>
<div id="grid"></div>
<button id="next">Next generation</button>
<button id="run">Auto run</button>
<script>
const width = 30, height = 15;
// Grid will be represented as an array of booleans
let gridNode = document.querySelector('#grid');
// This holds the checkboxes that display the grid in the document
let checkboxes = [];
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
let box = document.createElement("input");
box.type = "checkbox";
gridNode.appendChild(box);
checkboxes.push(box);
}
gridNode.appendChild(document.createElement("br"));
}
function gridFromCheckboxes () {
return checkboxes.map(box => box.checked);
}
function checkboxesFromGrid (grid) {
grid.forEach((value, i) => checkboxes[i].checked = value);
}
function randomGrid () {
let result = [];
for (let i = 0; i < width * height; i++) {
result.push(Math.random() < 0.3);
}
return result;
}
checkboxesFromGrid(randomGrid());
// This does a two-dimensional loop over the square around the given
// x, y position, counting all fields that have a cell but are not the
// center field.
function countNeighbors(grid, x, y) {
let count = 0;
for (let y1 = Math.max(0, y - 1); y1 <= Math.min(height - 1, y + 1); y1++) {
for (let x1 = Math.max(0, x - 1); x1 <= Math.min(width - 1, x + 1); x1++) {
if ((x1 != x || y1 != y) && grid[x1 + y1 * width]) {
count++;
}
}
}
return count;
}
function nextGeneration (grid) {
let newGrid = new Array(width * height);
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
let neighbors = countNeighbors(grid, x, y);
let offset = x + y * width;
if (neighbors < 2 || neighbors > 3) {
newGrid[offset] = false;
} else if (neighbors == 2) {
newGrid[offset] = grid[offset];
} else {
newGrid[offset] = true;
}
}
}
return newGrid;
}
function turn () {
checkboxesFromGrid(nextGeneration(gridFromCheckboxes()));
}
document.querySelector('#next').addEventListener('click', turn);
let running = null;
document.querySelector('#run').addEventListener('click', () => {
if (running) {
clearInterval(running);
running = null;
} else {
running = setInterval(turn, 400);
}
});
</script>