diff --git a/index.html b/index.html
index 77be7ff..b9a8038 100644
--- a/index.html
+++ b/index.html
@@ -1,19 +1,72 @@
- Cellular automata
-
+ Cellular Automaton Explorer
+
-
+
+ Cellular Automaton Explorer
+
+
+
+
+
+
diff --git a/main.js b/main.js
index 94931e5..a8078b8 100644
--- a/main.js
+++ b/main.js
@@ -1,77 +1,86 @@
-'use strict';
+let drawing = 1;
-const rules = {
- "111": "0",
- "110": "1",
- "101": "0",
- "100": "1",
- "011": "1",
- "010": "0",
- "001": "1",
- "000": "0"
-}
+const form = Array.from(document.forms.rules.elements);
+const canvas = document.getElementById('canvas');
+const main = document.getElementById('main');
+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);
+ return Math.floor(Math.random() * (max - min) + min);
}
function sleep(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
+ return new Promise((resolve) => setTimeout(resolve, ms));
}
-function evolve(state, acc) {
+function evolve(state, acc, rules) {
const [x, y, z, ...xs] = state;
if (!xs.length) {
- return acc[0] + acc + acc[acc.length - 1]
- }
- else {
- const rule = x + y + z;
- const new_acc = acc.concat(rules[rule]);
- return evolve(y + z + xs.join(""), new_acc)
+ return acc[acc.length - 1] + acc + acc[0];
}
+
+ const rule = x + y + z;
+ const newAcc = acc.concat(rules[rule]);
+ return evolve(y + z + xs.join(''), newAcc, rules);
}
function draw(state, context, acc) {
- const cell_dim = 2
+ const cellDim = 5;
Object.keys(state).forEach(
- function (key) {
- context.moveTo(key * cell_dim, acc * cell_dim)
- context.fillRect(key * cell_dim, acc * cell_dim, cell_dim, cell_dim)
- if(state[key] == "1") {
- context.fillStyle="black";
- }else {
- if (acc % 2) {
- context.fillStyle="white";
- }else {
- context.fillStyle="white";
- }
- }
- })
+ (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;
+ },
+ );
}
-window.addEventListener("load", async function() {
- const canvas = document.getElementById("canvas")
- canvas.width = window.innerWidth
- canvas.height = window.innerHeight
- const ctx = canvas.getContext("2d")
+const start = document.getElementById('start');
- const initial_state = [...Array(canvas.width)].map(
- _=> getRandomInt(0, 2).toString()
- ).join("")
+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;
+ }, {});
- console.log("initial state length : ", initial_state.length)
+ const ctx = canvas.getContext('2d');
- var new_state = evolve(initial_state, "")
- var acc = 0
-
- while(acc < canvas.width) {
- draw(new_state, ctx, acc)
- new_state = evolve(new_state, "")
- acc++
- await sleep(100)
+ const initialState = [...Array(canvas.width)].map(
+ (_) => 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);
}
-})
+});
+
+const reset = document.getElementById('reset');
+
+reset.addEventListener('click', async () => {
+ drawing = 0;
+ const ctx = canvas.getContext('2d');
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+});
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..25a8f8e
--- /dev/null
+++ b/style.css
@@ -0,0 +1,39 @@
+* {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background: black;
+ color: white;
+ display: flex;
+ font-family: Courier New;
+}
+
+h1 {
+ font-size: large;
+ font-weight: bold;
+}
+
+sidebar {
+ flex: auto;
+ padding: 10px;
+}
+
+.form-field {
+ display: flex;
+ margin: 10px;
+}
+
+.menu-row {
+ flex: 1;
+}
+
+label, .form-field label {
+ margin-right: 10px;
+ font-weight: bold;
+}
+
+#main {
+ flex: 4;
+}