// m13 life model: the whole world is one value, like the snake and the match. /** @typedef {{x: number, y: number}} Point */ /** @typedef {{cells: Point[], running: boolean, seed: number, generation: number}} LifeState */ /** @typedef {{tag: 'Frame'} | {tag: 'Toggle', cell: Point} | {tag: 'TogglePause'} | {tag: 'Step'} | {tag: 'Clear'} | {tag: 'Randomize'}} LifeAction */ // The board, in cells: LW columns, LH rows, LCELL pixels per cell. Below it the page shows a status strip. export const LW = 40 export const LH = 30 /** Pixels per cell. */ export const LCELL = 16 /** Height of the status strip under the board, in pixels. */ export const STRIP = 24 /** A fresh world: no live cells, paused, the given seed, generation 0. * @type {(seed: number) => LifeState} */ export const initialLife = (seed) => ({ cells: [], running: false, seed, generation: 0 }) /** Everything that can happen to the world, as data. `Toggle` carries the cell that was clicked. * @type {{Frame: LifeAction, Toggle: (cell: Point) => LifeAction, TogglePause: LifeAction, Step: LifeAction, Clear: LifeAction, Randomize: LifeAction}} */ export const LifeAction = { Frame: { tag: 'Frame' }, Toggle: (cell) => ({ tag: 'Toggle', cell }), TogglePause: { tag: 'TogglePause' }, Step: { tag: 'Step' }, Clear: { tag: 'Clear' }, Randomize: { tag: 'Randomize' }, }