Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Conway's Game of Life with JS and D3
function Cell(initialState) {
this.isAlive = initialState;
this.willBeAlive = false;
}
Cell.prototype.computeNextState = function(aliveNeighborsCount) {
if(aliveNeighborsCount == 3){
this.willBeAlive = true;
} else if(aliveNeighborsCount > 3 || aliveNeighborsCount < 2) {
this.willBeAlive = false;
} else {
this.willBeAlive = this.isAlive;
}
return this.willBeAlive;
};
Cell.prototype.nextState = function(){
this.isAlive = this.willBeAlive;
}
function CellGrid(rows, columns) {
this.cells = new Array(rows);
var n = 0;
for(var i = -1; ++i < rows;){
this.cells[i] = new Array(columns);
for(var j = -1; ++j < columns; ){
var cell = new Cell(false);
cell.n = n++;
cell.x = i;
cell.y = j;
this.cells[i][j] = cell;
}
}
}
CellGrid.prototype.aliveNeighborsFor = function(x, y) {
var self = this,
neighbors = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];
function isAliveAt(i, j){
if(i < 0 || i >= self.cells.length || j < 0 || j >= self.cells[0].length){
return false;
}
return self.cells[i][j].isAlive;
}
var count = 0;
for(var i = 0; i < neighbors.length; i++){
count += (isAliveAt(x+neighbors[i][0],y+neighbors[i][1]))?1:0;
}
return count;
};
CellGrid.prototype.eachCell = function(callback){
var rows = this.cells.length,
columns = this.cells[0].length,
x,y;
for(var i = 0; i < rows * columns; i++){
x = i%rows; y = Math.floor(i/rows);
callback.apply(this,[this.cells[x][y],x,y]);
}
};
CellGrid.prototype.reset = function(){
this.eachCell(function(cell,x,y){
cell.isAlive = (Math.random() > 0.5);
});
};
CellGrid.prototype.prepareStep = function() {
this.eachCell(function(cell,x,y){
cell.computeNextState(this.aliveNeighborsFor(x,y));
});
};
CellGrid.prototype.step = function() {
this.prepareStep();
this.eachCell(function(cell,x,y){
cell.nextState();
});
};
CellGrid.prototype.aliveCells = function() {
var alive = [];
this.eachCell(function(cell){
cell.isAlive && alive.push(cell);
});
return alive;
};
<!doctype html>
<html>
<body>
<a href="http://github.com/sylvaingi/d3-life"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://a248.e.akamai.net/assets.github.com/img/abad93f42020b733148435e2cd92ce15c542d320/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67" alt="Fork me on GitHub"></a>
<style type="text/css">
html,body{
margin: 0;
overflow: hidden;
}
circle {
fill: #1f77b4;
}
</style>
<script type="text/javascript" src="Cell.js"></script>
<script type="text/javascript" src="CellGrid.js"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?2.8.1"></script>
<script type="text/javascript">
(function(){
var w = window.innerWidth,
h = window.innerHeight,
columns = 10,
rows = 10,
wRatio = w/columns,
hRatio = h/rows,
radius = Math.min(Math.floor(w/(2*columns)),Math.floor(h/(2*rows)));
var grid = new CellGrid(rows,columns);
grid.reset();
var svg = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h);
var circle = svg.selectAll("circle");
(function(){
grid.step();
circle = circle.data(grid.aliveCells(),function(d){return d.n});
circle.enter().append("circle")
.attr("cx", function(d){return d.x*wRatio + radius})
.attr("cy", function(d){return d.y*hRatio + radius})
.transition().duration(500)
.attr("r", radius)
.style("fill","#2ca02c");;
circle.exit()
.style("fill","#d62728")
.transition().duration(500)
.attr("r", 0)
.remove();
setTimeout(arguments.callee,500);
})();
})();
</script>
</body>
</html>
@sylvaingi

This comment has been minimized.

Show comment
Hide comment
Owner

sylvaingi commented Apr 12, 2012

Github repo here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment