-
Notifications
You must be signed in to change notification settings - Fork 3
/
life.js
153 lines (138 loc) · 3.69 KB
/
life.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
import { glider, nextState } from "./lifeCommon.js";
import { Command, GUI, Integer, Key, Control } from "../libraries/gui/gui.js";
import { getLargeCanvas } from "../libraries/misc.js";
// Simple and non-optimised (no hashlife) version of Conway's Game of Life. You
// can control cell size with i (increase) and d (decrease). Use c to toggle an
// overlay with the current cell size
const sketch = (s) => {
const gapX = 10;
const gapY = 10;
let rectSize = 10;
let cells,
rows,
columns,
cnt = 0;
let stateMatrix = [],
nextStateMatrix = [];
let gui;
s.setup = () => {
let { w, h } = getLargeCanvas(s, 1600);
let canvas = s.createCanvas(w, h);
canvas.mousePressed(() => {
// Touch to add a glider. Why not
let i = s.int(s.mouseX / rectSize);
let j = s.int(s.mouseY / rectSize);
glider(i, j, stateMatrix, rows, columns);
});
s.frameRate(20);
setupMatrix();
randomise();
gui = createGUI();
gui.toggle();
};
function setupMatrix() {
// Prepares two empty arrays to store states (current and next)
columns = s.int(s.windowWidth / rectSize);
rows = s.int(s.windowHeight / rectSize);
stateMatrix = Array(columns);
nextStateMatrix = Array(columns);
for (let i = 0; i < columns; i++) {
stateMatrix[i] = Array(rows).fill(0);
nextStateMatrix[i] = Array(rows).fill(0);
}
// Prepares a static indexer, somehow this runs faster on iOS Safari than
// usual for loops. Go figure
cells = [];
for (let j = 0; j < rows; j++) {
for (let i = 0; i < columns; i++) {
cells.push([i, j]);
}
}
}
function randomise() {
// Randomise current state matrix
for (let cell of cells) {
let [i, j] = cell;
stateMatrix[i][j] = s.int(s.random(2));
}
}
s.draw = () => {
s.rectMode(s.CENTER);
s.strokeWeight(2);
s.stroke(60, 60, 30);
for (let cell of cells) {
let [i, j] = cell;
s.push();
s.translate(gapX / 2 + i * rectSize, gapY / 2 + j * rectSize);
s.beginShape();
if (stateMatrix[i][j] == 1) {
s.fill(20, 20, 20);
} else {
s.fill(100, 100, 100);
}
nextStateMatrix[i][j] = nextState(i, j, stateMatrix, rows, columns);
s.rect(0, 0, rectSize, rectSize);
s.endShape();
s.pop();
}
// Advance states and clean next
for (let cell of cells) {
let [i, j] = cell;
stateMatrix[i][j] = nextStateMatrix[i][j];
nextStateMatrix[i][j] = 0;
}
};
function createGUI() {
let info = `Tap/click on the canvas generate a glider`;
let subinfo = "";
let G = new Key("g", () => {
setupMatrix();
glider(
s.int(s.random(rows)),
s.int(s.random(columns)),
stateMatrix,
rows,
columns,
);
});
let resetCanvas = new Command(
G,
"clear the canvas and place a random glider",
);
let incR = new Key(")", () => {
rectSize++;
setupMatrix();
randomise();
});
let decR = new Key("(", () => {
if (rectSize > 4) {
rectSize--;
}
setupMatrix();
randomise();
});
let rectSizeInt = new Integer(() => rectSize);
let rectSizeControl = new Control(
[decR, incR],
"+/- cell size",
rectSizeInt,
);
let gui = new GUI(
"Conway's Game of Life, RB 2020/05",
info,
subinfo,
[resetCanvas],
[rectSizeControl],
);
let QM = new Key("?", () => gui.toggle());
let hide = new Command(QM, "hide this");
gui.addCmd(hide);
gui.update();
return gui;
}
s.keyReleased = () => {
gui.dispatch(s.key);
};
};
p5.disableFriendlyErrors = true;
let p5sketch = new p5(sketch);