Automata

by wio_dude

HTML

<canvas id="canvas"></canvas>
<div id="inputs">

  <input id="randomize" type="button" value="Randomize" />
  <br />
  <label for="speed">Speed</label>
  <input id="speed" type="range" min="1" max="10" value="10" />
</div>
<br />
<textarea id="debug" cols="30" rows="10"></textarea>

CSS

canvas {
   background-color: lightgrey;
}

#inputs {
  float: right;
}

JavaScript

const CENTER = 4;
const TOP = CENTER - 3;
const BOTTOM = CENTER + 3;
const LEFT = CENTER - 1;
const RIGHT = CENTER + 1;
const TOP_LEFT = TOP - 1;
const TOP_RGIHT = TOP + 1;
const BOTTOM_LEFT = BOTTOM - 1;
const BOTTOM_RIGHT = BOTTOM + 1;

const ids = [
  'canvas',
  'randomize',
  'speed',
  'debug',
];
const $e = {};
for (const id of ids) {
  $e[id] = document.getElementById(id);
}

$e.randomize.addEventListener('click', () => {
	randomizeCells();
})

const ctx = $e.canvas.getContext('2d');


const cellTypes = {
  empty: [0, 0, 0, 0],
  static: [0, 255, 0, 255],
  fluid: [0, 0, 255, 255],
};

const imageData = new ImageData($e.canvas.width, $e.canvas.height);

const cells = new Array($e.canvas.width * $e.canvas.height);
const automata = {
  buffer: new Array(cells.length),
  cells,
  width: $e.canvas.width,
};

function updateAutomata(automata) {
  for (const [i, cell] of automata.cells.entries()) {
    automata.buffer[i] = cell;
    const row = Math.floor(i / automata.width);
    const col = i % automata.width;
    const neighbor = [
    	row !== 0 && col !== 0 ? automata.cells[i - 1 - automata.width] : 'none',
    	row !== 0 ? automata.cells[i - automata.width] : 'none',
    	'none',
    	'none',
    	'none',
    	'none',
    	'none',
    	'none',
    	'none',
    ];
    const topCellI = i - automata.width;
    const topCell = topCellI > 0 ? automata.cells[topCellI] : 'empty';
    const topRightCellI = topCellI + 1;
    const topRightCell = topRightCellI % automata.width === 0 ? automata.cells[topRightCellI] : 'static';
    const topLeftCellI = topCellI - 1;
    const topLeftCell = topRightCellI % automata.width === automata.width - 1 ? automata.cells[topLeftCellI] : 'static';
    const botCellI = i + automata.width;
    const botCell = botCellI < automata.cells.length ? automata.cells[botCellI] : 'static';
    switch (cell) {
      case 'empty':
        if (topCell === 'static') {
          automata.buffer[i] = 'static';
        } else if (topCell ===...