Last active
December 21, 2017 14:46
-
-
Save misterussell/51f7ef8fccecd380de3b9ba07c702260 to your computer and use it in GitHub Desktop.
A basic non-optimized Game of Life
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* getGeneration() takes an initial 2d array, and a integer n where n is the | |
* desired generation output | |
* the initial 2d array must immediately be converted into a toroidal array | |
* the left and right edges must be stitched together | |
* the top and bottom edges must be stiched together | |
* these indices have a total of 8 neighbors | |
* any live cell with n < 2 dies | |
* any live cell with 2 < n < 3 lives on gen x + 1 | |
* any live cell with n < 3 dies | |
* any dead cell with n = 3 becomes alive | |
* toroidal stictching will be handled after we have been able to create and | |
* optimize the 2d life model | |
*/ | |
function getGeneration(cells, generations){ | |
// create a mutable copy of the array passed in | |
const initialGen = cells; | |
// create an array to store the new generations in | |
let genCache = []; | |
/* the goal for the later version is to keep the program aware of previous | |
* runs to assist with speeding up computation so we will initiate a hash for | |
* each cell. We multiply the x and y values with specific prime numbers so | |
* that we can keep the hashes unique. I have a feeling that we are going to | |
* need to give each cell more knowledge of itself so I am using this as a | |
* constructor | |
*/ | |
for (var i = 0; i < generations; i++) { | |
const previousGen = genCache.length > 0 | |
? generateNextState(generateGenState(genCache[genCache.length - 1])) | |
: initialGen | |
genCache.push(previousGen); | |
} | |
return genCache; | |
} | |
function generateGenState(rawCells) { | |
// first create the Cell constructor. In the first non-toroidal | |
function Cell(x, y, cellState, neighbors = 0) { | |
this.x = x; | |
this.y = y; | |
this.hash = (this.x * 15486047) + (this.y * 15487429); | |
this.isAlive = cellState; | |
this.neighbors = neighbors | |
} | |
// return a map of the current cell configuration passed in as cells | |
// I will refer to each level of the array as a terrain | |
let test = rawCells.map((terrian, i, arr) => { | |
return terrian.map((cell, p, arr2) => { | |
const cellState = Boolean(cell); | |
const above = arr[i - 1] !== undefined ? arr[i - 1][p] : 0; | |
const below = arr[i + 1] !== undefined ? arr[i + 1][p] : 0; | |
const right = arr2[p + 1] !== undefined ? arr2[p + 1] : 0; | |
const left = arr2[p - 1] !== undefined ? arr2[p - 1] : 0; | |
const abovePerps = arr[i - 1] !== undefined ? [arr[i - 1][p - 1], arr[i - 1][p + 1]] : [0, 0]; | |
const belowPerps = arr[i + 1] !== undefined ? [arr[i + 1][p - 1], arr[i + 1][p + 1]] : [0, 0]; | |
const neighbors = checkNeighbors([ | |
// right left | |
right, left, | |
// above below | |
above, below, | |
// above perps | |
abovePerps[0], abovePerps[1], | |
// below perps | |
belowPerps[0], belowPerps[1] | |
]); | |
return new Cell(i + 1, p + 1, cellState, neighbors); | |
}); | |
}); | |
// console.log(test); | |
return test | |
} | |
function checkNeighbors(neighbors) { | |
let verifiedNeighbors = 0; | |
neighbors.forEach(neighbor => { | |
return neighbor === 1 ? verifiedNeighbors += 1 : null | |
}) | |
return verifiedNeighbors; | |
} | |
function generateNextState(cells) { | |
return cells.map(terrain => { | |
return terrain.map(cell => { | |
const twoOrThree = (cell.neighbors === 2 || cell.neighbors === 3) ? 1 : 0; | |
const greaterThanThree = cell.neighbors > 3 ? 0 : twoOrThree; | |
const convertLive = cell.nieghbors < 2 ? 0 : greaterThanThree; | |
const convertDead = cell.neighbors === 3 ? 1 : 0 | |
return cell.isAlive | |
? convertLive | |
: convertDead | |
}); | |
}) | |
} | |
let gen = [ | |
[0,0,0,0,0], | |
[0,0,1,0,0], | |
[0,0,0,1,0], | |
[0,1,1,1,0], | |
[0,0,0,0,0] | |
] | |
console.log(getGeneration(gen, 12)) | |
gen = [ | |
[0,0,0,0,0], | |
[0,0,1,0,0], | |
[0,0,1,0,0], | |
[0,0,1,0,0], | |
[0,0,0,0,0] | |
] | |
console.log(getGeneration(gen, 4)); | |
gen = [ | |
[0,0,0,0,0,0], | |
[0,1,1,0,0,0], | |
[0,1,0,0,0,0], | |
[0,0,0,0,1,0], | |
[0,0,0,1,1,0], | |
[0,0,0,0,0,0] | |
] | |
console.log(getGeneration(gen, 4)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment