UNPKG

games-of-life

Version:

Create any Game of Life variation

91 lines (78 loc) 2.19 kB
/** * Counts alive cells nearby. * * @param {Function} getNeighboursOf * @param {Function} isAlive * @param {*} cell * @returns {Number} count */ export function countAliveNeighbours (getNeighboursOf, isAlive, cell) { return getNeighboursOf(cell).filter(isAlive).length } /** * Implements the following rules. * * 1. Any live cell with fewer than `a` live neighbours dies, as if caused by under-population. * 2. Any live cell with `a` or `b` live neighbours lives on to the next generation. * 3. Any live cell with more than `b` live neighbours dies, as if by overcrowding. * 4. Any dead cell with exactly `c` live neighbours becomes a live cell, as if by reproduction. * * where in the classic *Game of Life*, * * ``` * a = 2 * b = 3 * c = 3 * ``` * * @param {Number} a under population threshold * @param {Number} b over crowding threshold * @param {Number} c reproduction value * @param {Function} getNeighboursOf * @param {Function} isAlive * * @returns {Function} nextStatusOf (cell) */ export function classicTransitionRule (a, b, c, getNeighboursOf, isAlive) { const countAliveNeighboursOf = countAliveNeighbours.bind(null, getNeighboursOf, isAlive) /** * @param {*} cell * @returns {Boolean} status */ return function nextStatusOf (cell) { const numNeighboursAlive = countAliveNeighboursOf(cell) if (isAlive(cell)) { return ((numNeighboursAlive >= a) && (numNeighboursAlive <= b)) } else { return (numNeighboursAlive === c) } } } /** * Create a GoL world. * * @param {Function} getNeighboursOf * @returns {Function} world */ export function createWorld (getNeighboursOf) { /** * @param {Function} transitionRule * @returns {Function} evolve */ return function world (transitionRule) { /** * @param {Function} isAliveNow * @returns {Function} isAliveNext */ return function evolve (isAliveNow) { const nextStatusOf = transitionRule(getNeighboursOf, isAliveNow) /** * @param {*} cell * @returns {Boolean} status of the cell */ return function isAliveNext (cell) { return nextStatusOf(cell) } } } }