fix evolve 2D #11
@ -1,23 +1,26 @@
|
||||
// core functions to generate initial states and evolve them
|
||||
|
||||
// handles negative index and index bigger than its array length
|
||||
function guard(index, arrayLength) {
|
||||
if (index > arrayLength - 1) return 0;
|
||||
if (index < 0) return arrayLength - 1;
|
||||
return index;
|
||||
}
|
||||
// get the next evolution of a 1D CA initial state
|
||||
// buggy BUT produces interesting results
|
||||
// function evolve1d(state, rules) {
|
||||
// const sl = state.length - 1;
|
||||
// return [
|
||||
// rules[[state[sl - 1], state[sl], state[sl + 1]].join("")],
|
||||
// ...state.map((_,x) => (rules[[state[x - 1], state[x], state[x + 1]].join("")])).slice(0, sl),
|
||||
// rules[[state[0], state[1], state[2]].join("")]
|
||||
// ]
|
||||
// }
|
||||
|
||||
// get the next evolution of a 1D CA initial state
|
||||
function evolve1d(state, rules) {
|
||||
function getCell(index) {
|
||||
const safeIndex = guard(index, state.length);
|
||||
return state[safeIndex];
|
||||
}
|
||||
const newState = state.map((_, x) => {
|
||||
const cells = [getCell(x - 1), getCell(x), getCell(x + 1)];
|
||||
return rules[cells.join("")];
|
||||
});
|
||||
return newState.map(Number);
|
||||
const sl = state.length - 1;
|
||||
const edge1 = [state[sl - 2], state[sl - 1], state[sl]].join("");
|
||||
const edge2 = [state[0], state[1], state[2]].join("");
|
||||
// normal case (3 neighbor cells)
|
||||
const center = state
|
||||
.map((_, x) => rules[[state[x - 1], state[x], state[x + 1]].join("")])
|
||||
.slice(1, sl);
|
||||
return [rules[edge1], ...center, rules[edge2]];
|
||||
}
|
||||
|
||||
// create a 2D board from a 1D CA initial state
|
||||
@ -49,31 +52,6 @@ function createBoard(state, rules, max) {
|
||||
return board;
|
||||
}
|
||||
|
||||
// Find the neighbor of a given cell in a 2D CA board
|
||||
function getCellNeighbors(board, cellCoordinates) {
|
||||
const [x, y] = cellCoordinates;
|
||||
const rowLength = board[0].length; // caca?
|
||||
|
||||
// handles board edges where the cell is missing neighbors
|
||||
function getCell(xx, yy) {
|
||||
const safeX = guard(xx, board.length);
|
||||
const safeY = guard(yy, rowLength.length);
|
||||
return board[safeX][safeY];
|
||||
}
|
||||
|
||||
// the current cell is not included in the result
|
||||
return [
|
||||
getCell(x - 1, y - 1),
|
||||
getCell(x, y - 1),
|
||||
getCell(x + 1, y - 1),
|
||||
getCell(x - 1, y),
|
||||
getCell(x + 1, y),
|
||||
getCell(x - 1, y + 1),
|
||||
getCell(x, y + 1),
|
||||
getCell(x + 1, y - 1),
|
||||
];
|
||||
}
|
||||
|
||||
// Sums the value of a cell's neighbors
|
||||
function getNeighborsSum(cells) {
|
||||
return cells.reduce((cell, acc) => cell + acc, 0);
|
||||
@ -152,13 +130,31 @@ function overpopulationRules(cell, neighbors) {
|
||||
// get the next evolution of a 2D CA initial state
|
||||
// Rules : Moore neighborhood
|
||||
function evolve2d(board, rulesFn) {
|
||||
return board.map((row, x) =>
|
||||
row.map((cell, y) => {
|
||||
const neighbors = getCellNeighbors(board, [x, y]);
|
||||
const bh = board.length - 1;
|
||||
const bw = board[0].length - 1;
|
||||
return board.map((row, y) => {
|
||||
// handle edges
|
||||
const prow = y - 1 < 0 ? board[bh] : board[y - 1];
|
||||
const nrow = y + 1 > bh ? board[0] : board[y + 1];
|
||||
return row.map((cell, x) => {
|
||||
// handle edges too
|
||||
const pcell = x - 1 < 0 ? bw : x - 1;
|
||||
const ncell = x + 1 > bw ? 0 : x + 1;
|
||||
// the current cell is not included in the result
|
||||
const neighbors = [
|
||||
prow[pcell],
|
||||
prow[x],
|
||||
prow[ncell],
|
||||
row[pcell],
|
||||
row[ncell],
|
||||
nrow[pcell],
|
||||
nrow[x],
|
||||
nrow[ncell],
|
||||
];
|
||||
const sum = getNeighborsSum(neighbors);
|
||||
return rulesFn(cell, sum);
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getDrawingValues(state, acc, cell) {
|
||||
|
Loading…
Reference in New Issue
Block a user