-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconway.js
149 lines (118 loc) · 3.81 KB
/
conway.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
/* Conways game of life
For a space that is 'populated':
Each cell with one or no neighbors dies, as if by solitude.
Each cell with four or more neighbors dies, as if by overpopulation.
Each cell with two or three neighbors survives.
For a space that is 'empty' or 'unpopulated'
Each cell with three neighbors becomes populated.
*/
function range(...args) {
let start;
let end;
let step;
if (args.length == 1) {
start = 0;
end = args[0];
step = 1;
} else if (args.length == 2) {
start = args[0];
end = args[1];
step = 1;
} else {
start = args[0];
end = args[1];
step = args[2] || 1;
}
let ret = [];
for (let i = start; i < end; i += step) {
ret.push(i);
}
return ret;
}
function centerPad(str, len, char=" ") {
const rem = len - str.length;
const left = Math.floor(rem / 2);
const right = rem - left;
return Array.from(new Array(left), _ => char).concat(Array.from(str)).concat(Array.from(new Array(right), _ => char));
}
function rangeIn(...args) {
if (args.length > 1) {
return range(args[0], args[1] + 1, args[2]);
} else {
return range(args[0] + 1);
}
}
function random(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
function Grid(rows, cols, positions) {
const colBorder = "|";
const rowBorder = "-";
const fill = "\u2588";
const empty = " ";
const matrix = range(rows).map(_ => Array.from(new Array(cols), _ => empty))
const coords = range(0, rows).map(i => range(0, cols).map(j => [i, j])).reduce((a, b) => a.concat(b));
for (let [i, j] of positions) matrix[i][j] = fill;
function bordered() {
const copy = matrix.slice();
const rowBordering = [" "].concat(range(cols).map(_ => rowBorder)).concat([" "]);
range(rows).map(i => {
let col = matrix[i].slice();
col.push(colBorder);
col.unshift(colBorder);
copy[i] = col;
});
copy.push(rowBordering);
copy.unshift(rowBordering);
copy.push(centerPad("We are hiring!", cols + 2))
copy.push(centerPad('http://www.sytac.nl/vacatures/', cols + 2));
copy.push(centerPad("", cols + 2));
copy.push(centerPad("Please use Firefox if you are experiencing glitches", cols + 2));
copy.push(centerPad("", cols + 2));
return copy;
}
function neighbors(row, col) {
return (
rangeIn(row - 1, row + 1).map(i =>
rangeIn(col - 1, col + 1).map(j => [i, j]))
.reduce((a, b) => a.concat(b))
.filter(([i, j]) => inBounds(i, j) && (i !== row || j !== col)));
}
function neighborCount() {
const copy = matrix.map(_ => _.map(_ => 0));
cells().map(([i, j]) => neighbors(i, j).map(([_i, _j]) => copy[_i][_j] += 1));
return copy;
}
function show() { return bordered().map(_ => _.join("")).join("\n");}
function inBounds(i, j) { return i >= 0 && i < rows && j >= 0 && j < cols; }
function isFull(i, j) { return matrix[i][j] === fill; }
function isEmpty(i, j) { return !isFull(i, j);}
function cells() { return coords.filter(([i, j]) => isFull(i, j));}
function mapCell(fn) { return cells().map(fn);}
function lonely(nc) { return coords.filter(([i, j]) => nc[i][j] <= 1);}
function packed(nc) { return coords.filter(([i, j]) => nc[i][j] >= 4);}
function expected(nc) { return coords.filter(([i, j]) => nc[i][j] === 3);}
function c2s([i, j]) { return i + "," + j;}
return {
evolve() {
const nc = neighborCount();
const toKill = new Set(lonely(nc).concat(packed(nc)).map(c2s));
const toCreate = expected(nc);
let newCoords = coords.filter(([i, j]) => !toKill.has(c2s([i, j])) && isFull(i, j)).concat(toCreate);
return Grid(rows, cols, newCoords);
},
show
}
}
function evolve(grid) {
range(10).map(_ => {
grid = grid.evolve();
grid.print();
});
}
window.Grid = Grid;
// const rows = 6;
// const cols = 6;
// var grid = Grid(rows, cols, [[1, 1], [1, 2], [2, 1], [2, 2], [3, 3], [3, 4], [4, 3], [4, 4]]);