From 89723351988fc66af37acfd205ae43cf1c587af2 Mon Sep 17 00:00:00 2001 From: Gator Date: Tue, 6 Dec 2022 17:41:32 +0100 Subject: [PATCH 1/9] test load picture on canvas --- src/components/CanvasBoard.vue | 20 ++++++++++++++- src/components/Menu2dCA.vue | 40 ++++++++++++++++++++++++----- src/components/MenuElementaryCA.vue | 11 +++++--- src/components/MenuRow.vue | 6 ++++- src/stores/index.js | 9 +++++++ 5 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/components/CanvasBoard.vue b/src/components/CanvasBoard.vue index f7ce42f..9291b1c 100644 --- a/src/components/CanvasBoard.vue +++ b/src/components/CanvasBoard.vue @@ -38,8 +38,10 @@ getDraw1d: "draw1d", getDraw2d: "draw2d", getDraw2dLast: "draw2dLast", + getDraw2dPicture: "draw2dpicture", boardWidth: "boardWidth", boardHeight: "boardHeight", + picture: "picture", }), ...mapWritableState(globalStore, { lastBoard: "lastBoard", @@ -62,6 +64,9 @@ getDraw2dLast(value) { if (value == true) this.draw2dLast(); }, + getDraw2dPicture(value) { + if (value == true) this.draw2dPicture(); + }, getReset(value) { if (value == true) this.reset(); }, @@ -137,9 +142,22 @@ this.draw2d(board); }, // draw 2d automaton from the last known generated board - async draw2dLast() { + draw2dLast() { if (this.lastBoard != undefined) this.draw2d(this.lastBoard); }, + // draw 2d automaton from an uploaded picture + draw2dPicture(e) { + this.picture.width = this.canvas.width; + this.picture.height = this.canvas.height; + this.ctx.drawImage( + this.picture, + 0, + 0, + this.canvas.width, + this.canvas.height + ); + this.toggleStop(); + }, // stop drawing routines and clear the canvas reset() { this.toggleStop(); diff --git a/src/components/Menu2dCA.vue b/src/components/Menu2dCA.vue index 58a410b..2653cfa 100644 --- a/src/components/Menu2dCA.vue +++ b/src/components/Menu2dCA.vue @@ -15,14 +15,14 @@

- - + +
diff --git a/src/modules/automata.js b/src/modules/automata.js index 8ed51a5..42e5f63 100644 --- a/src/modules/automata.js +++ b/src/modules/automata.js @@ -91,6 +91,17 @@ function conwayRules(cell, neighbors) { return cell; } +// variation on the game of life's rules, +// where the overpopulation rule is ignored +function overpopulationRules(cell, neighbors) { + // loneliness rule + if (cell === 1 && neighbors < 2) 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; +} + // get the next evolution of a 2D CA initial state // Rules : Moore neighborhood function evolve2d(board, rulesFn) { @@ -148,6 +159,7 @@ export { createBoard, create1dStateOneCell, conwayRules, + overpopulationRules, evolve1d, evolve2d, }; diff --git a/src/modules/preset.js b/src/modules/preset.js index 0eee491..0a5b26f 100644 --- a/src/modules/preset.js +++ b/src/modules/preset.js @@ -92,4 +92,18 @@ const initialStates = [ }, ]; -export { presetRuleset, initialStates }; +const preset2dRules = [ + { + id: "conway", + name: "Conway's Game of Life", + description: "The most popular 2d automata", + }, + { + id: "overpopulation", + name: "Overpopulation variation", + description: + "Variation on Conway's Game of Life *without* the overpopulation rule", + }, +]; + +export { presetRuleset, initialStates, preset2dRules }; diff --git a/src/stores/index.js b/src/stores/index.js index 255cfdb..cd81b56 100644 --- a/src/stores/index.js +++ b/src/stores/index.js @@ -16,6 +16,11 @@ export const globalStore = defineStore("globalStore", { "000": 1, }, }, + selected2dRules: { + id: "conway", + name: "Conway's Game of Life", + description: "The most popular 2d automata", + }, cellProperties: { size: 3, liveColor: "#000000", From 2d57acd0a5bac95836b1938b345c1e8e55ecf0bb Mon Sep 17 00:00:00 2001 From: Gator Date: Thu, 15 Dec 2022 21:24:17 +0100 Subject: [PATCH 7/9] update last board, new rules --- src/components/CanvasBoard.vue | 14 ++++++++++---- src/modules/automata.js | 24 ++++++++++++++++++++++++ src/modules/preset.js | 12 ++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) 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 }; From ae9275647f7ae55eed79aec95f4a0986142b3a73 Mon Sep 17 00:00:00 2001 From: Gator Date: Fri, 16 Dec 2022 10:16:50 +0100 Subject: [PATCH 8/9] color switching button --- src/components/MenuCellProperties.vue | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/MenuCellProperties.vue b/src/components/MenuCellProperties.vue index b8e42cc..85ee317 100644 --- a/src/components/MenuCellProperties.vue +++ b/src/components/MenuCellProperties.vue @@ -6,7 +6,7 @@ @@ -19,6 +19,9 @@ @input="updateCellProperties" /> +
@@ -58,6 +61,17 @@ this.setBoardWidth(); this.setBoardHeight(); }, + switchColor() { + [this.cellProperties["liveColor"], this.cellProperties["deadColor"]] = [ + this.cellProperties["deadColor"], + this.cellProperties["liveColor"], + ]; + }, }, }; + From bce0f39affe6e21a8cbc7ea645970ad4820c549b Mon Sep 17 00:00:00 2001 From: Gator Date: Sun, 18 Dec 2022 12:23:47 +0100 Subject: [PATCH 9/9] styling --- src/components/MenuCellProperties.vue | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/MenuCellProperties.vue b/src/components/MenuCellProperties.vue index 85ee317..0828a50 100644 --- a/src/components/MenuCellProperties.vue +++ b/src/components/MenuCellProperties.vue @@ -71,6 +71,11 @@ };