Compare commits

..

No commits in common. "9613f023b143ab20c275ed13afc9ce1298f82865" and "266840aa0b3b0d4f06f9559dffe04ba87826a99a" have entirely different histories.

6 changed files with 31 additions and 100 deletions

View File

@ -9,7 +9,7 @@
</main> </main>
</template> </template>
<script> <script>
import { create1dState, create1dStateOneCell, create2dState, createBoard, conwayRules, evolve2d } from '../modules/automata.js' import { evolve2d, initialState1d, initialState2d, conwayRules, createBoard } from '../modules/automata.js'
import { getRandomInt, sleep } from '../modules/common.js' import { getRandomInt, sleep } from '../modules/common.js'
import {mapGetters} from 'vuex' import {mapGetters} from 'vuex'
export default { export default {
@ -27,19 +27,8 @@ export default {
drawing: 'isDrawing', drawing: 'isDrawing',
canvasWidth: 'getCanvasWidth', canvasWidth: 'getCanvasWidth',
canvasHeight: 'getCanvasHeight', canvasHeight: 'getCanvasHeight',
refreshRate: 'getRefreshRate', refreshRate: 'getRefreshRate'
initial1dState: 'getInitial1dState' })
}),
boardWidth: function() {
return Math.floor(
this.canvas.width /
this.cellProperties.size)
},
boardHeight: function() {
return Math.floor(
this.canvas.height /
this.cellProperties.size)
}
}, },
mounted() { mounted() {
this.canvas = this.$refs['canvas'] this.canvas = this.$refs['canvas']
@ -67,25 +56,24 @@ export default {
) )
}) })
}, },
compute1dInitialState() {
if(this.initial1dState === "onecell")
return create1dStateOneCell(this.boardWidth)
return create1dState(this.boardWidth, getRandomInt, [0, 2])
},
async draw1d() { async draw1d() {
const initialState = this.compute1dInitialState() const initialState = initialState1d(
Math.floor(this.canvas.width / this.cellProperties.size),
getRandomInt,
[0, 2],
)
const board = createBoard( const board = createBoard(
initialState, initialState,
this.rules, this.rules,
this.boardHeight Math.floor(this.canvas.height / this.cellProperties.size)
) )
this.drawCanvas(board) this.drawCanvas(board)
}, },
async draw2d() { async draw2d() {
if (this.drawing === 0) return if (this.drawing === 0) return
const initialState = create2dState( const initialState = initialState2d(
this.boardWidth, Math.floor(this.canvas.width / this.cellProperties.size),
this.boardHeight, Math.floor(this.canvas.height / this.cellProperties.size),
getRandomInt, getRandomInt,
[0, 2], [0, 2],
); );

View File

@ -0,0 +1,9 @@
<template>
<div class="form-field" v-if="type === 'checkbox'">
<label>{{ name }}
<input type="checkbox" name="{{ name }}">
</label>
</div>
<div class="form-field" v-else-if="type === ''">
</div>
</template>

View File

@ -1,26 +1,9 @@
<template> <template>
<MenuRow row-title="Elementary Cellular Automata"> <MenuRow row-title="Elementary Cellular Automata">
<form>
<div class="form-field">
<label>Initial state presets
<br>
<select
name="initial1dStates"
value="initial1dStates"
@input="updateInitial1dState"
>
<option
v-for="state in initial1dStates"
:key="state.id"
:value="state.id"
>{{ state.name }}
</option>
</select>
</label>
</div>
<div class="form-field"> <div class="form-field">
<label>Rules</label> <label>Rules</label>
</div> </div>
<form>
<div <div
v-for="rule in rules" v-for="rule in rules"
:key="rule" :key="rule"
@ -62,7 +45,6 @@
</template> </template>
<script> <script>
import {mapGetters} from 'vuex'
import MenuRow from './MenuRow.vue' import MenuRow from './MenuRow.vue'
export default { export default {
name: 'MenuElementaryCA', name: 'MenuElementaryCA',
@ -70,43 +52,17 @@ export default {
MenuRow MenuRow
}, },
data() { data() {
// TODO: Why not a getter in the store?
return { return {
rules: ["111", "110", "101", "100", "011", "010", "001", "000"], rules: ["111", "110", "101", "100", "011", "010", "001", "000"]
initial1dStates: [
{ id : "onecell",
name : "One cell at center",
description : "State with a single cell in the middle",
},
{
id : "random",
name : "Random cell",
description : "State populated with random cells",
} }
]
}
},
computed: {
...mapGetters({
initial1dState: 'getInitial1dState'
})
}, },
methods: { methods: {
isCurrentPreset(event) {
console.log(elem.value)
const elem = event.target
return this.initialState === elem.value
},
update1dRules(event) { update1dRules(event) {
const elem = event.target const elem = event.target
const value = elem.checked ? 1 : 0 const value = elem.checked ? 1 : 0
const data = { 'rule' : elem.name, 'value' : value} const data = { 'rule' : elem.name, 'value' : value}
this.$store.commit('update1dRules', data) this.$store.commit('update1dRules', data)
}, },
updateInitial1dState(event) {
const elem = event.target
this.$store.commit('setInitial1dState', elem.value)
},
draw1d() { draw1d() {
this.$root.$store.state.drawing = 1 this.$root.$store.state.drawing = 1
this.$root.$emit('draw1d') this.$root.$emit('draw1d')

View File

@ -38,12 +38,7 @@ export default {
cursor: pointer; cursor: pointer;
border: 2px solid darkgrey; border: 2px solid darkgrey;
margin: 0 0 10px 0; margin: 0 0 10px 0;
} }
select {
margin-top: 10px;
padding: 5px;
}
input[type="button"] { input[type="button"] {
min-width: 60px; min-width: 60px;

View File

@ -73,7 +73,6 @@ function conwayRules(cell, neighbors) {
} }
// get the next evolution of a 2D CA initial state // get the next evolution of a 2D CA initial state
// Rules : Moore neighborhood
function evolve2d(board, rulesFn) { function evolve2d(board, rulesFn) {
return board.map((row, x) => row.map((cell, y) => { return board.map((row, x) => row.map((cell, y) => {
const neighbors = getCellNeighbors(board, [x, y]); const neighbors = getCellNeighbors(board, [x, y]);
@ -100,26 +99,17 @@ function getDrawingValues(state, acc, cell) {
); );
} }
// Populates the first state with a single living cell in the center
function create1dStateOneCell(width) {
return [...Array(width)].map(
(cell, index) => {
if (index === width / 2 || index === width + 1 / 2) return 1
return 0
})
}
// Populates the first state of a 1D CA with cells returned // Populates the first state of a 1D CA with cells returned
// by initFn // by initFn
function create1dState(width, initFn, args) { function initialState1d(width, initFn, args) {
return [...Array(width)].map( return [...Array(width)].map(
() => initFn(...args) () => initFn(...args),
); );
} }
// Populates the first state of a 2D CA with cells returned // Populates the first state of a 2D CA with cells returned
// by initFn // by initFn
function create2dState(width, height, initFn, args) { function initialState2d(width, height, initFn, args) {
return [...Array(height)].map( return [...Array(height)].map(
() => [...Array(width)].map( () => [...Array(width)].map(
() => initFn(...args), () => initFn(...args),
@ -128,5 +118,5 @@ function create2dState(width, height, initFn, args) {
} }
export { export {
getDrawingValues, create1dState, create2dState, createBoard, create1dStateOneCell, conwayRules, evolve1d, evolve2d getDrawingValues, initialState1d, initialState2d, evolve1d, evolve2d, conwayRules, createBoard,
}; };

View File

@ -23,8 +23,7 @@ export default new Vuex.Store({
}, },
canvasWidth: 1280, canvasWidth: 1280,
canvasHeight: 720, canvasHeight: 720,
refreshRate: 300, refreshRate: 300
initial1dState: "onecell"
}, },
mutations: { mutations: {
update1dRules(state, data) { update1dRules(state, data) {
@ -44,9 +43,6 @@ export default new Vuex.Store({
}, },
setRefreshRate(state, data) { setRefreshRate(state, data) {
state.refreshRate = data; state.refreshRate = data;
},
setInitial1dState(state, data) {
state.initial1dState = data
} }
}, },
getters: { getters: {
@ -70,9 +66,6 @@ export default new Vuex.Store({
}, },
getRefreshRate(state) { getRefreshRate(state) {
return state.refreshRate return state.refreshRate
},
getInitial1dState(state) {
return state.initial1dState
} }
}, },
actions: { actions: {