diff --git a/src/components/CanvasBoard.vue b/src/components/CanvasBoard.vue index d624fde..c2f3373 100644 --- a/src/components/CanvasBoard.vue +++ b/src/components/CanvasBoard.vue @@ -22,6 +22,8 @@ createBoard, conwayRules, overpopulationRules, + lonelinessRules, + threebornRules, evolve2d, } from "../modules/automata.js"; import { getRandomInt, sleep } from "../modules/common.js"; @@ -38,6 +40,8 @@ available2dRules: { conway: conwayRules, overpopulation: overpopulationRules, + loneliness: lonelinessRules, + threeborn: threebornRules, }, }; }, @@ -89,9 +93,10 @@ mounted() { this.canvas = Object.freeze(document.getElementById("board-canvas")); this.workCanvas = Object.freeze(document.getElementById("work-canvas")); - this.ctx = this.canvas.getContext("2d"); - this.workCtx = this.workCanvas.getContext("2d"); - this.workCanvas.setAttribute("willReadFrequently", true); + this.ctx = this.canvas.getContext("2d", { willReadFrequently: true }); + this.workCtx = this.workCanvas.getContext("2d", { + willReadFrequently: true, + }); this.canvasWidth = this.canvas.parentElement.clientWidth; this.canvasHeight = this.canvas.parentElement.clientHeight; this.setBoardWidth(); @@ -135,7 +140,7 @@ this.drawCanvas(this.lastBoard); this.toggleStop(); }, - // draw 2D automaton on the canvas (currently only the game of life) + // draw 2D automaton on the canvas in a loop draw2d(board) { if (!this.canDraw) return; const draw2dNext = async (b) => { @@ -145,6 +150,7 @@ this.available2dRules[this.selected2dRules.id] ); this.drawCanvas(b, this.cellProperties); + this.lastBoard = Object.freeze(newBoard); await sleep(this.refreshRate); draw2dNext(newBoard); }; diff --git a/src/modules/automata.js b/src/modules/automata.js index 42e5f63..ac4df56 100644 --- a/src/modules/automata.js +++ b/src/modules/automata.js @@ -91,6 +91,28 @@ function conwayRules(cell, neighbors) { return cell; } +// variation on the game of life's rules, +// where the "three live neighbors" rule is ignored +function threebornRules(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 + return cell; +} + +// variation on the game of life's rules, +// where the loneliness rule is ignored +function lonelinessRules(cell, neighbors) { + // 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; +} + // variation on the game of life's rules, // where the overpopulation rule is ignored function overpopulationRules(cell, neighbors) { @@ -160,6 +182,8 @@ export { create1dStateOneCell, conwayRules, overpopulationRules, + lonelinessRules, + threebornRules, evolve1d, evolve2d, }; diff --git a/src/modules/preset.js b/src/modules/preset.js index 0a5b26f..922aab0 100644 --- a/src/modules/preset.js +++ b/src/modules/preset.js @@ -104,6 +104,18 @@ const preset2dRules = [ description: "Variation on Conway's Game of Life *without* the overpopulation rule", }, + { + id: "loneliness", + name: "Loneliness variation", + description: + "Variation on Conway's Game of Life *without* the loneliness rule", + }, + { + id: "threeborn", + name: "Three lives variation", + description: + "Variation on Conway's Game of Life *without* the 'three live neighbors' rule", + }, ]; export { presetRuleset, initialStates, preset2dRules };