Skip to content

Instantly share code, notes, and snippets.

@dshook
Created February 4, 2015 17:57
Show Gist options
  • Select an option

  • Save dshook/95e5bcbd197d38df8c6b to your computer and use it in GitHub Desktop.

Select an option

Save dshook/95e5bcbd197d38df8c6b to your computer and use it in GitHub Desktop.
var TABLE_SIZE = 200;
var ALIVE = 'black';
var DEAD = 'white';
//gamestate
function initState(size){
var board = [];
for(var y = 0; y < size; y++){
var row = [];
for(var x = 0; x < size; x++){
var emptyCell = {
x: x,
y: y,
state: DEAD,
nextState: DEAD
};
row.push(emptyCell);
}
board.push(row);
}
return board;
}
var board = initState(TABLE_SIZE);
//set up table in DOM and in our representation
function drawTable() {
//check if table is already created, if it isn't create it
//if it is then update
var table = document.getElementById('table');
if(table){
for(var y = 0; y < board.length; y++){
for(var x = 0; x < board[y].length; x++){
var cell = table.rows[y].cells[x];
var boardCell = board[y][x];
cell.style.backgroundColor = boardCell.state;
}
}
}else{
var table = document.createElement("table");
table.setAttribute('id', 'table');
table.setAttribute('cellspacing', 0);
table.setAttribute('cellpadding', 0);
for(var y = 0; y < board.length; y++){
var row = document.createElement("tr");
var boardRow = board[y];
for(var x = 0; x < boardRow.length; x++){
var cell = document.createElement("td");
var boardCell = board[y][x];
cell.style.backgroundColor = boardCell.state;
cell.dataset.x = x;
cell.dataset.y = y;
row.appendChild(cell);
}
table.appendChild(row);
}
document.getElementById('table-container').appendChild(table);
}
}
//init state
var pattern = [
{x: 1, y: 2},
{x: 2, y: 2},
{x: 3, y: 2},
{x: 3, y: 3},
{x: 2, y: 4},
{x: 5, y: 6},
{x: 6, y: 6},
{x: 5, y: 7},
{x: 6, y: 7},
{x: 9, y: 3},
];
//add some rand for fun
for(var r = 0; r < TABLE_SIZE * 8; r++){
var randX = Math.round((Math.random() * TABLE_SIZE) % (TABLE_SIZE - 1), 0);
var randY = Math.round((Math.random() * TABLE_SIZE) % (TABLE_SIZE - 1), 0);
pattern.push({x: randX, y: randY});
}
initPattern(board, pattern);
drawTable();
//life step
function setInterval(){
return window.setTimeout(step, 100);
}
setInterval();
//game o life
function step(){
console.log('step');
board.forEach(function(row){
row.forEach(function(cell){
underPop(board, cell);
live(board, cell);
overcrowd(board, cell);
birth(board, cell);
});
});
updateStep(board);
drawTable();
setInterval();
}
//Any live cell with fewer than two live neighbours dies, as if caused by under-population.
function underPop(board, cell){
var surrounding = getSurrounding(board, cell.x, cell.y);
var surroundingAlive = countSurrounding(surrounding);
if(cell.state == ALIVE){
if(surroundingAlive < 2){
setCell(cell, DEAD);
}
}
}
//Any live cell with two or three live neighbours lives on to the next generation.
function live(board, cell){
var surrounding = getSurrounding(board, cell.x, cell.y);
var surroundingAlive = countSurrounding(surrounding);
if(cell.state == ALIVE){
if(surroundingAlive == 2 || surroundingAlive == 3){
setCell(cell, ALIVE);
}
}
}
//Any live cell with more than three live neighbours dies, as if by overcrowding.
function overcrowd(board, cell){
var surrounding = getSurrounding(board, cell.x, cell.y);
var surroundingAlive = countSurrounding(surrounding);
if(cell.state == ALIVE){
if(surroundingAlive > 3){
setCell(cell, DEAD);
}
}
}
//Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
function birth(board, cell){
var surrounding = getSurrounding(board, cell.x, cell.y);
var surroundingAlive = countSurrounding(surrounding);
if(cell.state == DEAD){
if(surroundingAlive == 3){
setCell(cell, ALIVE);
}
}
}
//board utils
function getSurrounding(board, x, y){
var surrounding = [];
for(var xDelta = -1; xDelta <= 1; xDelta++){
for(var yDelta = -1; yDelta <= 1; yDelta++){
var xCurrent = x + xDelta;
var yCurrent = y + yDelta;
if(xCurrent == x && yCurrent == y) continue;
//try catch a bit easier than checking all the bounds
try{
var cell = board[yCurrent][xCurrent];
if(cell) surrounding.push(cell);
}catch(e){};
}
}
return surrounding;
}
//returns board in a list for count
function getAllCells(board){
var surrounding = [];
board.forEach(function(row){
row.forEach(function(cell){
surrounding.push(cell);
});
});
return surrounding;
}
function countSurrounding(cellList){
var total = 0;
cellList.forEach(function(cell){
if(cell.state == ALIVE){
total++;
}
});
return total;
}
//update all the current states at once after the next states have been mutated by the game rules
function updateStep(board){
board.forEach(function(row){
row.forEach(function(cell){
cell.state = cell.nextState;
})
});
}
function initPattern(board, pattern){
pattern.forEach(function(item){
var cell = board[item.y][item.x];
hardSetCell(cell, ALIVE);
});
}
//Set both the state and next state
function hardSetCell(cell, state){
cell.state = state;
cell.nextState = state;
}
//set just next state
function setCell(cell, state){
cell.nextState = state;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment