// TODO: Hide accumulator inside function evolve(state, acc, rules) { const [x, y, z, ...xs] = state; if (!xs.length) { return acc[acc.length - 1] + acc + acc[0]; } const rule = x + y + z; const newAcc = acc.concat(rules[rule]); return evolve(y + z + xs.join(''), newAcc, rules); } function conwayRules(cell, neighbors) { // loneliness rule if (cell === 1 && neighbors < 2) return 0; // overpopulation rule if (cell === 1 && neighbors > 3) return 0; // born when three live neighbors rule if (cell === 0 && neighbors === 3) return 1; // the cell remains the same if none apply return cell; } function getDrawingValues(state, acc, cell) { const d = cell.dimension; return Object.keys(state).map( (key) => { const fillStyle = state[key] === '1' ? cell.liveColor : cell.deadColor; return { move: [key * d, acc * d], fill: [key * d, acc * d, d, d], fillStyle, }; }, ); } function initialState1D(width, initFn, args) { return [...Array(width)].map( () => initFn(...args).toString(), ).join(''); } function initialState2D(width, height, initFn, args) { return [...Array(height)].map( () => [...Array(width)].map(() => initFn(...args)), ); } export { evolve, getDrawingValues, initialState1D, initialState2D, };