2d logics fully ready (me think)
This commit is contained in:
parent
1a14e2d028
commit
74e9667c51
@ -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>
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
128
src/js/main.js
128
src/js/main.js
@ -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();
|
||||||
|
});
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user