Created
February 4, 2015 17:57
-
-
Save dshook/95e5bcbd197d38df8c6b to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| 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