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>
<div id="container">
<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">
<h2>Elementary Cellular Automata</h2>
<div class="menu-row-content">
@ -56,31 +75,8 @@
</div>
<div class="form-field">
<input type="button" name="start" id="start" value="start"/>
</div>
<div class="form-field">
<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>
<input type="button" name="stop" class="stop" value="stop"/>
<input type="button" name="reset" class="reset" value="reset"/>
</div>
</form>
</div>
@ -91,12 +87,8 @@
<form>
<div class="form-field">
<input type="button" name="start2d" id="start2d" value="start"/>
</div>
<div class="form-field">
<input type="button" name="stop2d" id="stop2d" value="stop"/>
</div>
<div class="form-field">
<input type="button" name="reset2d" id="reset2d" value="reset"/>
<input type="button" name="stop" class="stop" value="stop"/>
<input type="button" name="reset" class="reset" value="reset"/>
</div>
</form>
</div>

View File

@ -6,7 +6,7 @@ function guard(index, array) {
}
// get the next evolution of a 1D CA initial state
function evolve(state, rules) {
function evolve1d(state, rules) {
function getCell(index) {
const safeIndex = guard(index, state);
return state[safeIndex];
@ -26,7 +26,7 @@ function evolve(state, rules) {
function createBoard(state, rules, height) {
function createBoardAcc(s, h, acc) {
if (h === 0) return acc;
const newState = evolve(s, rules);
const newState = evolve1d(s, rules);
const newAcc = acc.concat([s]);
return createBoardAcc(newState, h - 1, newAcc);
}
@ -118,5 +118,5 @@ function initialState2d(width, height, initFn, args) {
}
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 {
evolve, evolve2d, getDrawingValues, initialState1d, initialState2d, conwayRules, createBoard,
evolve2d, initialState1d, initialState2d, conwayRules, createBoard,
} from './automata.js';
let drawing = 1;
@ -12,16 +11,30 @@ const ctx = canvas.getContext('2d');
const main = document.querySelector('#main');
const dead = document.querySelector('#dead');
const live = document.querySelector('#live');
const cellSize = document.querySelector('#cellSize');
const startBtn = document.querySelector('#start');
const startBtn2d = document.querySelector('#start2d');
const resetBtn = document.querySelector('#reset');
const stopBtn = document.querySelector('#stop');
const cellSize = document.querySelector('#cellSize');
const loop = document.querySelector('#loop');
const resetBtn = document.querySelectorAll('.reset');
const stopBtn = document.querySelectorAll('.stop');
// const loop = document.querySelector('#loop');
const menuRow = document.querySelectorAll('.menu-row');
canvas.width = main.offsetWidth * 0.9;
canvas.height = main.offsetHeight * 0.9;
function drawCanvas(board, props) {
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() {
const rules = {};
@ -38,60 +51,55 @@ function getRules() {
return rules;
}
function getCellProperties() {
return {
size: cellSize.value,
liveColor: live.value,
deadColor: dead.value,
};
}
function reset() {
drawing = 0;
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
async function draw(dimension) {
if (drawing === 0) {
return;
function resizeCanvas() {
canvas.width = main.offsetWidth * 0.9;
canvas.height = main.offsetHeight * 0.9;
}
async function draw1d() {
const rules = getRules();
const cellProperties = {
dimensions: cellSize.value,
liveColor: live.value,
deadColor: dead.value,
};
const initialState = (
() => {
if (dimension === '1d') {
return initialState1d(
Math.floor(canvas.width / cellProperties.dimensions),
const props = getCellProperties();
const initialState = initialState1d(
Math.floor(canvas.width / props.size),
getRandomInt,
[0, 2],
);
const board = createBoard(initialState, rules, Math.floor(canvas.height / props.size));
drawCanvas(board, props);
}
return evolve2d(initialState2d(
Math.floor(canvas.width / cellProperties.dimensions),
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,
[0, 2]), conwayRules);
})();
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;
},
[0, 2],
);
});
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
@ -103,7 +111,7 @@ startBtn.addEventListener('click', async () => {
drawing = 1;
draw('1d');
draw1d();
});
startBtn2d.addEventListener('click', async () => {
@ -113,16 +121,20 @@ startBtn2d.addEventListener('click', async () => {
drawing = 1;
draw('2d');
draw2d();
});
resetBtn.addEventListener('click', async () => {
resetBtn.forEach((elem) => {
elem.addEventListener('click', async () => {
reset();
});
});
stopBtn.addEventListener('click', async () => {
stopBtn.forEach((elem) => {
elem.addEventListener('click', async () => {
drawing = 0;
});
});
menuRow.forEach((elem) => {
elem.querySelector('h2').addEventListener('click', async (e) => {
@ -132,3 +144,11 @@ menuRow.forEach((elem) => {
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;
padding: 5px;
font-weight: bold;
margin-right: 10px;
}
.form-field {