2d logics fully ready (me think)

This commit is contained in:
Ali Gator 2022-01-02 16:45:03 +01:00
parent 1a14e2d028
commit 74e9667c51
4 changed files with 105 additions and 92 deletions

View File

@ -7,6 +7,25 @@
<h1>Cellular Automata Explorer</h1> <h1>Cellular Automata Explorer</h1>
<div id="container"> <div id="container">
<sidebar> <sidebar>
<div class="menu-row">
<h2> Cell Properties</h2>
<div class="menu-row-content">
<form>
<div class="form-field">
<label for="live">Living cell color</label>
<input name="live" type="color" id="live" value="#000000"/>
</div>
<div class="form-field">
<label for="dead">Dead cell color</label>
<input name="dead" type="color" id="dead" value="#AA78E8"/>
</div>
<div class="form-field">
<label>Cell size</label>
<input name="cellSize" type="number" id="cellSize" value="5"/>
</div>
</form>
</div>
</div>
<div class="menu-row"> <div class="menu-row">
<h2>Elementary Cellular Automata</h2> <h2>Elementary Cellular Automata</h2>
<div class="menu-row-content"> <div class="menu-row-content">
@ -56,31 +75,8 @@
</div> </div>
<div class="form-field"> <div class="form-field">
<input type="button" name="start" id="start" value="start"/> <input type="button" name="start" id="start" value="start"/>
</div> <input type="button" name="stop" class="stop" value="stop"/>
<div class="form-field"> <input type="button" name="reset" class="reset" value="reset"/>
<input type="button" name="stop" id="stop" value="stop"/>
</div>
<div class="form-field">
<input type="button" name="reset" id="reset" value="reset"/>
</div>
</form>
<form>
<div class="form-field">
<label for="live">Living cell color</label>
<input name="live" type="color" id="live" value="#000000"/>
</div>
<div class="form-field">
<label for="dead">Dead cell color</label>
<input name="dead" type="color" id="dead" value="#AA78E8"/>
</div>
<div class="form-field">
<label>Cell size</label>
<input name="cellSize" type="number" id="cellSize" value="5"/>
</div>
<div class="form-field">
<label>Loop
<input name="loop" type="checkbox" id="loop"/>
</label>
</div> </div>
</form> </form>
</div> </div>
@ -91,12 +87,8 @@
<form> <form>
<div class="form-field"> <div class="form-field">
<input type="button" name="start2d" id="start2d" value="start"/> <input type="button" name="start2d" id="start2d" value="start"/>
</div> <input type="button" name="stop" class="stop" value="stop"/>
<div class="form-field"> <input type="button" name="reset" class="reset" value="reset"/>
<input type="button" name="stop2d" id="stop2d" value="stop"/>
</div>
<div class="form-field">
<input type="button" name="reset2d" id="reset2d" value="reset"/>
</div> </div>
</form> </form>
</div> </div>

View File

@ -6,7 +6,7 @@ function guard(index, array) {
} }
// get the next evolution of a 1D CA initial state // get the next evolution of a 1D CA initial state
function evolve(state, rules) { function evolve1d(state, rules) {
function getCell(index) { function getCell(index) {
const safeIndex = guard(index, state); const safeIndex = guard(index, state);
return state[safeIndex]; return state[safeIndex];
@ -26,7 +26,7 @@ function evolve(state, rules) {
function createBoard(state, rules, height) { function createBoard(state, rules, height) {
function createBoardAcc(s, h, acc) { function createBoardAcc(s, h, acc) {
if (h === 0) return acc; if (h === 0) return acc;
const newState = evolve(s, rules); const newState = evolve1d(s, rules);
const newAcc = acc.concat([s]); const newAcc = acc.concat([s]);
return createBoardAcc(newState, h - 1, newAcc); return createBoardAcc(newState, h - 1, newAcc);
} }
@ -118,5 +118,5 @@ function initialState2d(width, height, initFn, args) {
} }
export { export {
getDrawingValues, initialState1d, initialState2d, evolve, evolve2d, conwayRules, createBoard, getDrawingValues, initialState1d, initialState2d, evolve1d, evolve2d, conwayRules, createBoard,
}; };

View File

@ -1,7 +1,6 @@
// TODO : Change board resolution according to the set cell dimensions
import { getRandomInt, sleep } from './common.js'; import { getRandomInt, sleep } from './common.js';
import { import {
evolve, evolve2d, getDrawingValues, initialState1d, initialState2d, conwayRules, createBoard, evolve2d, initialState1d, initialState2d, conwayRules, createBoard,
} from './automata.js'; } from './automata.js';
let drawing = 1; let drawing = 1;
@ -12,16 +11,30 @@ const ctx = canvas.getContext('2d');
const main = document.querySelector('#main'); const main = document.querySelector('#main');
const dead = document.querySelector('#dead'); const dead = document.querySelector('#dead');
const live = document.querySelector('#live'); const live = document.querySelector('#live');
const cellSize = document.querySelector('#cellSize');
const startBtn = document.querySelector('#start'); const startBtn = document.querySelector('#start');
const startBtn2d = document.querySelector('#start2d'); const startBtn2d = document.querySelector('#start2d');
const resetBtn = document.querySelector('#reset'); const resetBtn = document.querySelectorAll('.reset');
const stopBtn = document.querySelector('#stop'); const stopBtn = document.querySelectorAll('.stop');
const cellSize = document.querySelector('#cellSize'); // const loop = document.querySelector('#loop');
const loop = document.querySelector('#loop');
const menuRow = document.querySelectorAll('.menu-row'); const menuRow = document.querySelectorAll('.menu-row');
canvas.width = main.offsetWidth * 0.9; function drawCanvas(board, props) {
canvas.height = main.offsetHeight * 0.9; board.map((row, y) => {
const d = props.size;
return row.map(
(cell, x) => {
ctx.fillStyle = (
() => {
if (cell === 1) return props.liveColor;
return props.deadColor;
})();
ctx.fillRect(x * d, y * d, d, d);
return cell;
},
);
});
}
function getRules() { function getRules() {
const rules = {}; const rules = {};
@ -38,60 +51,55 @@ function getRules() {
return rules; return rules;
} }
function getCellProperties() {
return {
size: cellSize.value,
liveColor: live.value,
deadColor: dead.value,
};
}
function reset() { function reset() {
drawing = 0; drawing = 0;
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
} }
async function draw(dimension) { function resizeCanvas() {
if (drawing === 0) { canvas.width = main.offsetWidth * 0.9;
return; canvas.height = main.offsetHeight * 0.9;
} }
async function draw1d() {
const rules = getRules(); const rules = getRules();
const props = getCellProperties();
const cellProperties = { const initialState = initialState1d(
dimensions: cellSize.value, Math.floor(canvas.width / props.size),
liveColor: live.value,
deadColor: dead.value,
};
const initialState = (
() => {
if (dimension === '1d') {
return initialState1d(
Math.floor(canvas.width / cellProperties.dimensions),
getRandomInt, getRandomInt,
[0, 2], [0, 2],
); );
} const board = createBoard(initialState, rules, Math.floor(canvas.height / props.size));
return evolve2d(initialState2d(
Math.floor(canvas.width / cellProperties.dimensions), drawCanvas(board, props);
Math.floor(canvas.height / cellProperties.dimensions), }
async function draw2d() {
const props = getCellProperties();
const initialState = initialState2d(
Math.floor(canvas.width / props.size),
Math.floor(canvas.height / props.size),
getRandomInt, getRandomInt,
[0, 2]), conwayRules); [0, 2],
})();
const board = (
() => {
if (dimension === '1d') return createBoard(initialState, rules, Math.floor(canvas.height / cellProperties.dimensions));
return initialState;
})();
board.map((row, y) => {
const d = cellProperties.dimensions;
return row.map(
(cell, x) => {
ctx.fillStyle = (
() => {
if (cell === 1) return cellProperties.liveColor;
return cellProperties.deadColor;
})();
ctx.fillRect(x * d, y * d, d, d);
return cell;
},
); );
}); const board = evolve2d(initialState, conwayRules);
async function draw2dNext(b) {
if (drawing === 0) return;
const newBoard = evolve2d(b, conwayRules);
drawCanvas(b, props);
await sleep(300);
draw2dNext(newBoard);
}
return draw2dNext(board);
} }
// Listeners // Listeners
@ -103,7 +111,7 @@ startBtn.addEventListener('click', async () => {
drawing = 1; drawing = 1;
draw('1d'); draw1d();
}); });
startBtn2d.addEventListener('click', async () => { startBtn2d.addEventListener('click', async () => {
@ -113,15 +121,19 @@ startBtn2d.addEventListener('click', async () => {
drawing = 1; drawing = 1;
draw('2d'); draw2d();
}); });
resetBtn.addEventListener('click', async () => { resetBtn.forEach((elem) => {
elem.addEventListener('click', async () => {
reset(); reset();
});
}); });
stopBtn.addEventListener('click', async () => { stopBtn.forEach((elem) => {
elem.addEventListener('click', async () => {
drawing = 0; drawing = 0;
});
}); });
menuRow.forEach((elem) => { menuRow.forEach((elem) => {
@ -132,3 +144,11 @@ menuRow.forEach((elem) => {
else menuDisplay.setProperty('display', 'block'); else menuDisplay.setProperty('display', 'block');
}); });
}); });
window.addEventListener('load', () => {
resizeCanvas();
});
window.addEventListener('resize', () => {
resizeCanvas();
});

View File

@ -40,6 +40,7 @@ input[type="button"] {
min-width: 60px; min-width: 60px;
padding: 5px; padding: 5px;
font-weight: bold; font-weight: bold;
margin-right: 10px;
} }
.form-field { .form-field {