Skip to content

Instantly share code, notes, and snippets.

@chrisortman
Created April 16, 2014 04:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisortman/10805424 to your computer and use it in GitHub Desktop.
Save chrisortman/10805424 to your computer and use it in GitHub Desktop.
game of life
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Spec Runner v2.0.0</title>
<link rel="shortcut icon" type="image/png" href="jasmine-standalone-2/lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine-standalone-2/lib/jasmine-2.0.0/jasmine.css">
<script type="text/javascript" src="jasmine-standalone-2/lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="jasmine-standalone-2/lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine-standalone-2/lib/jasmine-2.0.0/boot.js"></script>
<!-- include source files here... -->
<script>
function makeWorld() {
var gridSize = 8;
var cells = [];
function visitCells(visitor) {
for(var i=0;i<gridSize;i++) {
for(var j=0;j<gridSize;j++) {
visitor(i,j)
}
}
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
visitCells(function(i,j) {
if(cells[i] === undefined) {
cells[i] = [];
}
var init = getRandomInt(0,100);
cells[i][j] = init > 50;
});
function countCells() {
var count = 0;
visitCells(function() {
count++;
});
return count;
}
function draw() {
var board = document.getElementById("board");
visitCells(function(i,j) {
board.rows[i].cells[j].innerText = i + "," + j;
if(cells[i][j] === true) {
board.rows[i].cells[j].style.backgroundColor = 'white';
} else {
board.rows[i].cells[j].style.backgroundColor = 'silver';
}
});
}
function nextState() {
visitCells(function(i,j) {
var neighbors = getNeighbors(gridSize,i,j).map(function(n) {
var row = n[0];
var col = n[1];
return cells[row][col];
});
//console.log(neighbors);
var currentState = cells[i][j];
var newState = getNextState(cells[i][j],neighbors);
//console.log("Changing state of " + i + "," + j + "from " + currentState + " to " + newState);
if(currentState !== newState) {
cells[i][j] = newState;
}
});
}
return {
cellCount : countCells,
draw : draw,
next : nextState
}
}
function getNeighbors(gridSize,row,col) {
var n = [];
n.push([ row-1,col-1 ]);
n.push([ row-1,col ]);
n.push([ row-1,col+1 ]);
n.push([ row,col-1 ]);
n.push([ row,col+1 ]);
n.push([ row+1,col-1 ]);
n.push([ row+1,col ]);
n.push([ row+1,col+1 ]);
return n.filter(function(v,idx,arr) {
if(v[0] < 0 || v[1] < 0) {
return false;
}
if(v[0] === row && v[1] === col) {
return false;
}
if(v[0] >= gridSize || v[1] >= gridSize) {
return false;
}
return true;
});
}
function getNextState(current,neighbors) {
var livingNeighbors = neighbors.filter(function(v) { return v;});
if(current === true) {
if(livingNeighbors.length === 2 || livingNeighbors.length === 3) {
return true;
}
} else {
if(livingNeighbors.length == 3) {
return true;
}
}
return false;
}
</script>
<script>
describe("Make world function",function() {
it("should create grid of 64 cells",function() {
var world = makeWorld();
expect(world.cellCount()).toEqual(64);
});
});
describe("getNeighbors",function() {
it("should compute adjacent cells",function() {
var n = getNeighbors(8,3,3);
expect(n[0]).toEqual([2,2]);
expect(n[1]).toEqual([2,3]);
expect(n[2]).toEqual([2,4]);
expect(n[3]).toEqual([3,2]);
expect(n[4]).toEqual([3,4]);
expect(n[5]).toEqual([4,2]);
expect(n[6]).toEqual([4,3]);
expect(n[7]).toEqual([4,4]);
});
it("should handle cells at left edge",function() {
var n = getNeighbors(8,0,0);
expect(n.length).toEqual(3);
expect(n[0]).toEqual([0,1]);
expect(n[1]).toEqual([1,0]);
expect(n[2]).toEqual([1,1]);
});
it("should handle cells at right edge",function() {
var n = getNeighbors(8,7,7);
expect(n.length).toEqual(3);
expect(n[0]).toEqual([6,6]);
expect(n[1]).toEqual([6,7]);
expect(n[2]).toEqual([7,6]);
});
});
describe("nextCellState",function() {
describe("live cell",function() {
it("should die with < 2 live neighbors",function() {
expect(getNextState(true,[false,true])).toEqual(false);
});
it("should live with 2 live neighbors",function() {
expect(getNextState(true,[false,true,true])).toEqual(true);
});
it("should live with 3 live neighbors",function() {
expect(getNextState(true,[true,true,true])).toEqual(true);
});
it("should die with more than 3 live neighbors",function() {
expect(getNextState(true,[true,true,true,true])).toEqual(false);
});
});
describe("dead cell",function() {
it("should live with 3 live neighbors",function() {
expect(getNextState(false,[true,true,true])).toEqual(true);
});
});
});
</script>
<!-- include spec files here... -->
<script type="text/javascript" src="SpecHelper.js"></script>
<style>
table.game {
width:300px;
height:300px;
border: 1px solid black;
background-color:white;
}
table.game td {
border: 1px solid black;
}
</style>
</head>
<body>
<div>
<table id="board" class="game">
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table>
<script>
var world = makeWorld();
world.draw();
setInterval(function() {
world.next();
world.draw();
console.log("tick");
}, 1000);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment