Skip to content

Instantly share code, notes, and snippets.

@munshkr
Last active August 29, 2015 14:10
Show Gist options
  • Save munshkr/d2eaa3bc4595a8ff692f to your computer and use it in GitHub Desktop.
Save munshkr/d2eaa3bc4595a8ff692f to your computer and use it in GitHub Desktop.
Game of Life
<!doctype html>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
cellSize = 20,
speed = 200,
blurSpeed = "200ms",
color = "#222",
backColor = "#fff";
var rows = height / cellSize,
cols = width / cellSize;
var createWorld = function(rows, cols) {
var matrix = [];
for (var i = 0; i < rows; i++) {
var row = [];
for (var j = 0; j < cols; j++) {
row.push(Math.random() > 0.9 ? 1 : 0);
}
matrix.push(row)
}
return matrix;
};
var update = function(matrix) {
var cellRow = d3.select("svg").selectAll("g")
.data(matrix);
// ENTER cellrow
cellRow.enter().append("g")
.attr("transform", function(d, y) {
return "translate(0 " + (cellSize * y) + ")";
});
// EXIT cellrow
cellRow.exit().remove();
var cell = cellRow.selectAll("rect")
.data(function(d, x) { return d; });
// ENTER cell
cell.enter().append("rect")
.attr("height", cellSize)
.attr("width", cellSize)
.attr("x", function(d, x) { return cellSize * x; })
.style("fill", function(d, x) { return d > 0 ? color : backColor; })
.style("transition", "fill " + blurSpeed)
.style("-webkit-transition", "fill " + blurSpeed)
.style("-moz-transition", "fill " + blurSpeed);
// UPDATE cell
cell.style("fill", function(d, x) { return d > 0 ? color : backColor; })
// EXIT cell
cell.exit().remove();
}
var neighbours = function(matrix, x, y) {
if (matrix.length === 0) return 0;
var c = 0;
for (var i = -1; i <= 1; i++) {
for (var j = -1; j <= 1; j++) {
if (y + i >= 0 && y + i < matrix.length &&
x + j >= 0 && x + j < matrix[0].length)
{
c += matrix[y + i][x + j];
}
}
}
if (matrix[y][x]) c--;
return c;
}
var tick = function(matrix) {
var changed = false;
if (matrix.length === 0) return {
world: matrix,
changed: changed,
};
// Clone matrix
var newMatrix = matrix.slice();
// Make new matrix based on Game of Life rules
for (var i = 0; i < matrix.length; i++) {
for (var j = 0; j < matrix[0].length; j++) {
var n = neighbours(matrix, j, i);
if (matrix[i][j] === 1 && (n < 2 || n > 3)) {
newMatrix[i][j] = 0;
changed = true;
} else if (matrix[i][j] === 0 && n === 3) {
newMatrix[i][j] = 1;
changed = true;
}
}
}
return {
world: newMatrix,
changed: changed,
};
}
var world = createWorld(rows, cols);
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.style("shape-rendering", "crispedges");
setInterval(function() {
var res = tick(world);
update(res.world);
// If game stops, create a new matrix
if (res.changed) {
world = res.world;
} else {
world = createWorld(rows, cols);
}
}, speed);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment