-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
115 lines (101 loc) · 2.88 KB
/
app.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
let width = 300
let height = 300
let cellSize = 2
let mutation = 0
let grid, ctx, canvas
let stats = {
generation: 0,
alive: 0
}
function init () {
// Prepare canvas
canvas = document.createElement('canvas')
canvas.width = width * cellSize + 1
canvas.height = height * cellSize + 1
document.getElementById('game').appendChild(canvas)
ctx = canvas.getContext('2d')
ctx.translate(0.5, 0.5)
// Prepare grid
stats.generation = 1
grid = []
for (let x = 0; x < width; x++) {
grid[x] = []
for (let y = 0; y < height; y++) {
grid[x][y] = Math.random() > 0.6 ? 1 : 0
stats.alive += grid[x][y] ? 1 : 0
}
}
// Let's play
play()
}
function draw () {
// Clear
ctx.clearRect(0, 0, canvas.width, canvas.height)
// Gridlines
ctx.lineWidth = 0.5
ctx.strokeStyle = '#888'
ctx.beginPath()
for (let x = 0; x <= width * cellSize; x += cellSize) {
ctx.moveTo(x, 0)
ctx.lineTo(x, height * cellSize)
}
for (let y = 0; y <= height * cellSize; y += cellSize) {
ctx.moveTo(0, y)
ctx.lineTo(width * cellSize, y)
}
ctx.stroke()
// Draw cells
ctx.fillStyle = '#000'
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
if (grid[x][y]) {
ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize)
}
}
}
}
function nextgen () {
stats.generation++
stats.alive = 0
let nextGrid = []
for (let x = 0; x < width; x++) {
nextGrid[x] = []
for (let y = 0; y < height; y++) {
let mutate = Math.random() < mutation
let alive = [
grid[(width + x - 1) % width][(height + y - 1) % height],
grid[(width + x) % width][(height + y - 1) % height],
grid[(width + x + 1) % width][(height + y - 1) % height],
grid[(width + x - 1) % width][(height + y) % height],
grid[(width + x + 1) % width][(height + y) % height],
grid[(width + x - 1) % width][(height + y + 1) % height],
grid[(width + x) % width][(height + y + 1) % height],
grid[(width + x + 1) % width][(height + y + 1) % height]
].reduce((prev, curr) => (curr ? 1 : 0) + prev, 0)
nextGrid[x][y] = (grid[x][y] && (mutate || (alive === 2 || alive === 3))) || (!grid[x][y] && alive === 3) ? 1 : 0
stats.alive += nextGrid[x][y] ? 1 : 0
}
}
grid = nextGrid
}
function printStats () {
let statsContainer = document.getElementById('stats')
statsContainer.innerHTML =
`Generation: ${stats.generation}<br>` +
`Alive: ${stats.alive} (${parseInt(stats.alive / (width * height) * 10000) / 100.00}%)`
}
function play () {
draw()
printStats()
nextgen()
setTimeout(play, 50)
}
// Helpers
function registerEvent (element, event, handler, capture) {
if (/msie/i.test(navigator.userAgent)) {
element.attachEvent('on' + event, handler)
} else {
element.addEventListener(event, handler, capture)
}
}
registerEvent(window, 'load', () => init())