diff --git a/index.html b/index.html
index b9a8038..39be899 100644
--- a/index.html
+++ b/index.html
@@ -12,36 +12,44 @@
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
@@ -54,13 +62,17 @@
diff --git a/main.js b/main.js
index a8078b8..fff0790 100644
--- a/main.js
+++ b/main.js
@@ -1,25 +1,19 @@
let drawing = 1;
const form = Array.from(document.forms.rules.elements);
-const canvas = document.getElementById('canvas');
-const main = document.getElementById('main');
+const canvas = document.querySelector('#canvas');
+const ctx = canvas.getContext('2d');
+const main = document.querySelector('#main');
+const dead = document.querySelector('#dead');
+const live = document.querySelector('#live');
+const startBtn = document.querySelector('#start');
+const resetBtn = document.querySelector('#reset');
+const cellSize = document.querySelector('#cellSize');
+
canvas.width = main.offsetWidth;
canvas.height = main.offsetHeight;
-const dead = document.getElementById('dead');
-const live = document.getElementById('live');
-
-function getRandomInt(min, max) {
- min = Math.ceil(min);
- max = Math.floor(max);
- // The maximum is exclusive and the minimum is inclusive
- return Math.floor(Math.random() * (max - min) + min);
-}
-
-function sleep(ms) {
- return new Promise((resolve) => setTimeout(resolve, ms));
-}
-
+// TODO: Hide iterator inside
function evolve(state, acc, rules) {
const [x, y, z, ...xs] = state;
if (!xs.length) {
@@ -31,56 +25,89 @@ function evolve(state, acc, rules) {
return evolve(y + z + xs.join(''), newAcc, rules);
}
-function draw(state, context, acc) {
- const cellDim = 5;
+function getRules() {
+ const rules = {};
- Object.keys(state).forEach(
+ form.reduce((_, i) => {
+ if (i !== undefined
+ && i.type === 'checkbox') {
+ if (i.checked) rules[i.name] = '1';
+ else rules[i.name] = '0';
+ }
+ return rules;
+ }, rules);
+
+ return rules;
+}
+
+function getDrawingValues(state, acc) {
+ const cellDim = cellSize.value;
+
+ return Object.keys(state).map(
(key) => {
- context.moveTo(key * cellDim, acc * cellDim);
- context.fillRect(key * cellDim, acc * cellDim, cellDim, cellDim);
- if (state[key] === '1') context.fillStyle = live.value;
- else context.fillStyle = dead.value;
+ const fillStyle = state[key] === '1' ? live.value : dead.value;
+ return {
+ move: [key * cellDim, acc * cellDim],
+ fill: [key * cellDim, acc * cellDim, cellDim, cellDim],
+ fillStyle,
+ };
},
);
}
-const start = document.getElementById('start');
+function getRandomInt(min, max) {
+ const minVal = Math.ceil(min);
+ const maxVal = Math.floor(max);
+ // The maximum is exclusive and the minimum is inclusive
+ return Math.floor(Math.random() * (maxVal - minVal) + minVal);
+}
+
+async function sleep(ms) {
+ await new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+async function draw(state, acc) {
+ if (drawing === 0) {
+ return;
+ }
+
+ const rules = getRules();
+ const newState = evolve(state, '', rules);
+ const line = getDrawingValues(newState, acc);
+
+ line.map((cell) => {
+ ctx.moveTo(...cell.move);
+ ctx.fillRect(...cell.fill);
+ ctx.fillStyle = cell.fillStyle;
+ return cell;
+ });
+
+ await sleep(40);
+
+ // TODO: makes it redraw on top of canvas once bottom is reached
+ const newAcc = acc < canvas.height ? acc + 1 : 1;
+ await draw(newState, newAcc);
+}
+
+function reset() {
+ drawing = 0;
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+}
+
+startBtn.addEventListener('click', async () => {
+ reset();
+
+ await sleep(60);
-start.addEventListener('click', async () => {
drawing = 1;
- const rules = form.reduce((a, i) => {
- if (i !== undefined
- && i.type === 'checkbox') {
- if (i.checked) a[i.name] = '1';
- else a[i.name] = '0';
- }
- return a;
- }, {});
-
- const ctx = canvas.getContext('2d');
const initialState = [...Array(canvas.width)].map(
- (_) => getRandomInt(0, 2).toString(),
+ () => getRandomInt(0, 2).toString(),
).join('');
- let newState = evolve(initialState, '', rules);
- let acc = 0;
-
- while (acc < canvas.width) {
- if (drawing === 0) {
- break;
- }
- draw(newState, ctx, acc);
- newState = evolve(newState, '', rules);
- acc += 1;
- await sleep(60);
- }
+ draw(initialState, 1);
});
-const reset = document.getElementById('reset');
-
-reset.addEventListener('click', async () => {
- drawing = 0;
- const ctx = canvas.getContext('2d');
- ctx.clearRect(0, 0, canvas.width, canvas.height);
+resetBtn.addEventListener('click', async () => {
+ reset();
});