Merge pull request 'new render method' (#8) from dev into master
Reviewed-on: #8
This commit is contained in:
commit
1644c8c5ce
@ -44,3 +44,4 @@ See [Configuration Reference](https://vitejs.dev/guide/).
|
|||||||
- https://en.wikipedia.org/wiki/Hashlife
|
- https://en.wikipedia.org/wiki/Hashlife
|
||||||
- https://plato.stanford.edu/entries/cellular-automata/supplement.html
|
- https://plato.stanford.edu/entries/cellular-automata/supplement.html
|
||||||
- https://www.conwaylife.com/wiki/Cellular_automaton
|
- https://www.conwaylife.com/wiki/Cellular_automaton
|
||||||
|
- https://conwaylife.com/
|
||||||
|
@ -24,15 +24,18 @@
|
|||||||
overpopulationRules,
|
overpopulationRules,
|
||||||
lonelinessRules,
|
lonelinessRules,
|
||||||
threebornRules,
|
threebornRules,
|
||||||
|
highLifeRules,
|
||||||
|
servietteRules,
|
||||||
evolve2d,
|
evolve2d,
|
||||||
} from "../modules/automata.js";
|
} from "../modules/automata.js";
|
||||||
import { getRandomInt, sleep } from "../modules/common.js";
|
import { getRandomInt } from "../modules/common.js";
|
||||||
import { picToBoard, picToBlackAndWhite } from "../modules/picture.js";
|
import { boardToPic, picToBoard } from "../modules/picture.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CanvasBoard",
|
name: "CanvasBoard",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
board: null,
|
||||||
canvas: null,
|
canvas: null,
|
||||||
workCanvas: null,
|
workCanvas: null,
|
||||||
workCtx: null,
|
workCtx: null,
|
||||||
@ -42,11 +45,14 @@
|
|||||||
overpopulation: overpopulationRules,
|
overpopulation: overpopulationRules,
|
||||||
loneliness: lonelinessRules,
|
loneliness: lonelinessRules,
|
||||||
threeborn: threebornRules,
|
threeborn: threebornRules,
|
||||||
|
highlife: highLifeRules,
|
||||||
|
serviette: servietteRules,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(globalStore, {
|
...mapState(globalStore, {
|
||||||
|
loop: "loop",
|
||||||
cellProperties: "cellProperties",
|
cellProperties: "cellProperties",
|
||||||
ruleset: "ruleset1d",
|
ruleset: "ruleset1d",
|
||||||
refreshRate: "refreshRate",
|
refreshRate: "refreshRate",
|
||||||
@ -59,8 +65,8 @@
|
|||||||
getDraw2dPicture: "draw2dpicture",
|
getDraw2dPicture: "draw2dpicture",
|
||||||
boardWidth: "boardWidth",
|
boardWidth: "boardWidth",
|
||||||
boardHeight: "boardHeight",
|
boardHeight: "boardHeight",
|
||||||
picture: "picture",
|
|
||||||
selected2dRules: "selected2dRules",
|
selected2dRules: "selected2dRules",
|
||||||
|
picture: "picture",
|
||||||
}),
|
}),
|
||||||
...mapWritableState(globalStore, {
|
...mapWritableState(globalStore, {
|
||||||
lastBoard: "lastBoard",
|
lastBoard: "lastBoard",
|
||||||
@ -72,6 +78,9 @@
|
|||||||
max() {
|
max() {
|
||||||
return Math.max(this.boardWidth, this.boardHeight);
|
return Math.max(this.boardWidth, this.boardHeight);
|
||||||
},
|
},
|
||||||
|
selectedRules() {
|
||||||
|
return this.available2dRules[this.selected2dRules.id];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
getDraw1d(value) {
|
getDraw1d(value) {
|
||||||
@ -80,8 +89,8 @@
|
|||||||
getDraw2d(value) {
|
getDraw2d(value) {
|
||||||
if (value == true) this.draw2dNew();
|
if (value == true) this.draw2dNew();
|
||||||
},
|
},
|
||||||
getDraw2dLast(value) {
|
async getDraw2dLast(value) {
|
||||||
if (value == true) this.draw2dLast();
|
if (value == true) await this.draw2dLast();
|
||||||
},
|
},
|
||||||
getDraw2dPicture(value) {
|
getDraw2dPicture(value) {
|
||||||
if (value == true) this.draw2dPicture();
|
if (value == true) this.draw2dPicture();
|
||||||
@ -109,21 +118,24 @@
|
|||||||
"setBoardHeight",
|
"setBoardHeight",
|
||||||
]),
|
]),
|
||||||
// draws the board on the canvas
|
// draws the board on the canvas
|
||||||
drawCanvas(board) {
|
async drawCanvas(board, width, height) {
|
||||||
const props = this.cellProperties;
|
const d = this.cellProperties.size;
|
||||||
board.map((row, y) => {
|
// bool to RGBA colors
|
||||||
const d = props.size;
|
const img = await boardToPic(board, width, height, this.cellProperties);
|
||||||
return row.map((cell, x) => {
|
// rescale and draw
|
||||||
this.ctx.fillStyle = (() => {
|
this.ctx.save();
|
||||||
if (cell === 1) return props.liveColor;
|
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||||
return props.deadColor;
|
this.workCtx.putImageData(img, 0, 0);
|
||||||
})();
|
this.ctx.imageSmoothingEnabled = false;
|
||||||
if (this.drawingDirection === "x")
|
this.ctx.scale(d, d);
|
||||||
this.ctx.fillRect(y * d, x * d, d, d);
|
this.ctx.drawImage(
|
||||||
else this.ctx.fillRect(x * d, y * d, d, d);
|
this.workCanvas,
|
||||||
return cell;
|
0,
|
||||||
});
|
0,
|
||||||
});
|
this.canvasWidth,
|
||||||
|
this.canvasHeight
|
||||||
|
);
|
||||||
|
this.ctx.restore();
|
||||||
},
|
},
|
||||||
// create a first state, either a single living cell
|
// create a first state, either a single living cell
|
||||||
// at the center or random ones
|
// at the center or random ones
|
||||||
@ -132,74 +144,77 @@
|
|||||||
return create1dStateOneCell(this.boardWidth);
|
return create1dStateOneCell(this.boardWidth);
|
||||||
return create1dState(this.boardWidth, getRandomInt, [0, 2]);
|
return create1dState(this.boardWidth, getRandomInt, [0, 2]);
|
||||||
},
|
},
|
||||||
// draw elementary automaton on the canvas based on selected ruleset
|
// initialize board with random cells
|
||||||
draw1d() {
|
randomInitialState() {
|
||||||
const initialState = this.compute1dInitialState();
|
return create2dState(
|
||||||
const board = createBoard(initialState, this.ruleset.rules, this.max);
|
|
||||||
this.lastBoard = Object.freeze(board);
|
|
||||||
this.drawCanvas(this.lastBoard);
|
|
||||||
this.toggleStop();
|
|
||||||
},
|
|
||||||
// draw 2D automaton on the canvas in a loop
|
|
||||||
draw2d(board) {
|
|
||||||
if (!this.canDraw) return;
|
|
||||||
const draw2dNext = async (b) => {
|
|
||||||
if (!this.canDraw) return;
|
|
||||||
const newBoard = evolve2d(
|
|
||||||
b,
|
|
||||||
this.available2dRules[this.selected2dRules.id]
|
|
||||||
);
|
|
||||||
this.drawCanvas(b, this.cellProperties);
|
|
||||||
this.lastBoard = Object.freeze(newBoard);
|
|
||||||
await sleep(this.refreshRate);
|
|
||||||
draw2dNext(newBoard);
|
|
||||||
};
|
|
||||||
return draw2dNext(board);
|
|
||||||
},
|
|
||||||
// draw 2d automaton from a new state
|
|
||||||
draw2dNew() {
|
|
||||||
const initialState = create2dState(
|
|
||||||
this.boardWidth,
|
this.boardWidth,
|
||||||
this.boardHeight,
|
this.boardHeight,
|
||||||
getRandomInt,
|
getRandomInt,
|
||||||
[0, 2]
|
[0, 2]
|
||||||
);
|
);
|
||||||
const board = evolve2d(initialState, conwayRules);
|
},
|
||||||
|
// draw elementary automaton on the canvas based on selected ruleset
|
||||||
|
draw1d() {
|
||||||
|
const initialState = this.compute1dInitialState();
|
||||||
|
const board = createBoard(initialState, this.ruleset.rules, this.max);
|
||||||
this.lastBoard = Object.freeze(board);
|
this.lastBoard = Object.freeze(board);
|
||||||
this.draw2d(board);
|
this.drawCanvas(this.lastBoard, this.boardWidth, this.boardHeight);
|
||||||
|
this.toggleStop();
|
||||||
|
},
|
||||||
|
// draw 2D automaton on the canvas in a loop
|
||||||
|
draw2d(board) {
|
||||||
|
const newBoard = evolve2d(board, this.selectedRules);
|
||||||
|
this.drawCanvas(newBoard, this.boardWidth, this.boardHeight);
|
||||||
|
this.lastBoard = Object.freeze(newBoard);
|
||||||
|
},
|
||||||
|
// draw 2d automaton in a loop, starting from passed state
|
||||||
|
async draw2dNext(board, time) {
|
||||||
|
setTimeout(() => {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (!this.canDraw) return;
|
||||||
|
this.draw2d(board);
|
||||||
|
return this.draw2dNext(this.lastBoard);
|
||||||
|
});
|
||||||
|
}, this.refreshRate);
|
||||||
|
},
|
||||||
|
// draw 2d automaton from a new state
|
||||||
|
async draw2dNew() {
|
||||||
|
if (!this.canDraw) return;
|
||||||
|
const initialState = this.randomInitialState();
|
||||||
|
let board = evolve2d(initialState, this.selectedRules);
|
||||||
|
if (this.loop) return this.draw2dNext(board);
|
||||||
|
else this.draw2d(board);
|
||||||
|
this.toggleStop();
|
||||||
},
|
},
|
||||||
// draw 2d automaton from the last known generated board
|
// draw 2d automaton from the last known generated board
|
||||||
draw2dLast() {
|
async draw2dLast() {
|
||||||
if (this.lastBoard != undefined) this.draw2d(this.lastBoard);
|
if (!this.canDraw) return;
|
||||||
|
if (this.loop) return this.draw2dNext(this.lastBoard);
|
||||||
|
else this.draw2d(this.lastBoard);
|
||||||
|
this.toggleStop();
|
||||||
},
|
},
|
||||||
// draw 2d automaton from an uploaded picture.
|
// draw 2d automaton from an uploaded picture.
|
||||||
// use the picture representation as an initial state
|
// use the picture representation as an initial state
|
||||||
draw2dPicture() {
|
draw2dPicture() {
|
||||||
// get image data by drawing it on a work canvas
|
// draw image on canvas
|
||||||
this.workCtx.drawImage(
|
this.ctx.fillStyle = "black";
|
||||||
|
this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||||
|
this.ctx.drawImage(
|
||||||
this.picture,
|
this.picture,
|
||||||
0,
|
Math.floor((this.canvasWidth - this.picture.width) / 2),
|
||||||
0,
|
Math.floor((this.canvasHeight - this.picture.height) / 2),
|
||||||
this.canvasWidth,
|
this.picture.width,
|
||||||
this.canvasHeight
|
this.picture.height
|
||||||
);
|
|
||||||
const imgData = this.workCtx.getImageData(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.canvasWidth,
|
|
||||||
this.canvasHeight
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// convert the image to black and white
|
// get image data from canvas
|
||||||
const black = picToBlackAndWhite(
|
const imgData = this.ctx.getImageData(
|
||||||
imgData.data,
|
0,
|
||||||
|
0,
|
||||||
this.canvasWidth,
|
this.canvasWidth,
|
||||||
this.canvasHeight
|
this.canvasHeight
|
||||||
);
|
);
|
||||||
|
|
||||||
// draw it back on the canvas
|
|
||||||
this.ctx.putImageData(black, 0, 0);
|
|
||||||
|
|
||||||
// draw the image back on the work canvas with the dimensions of the board
|
// draw the image back on the work canvas with the dimensions of the board
|
||||||
this.workCtx.drawImage(
|
this.workCtx.drawImage(
|
||||||
this.picture,
|
this.picture,
|
||||||
@ -209,6 +224,7 @@
|
|||||||
this.boardHeight
|
this.boardHeight
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// get the resized image data from work canvas
|
||||||
const resized = this.workCtx.getImageData(
|
const resized = this.workCtx.getImageData(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -216,7 +232,7 @@
|
|||||||
this.boardHeight
|
this.boardHeight
|
||||||
);
|
);
|
||||||
|
|
||||||
// convert the resized image into a 2D board of boolean based on pixel value
|
// convert the image into a 2D board of boolean based on pixel value
|
||||||
this.lastBoard = Object.freeze(
|
this.lastBoard = Object.freeze(
|
||||||
picToBoard(resized.data, this.boardWidth, this.boardHeight)
|
picToBoard(resized.data, this.boardWidth, this.boardHeight)
|
||||||
);
|
);
|
||||||
@ -226,7 +242,8 @@
|
|||||||
// stop drawing routines and clear the canvas
|
// stop drawing routines and clear the canvas
|
||||||
reset() {
|
reset() {
|
||||||
this.toggleStop();
|
this.toggleStop();
|
||||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
this.lastBoard = {};
|
||||||
|
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||||
this.getReset = 0;
|
this.getReset = 0;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -67,7 +67,6 @@
|
|||||||
preparePicture(event) {
|
preparePicture(event) {
|
||||||
const files = event.target.files;
|
const files = event.target.files;
|
||||||
this.picture = new Image();
|
this.picture = new Image();
|
||||||
this.picture.width = this.canvasWidth;
|
|
||||||
if (FileReader && files && files.length) {
|
if (FileReader && files && files.length) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
@ -1,5 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
|
<div class="form-field">
|
||||||
|
<label>
|
||||||
|
Loop
|
||||||
|
<input
|
||||||
|
:value="loop"
|
||||||
|
type="checkbox"
|
||||||
|
:checked="loop"
|
||||||
|
@input="toggleLoop()"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="button"
|
||||||
|
name="next"
|
||||||
|
class="next"
|
||||||
|
value="Next"
|
||||||
|
@click="toggleNext()"
|
||||||
|
/>
|
||||||
<input
|
<input
|
||||||
type="button"
|
type="button"
|
||||||
name="stop"
|
name="stop"
|
||||||
@ -17,13 +35,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import { globalStore } from "../stores/index.js";
|
import { globalStore } from "../stores/index.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MenuReset",
|
name: "MenuReset",
|
||||||
|
computed: {
|
||||||
|
...mapState(globalStore, ["loop"]),
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(globalStore, ["toggleReset", "toggleStop"]),
|
...mapActions(globalStore, [
|
||||||
|
"toggleReset",
|
||||||
|
"toggleStop",
|
||||||
|
"toggleLoop",
|
||||||
|
"toggleNext",
|
||||||
|
]),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
// handles negative index and index bigger than its array length
|
// handles negative index and index bigger than its array length
|
||||||
function guard(index, array) {
|
function guard(index, arrayLength) {
|
||||||
if (index > array.length - 1) return 0;
|
if (index > arrayLength - 1) return 0;
|
||||||
if (index < 0) return array.length - 1;
|
if (index < 0) return arrayLength - 1;
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the next evolution of a 1D CA initial state
|
// get the next evolution of a 1D CA initial state
|
||||||
function evolve1d(state, rules) {
|
function evolve1d(state, rules) {
|
||||||
function getCell(index) {
|
function getCell(index) {
|
||||||
const safeIndex = guard(index, state);
|
const safeIndex = guard(index, state.length);
|
||||||
return state[safeIndex];
|
return state[safeIndex];
|
||||||
}
|
}
|
||||||
const newState = state.map((_, x) => {
|
const newState = state.map((_, x) => {
|
||||||
@ -55,8 +55,8 @@ function getCellNeighbors(board, cellCoordinates) {
|
|||||||
|
|
||||||
// handles board edges where the cell is missing neighbors
|
// handles board edges where the cell is missing neighbors
|
||||||
function getCell(xx, yy) {
|
function getCell(xx, yy) {
|
||||||
const safeX = guard(xx, board);
|
const safeX = guard(xx, board.length);
|
||||||
const safeY = guard(yy, rowLength);
|
const safeY = guard(yy, rowLength.length);
|
||||||
return board[safeX][safeY];
|
return board[safeX][safeY];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +91,30 @@ function conwayRules(cell, neighbors) {
|
|||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the next evolution of a cell according to
|
||||||
|
// Conway's game of life rules
|
||||||
|
function servietteRules(cell, neighbors) {
|
||||||
|
// loneliness rule
|
||||||
|
if (cell === 0 && [2, 3, 4].find((x) => x == neighbors)) return 1;
|
||||||
|
// the cell remains the same if none apply
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// variation of the game of life where a
|
||||||
|
// cell comes to live if 6 neigbor cells are alive
|
||||||
|
function highLifeRules(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 === 2) return 1;
|
||||||
|
// highlife rules
|
||||||
|
if ((cell === 0 && neighbors === 3) || neighbors === 6) return 1;
|
||||||
|
// the cell remains the same if none apply
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
// variation on the game of life's rules,
|
// variation on the game of life's rules,
|
||||||
// where the "three live neighbors" rule is ignored
|
// where the "three live neighbors" rule is ignored
|
||||||
function threebornRules(cell, neighbors) {
|
function threebornRules(cell, neighbors) {
|
||||||
@ -184,6 +208,8 @@ export {
|
|||||||
overpopulationRules,
|
overpopulationRules,
|
||||||
lonelinessRules,
|
lonelinessRules,
|
||||||
threebornRules,
|
threebornRules,
|
||||||
|
highLifeRules,
|
||||||
|
servietteRules,
|
||||||
evolve1d,
|
evolve1d,
|
||||||
evolve2d,
|
evolve2d,
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
// https://stackoverflow.com/questions/21646738/convert-hex-to-rgba
|
||||||
|
// [
|
||||||
|
function hexToRGB(hex) {
|
||||||
|
return [
|
||||||
|
parseInt(hex.slice(1, 3), 16),
|
||||||
|
parseInt(hex.slice(3, 5), 16),
|
||||||
|
parseInt(hex.slice(5, 7), 16),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/4492385/convert-simple-array-into-two-dimensional-array-matrix
|
// https://stackoverflow.com/questions/4492385/convert-simple-array-into-two-dimensional-array-matrix
|
||||||
// convert a 1D array into a 2D matrix
|
// convert a 1D array into a 2D matrix
|
||||||
export function toMatrix(array, width) {
|
export function toMatrix(array, width) {
|
||||||
@ -28,12 +38,32 @@ export function picToBlackAndWhite(pixels, width, height) {
|
|||||||
// convert an ImageData into a 2D array of boolean (0, 1) values
|
// convert an ImageData into a 2D array of boolean (0, 1) values
|
||||||
export function picToBoard(pixels, width, height) {
|
export function picToBoard(pixels, width, height) {
|
||||||
const flat = pixels.reduce((acc, pixel, index) => {
|
const flat = pixels.reduce((acc, pixel, index) => {
|
||||||
if (index % 4 == 0) {
|
const i = index * 4;
|
||||||
const count = pixels[index] + pixels[index + 1] + pixels[index + 2];
|
const count = pixels[i] + pixels[i + 1] + pixels[i + 2];
|
||||||
const value = count >= 255 ? 1 : 0;
|
const value = count >= 255 ? 1 : 0;
|
||||||
acc.push(value);
|
acc[index] = value;
|
||||||
}
|
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
return toMatrix(flat, Math.max(width, height));
|
|
||||||
|
return toMatrix(flat, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert board to ImageData
|
||||||
|
// TODO : different cell to color functions
|
||||||
|
// (binary, intermediate states, camaieux, etc)
|
||||||
|
export function boardToPic(board, width, height, cellProperties) {
|
||||||
|
const live = cellProperties.liveColor;
|
||||||
|
const dead = cellProperties.deadColor;
|
||||||
|
const img = new ImageData(width, height);
|
||||||
|
const colors = [hexToRGB(live), hexToRGB(dead)];
|
||||||
|
board.flat().reduce((acc, cell, index) => {
|
||||||
|
const color = colors[cell];
|
||||||
|
const i = index * 4;
|
||||||
|
acc[i] = color[0];
|
||||||
|
acc[i + 1] = color[1];
|
||||||
|
acc[i + 2] = color[2];
|
||||||
|
acc[i + 3] = 255;
|
||||||
|
return acc;
|
||||||
|
}, img.data);
|
||||||
|
return img;
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,19 @@ const presetRuleset = [
|
|||||||
"000": 0,
|
"000": 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "rule 30",
|
||||||
|
rules: {
|
||||||
|
100: 1,
|
||||||
|
101: 0,
|
||||||
|
110: 0,
|
||||||
|
111: 0,
|
||||||
|
"011": 1,
|
||||||
|
"010": 1,
|
||||||
|
"001": 1,
|
||||||
|
"000": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "unknown rule",
|
name: "unknown rule",
|
||||||
rules: {
|
rules: {
|
||||||
@ -77,6 +90,19 @@ const presetRuleset = [
|
|||||||
"000": 1,
|
"000": 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "unknown rule 2",
|
||||||
|
rules: {
|
||||||
|
100: 1,
|
||||||
|
101: 0,
|
||||||
|
110: 1,
|
||||||
|
111: 0,
|
||||||
|
"011": 0,
|
||||||
|
"010": 0,
|
||||||
|
"001": 0,
|
||||||
|
"000": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const initialStates = [
|
const initialStates = [
|
||||||
@ -116,6 +142,17 @@ const preset2dRules = [
|
|||||||
description:
|
description:
|
||||||
"Variation on Conway's Game of Life *without* the 'three live neighbors' rule",
|
"Variation on Conway's Game of Life *without* the 'three live neighbors' rule",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "highlife",
|
||||||
|
name: "HighLife variation",
|
||||||
|
description:
|
||||||
|
"Variation on Conway's Game of Life where a cell live if the six neighbor cells are alive",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "serviette",
|
||||||
|
name: "Serviette variation",
|
||||||
|
description: "bla",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export { presetRuleset, initialStates, preset2dRules };
|
export { presetRuleset, initialStates, preset2dRules };
|
||||||
|
@ -33,7 +33,7 @@ export const globalStore = defineStore("globalStore", {
|
|||||||
refreshRate: 300,
|
refreshRate: 300,
|
||||||
initial1dState: "onecell",
|
initial1dState: "onecell",
|
||||||
drawingDirection: "y",
|
drawingDirection: "y",
|
||||||
lastBoard: {},
|
lastBoard: null,
|
||||||
draw1d: false,
|
draw1d: false,
|
||||||
draw2d: false,
|
draw2d: false,
|
||||||
draw2dLast: false,
|
draw2dLast: false,
|
||||||
@ -43,6 +43,8 @@ export const globalStore = defineStore("globalStore", {
|
|||||||
picture: null,
|
picture: null,
|
||||||
mainMenu: false,
|
mainMenu: false,
|
||||||
activeSubMenu: "",
|
activeSubMenu: "",
|
||||||
|
loop: false,
|
||||||
|
lastAction: "drawfromlast",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@ -61,6 +63,7 @@ export const globalStore = defineStore("globalStore", {
|
|||||||
},
|
},
|
||||||
toggleDraw2d() {
|
toggleDraw2d() {
|
||||||
this.setActiveSubMenu("");
|
this.setActiveSubMenu("");
|
||||||
|
this.lastAction = "draw2d";
|
||||||
this.setMainMenu(false);
|
this.setMainMenu(false);
|
||||||
this.toggleStop();
|
this.toggleStop();
|
||||||
this.canDraw = true;
|
this.canDraw = true;
|
||||||
@ -68,6 +71,7 @@ export const globalStore = defineStore("globalStore", {
|
|||||||
},
|
},
|
||||||
toggleDraw2dLast() {
|
toggleDraw2dLast() {
|
||||||
this.setActiveSubMenu("");
|
this.setActiveSubMenu("");
|
||||||
|
this.lastAction = "drawfromlast";
|
||||||
this.setMainMenu(false);
|
this.setMainMenu(false);
|
||||||
this.toggleStop();
|
this.toggleStop();
|
||||||
this.canDraw = true;
|
this.canDraw = true;
|
||||||
@ -89,6 +93,21 @@ export const globalStore = defineStore("globalStore", {
|
|||||||
this.draw2dpicture = false;
|
this.draw2dpicture = false;
|
||||||
this.canDraw = false;
|
this.canDraw = false;
|
||||||
},
|
},
|
||||||
|
toggleLoop() {
|
||||||
|
this.loop = !this.loop;
|
||||||
|
},
|
||||||
|
toggleNext() {
|
||||||
|
switch (this.lastAction) {
|
||||||
|
case "drawfromlast":
|
||||||
|
this.toggleDraw2dLast();
|
||||||
|
break;
|
||||||
|
case "draw2d":
|
||||||
|
this.toggleDraw2d();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
setActiveSubMenu(data) {
|
setActiveSubMenu(data) {
|
||||||
if (this.activeSubMenu == data) this.activeSubMenu = "";
|
if (this.activeSubMenu == data) this.activeSubMenu = "";
|
||||||
else this.activeSubMenu = data;
|
else this.activeSubMenu = data;
|
||||||
|
Loading…
Reference in New Issue
Block a user