Skip to content

Instantly share code, notes, and snippets.

@lachezar
Created July 24, 2011 19:18
Show Gist options
  • Save lachezar/1102964 to your computer and use it in GitHub Desktop.
Save lachezar/1102964 to your computer and use it in GitHub Desktop.
Game of Life (Javascript + HTML5's Canvas)
<!DOCTYPE html>
<html>
<head>
<title>Game of Life</title>
</head>
<body>
<canvas id="canvas" width="400" height="300">There should be a canvas somewhere here.... :-/</canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillRect(0, 0, canvas.width, canvas.height);
var THE_BLACK = 0;
var THE_WHITE = 0xFF;
function spawn(n, data) {
for (var i = 0; i < n; i++) {
var k = parseInt(Math.random()*canvas.width*canvas.height)*4;
data.data[k] = THE_WHITE;
data.data[k+1] = THE_WHITE;
data.data[k+2] = THE_WHITE;
}
}
function applyRules(data, newdata) {
// highly optimized
var width = canvas.width*4;
var d = data.data;
var nd = newdata.data;
var cw = canvas.width;
var ch = canvas.height;
var base = 0;
for (var i = 0; i < d.length/4; i++) {
var x = i % cw;
var y = parseInt(i / cw);
var cnt = 0;
if (x > 0 && d[base-4] != THE_BLACK) cnt++;
if (x < cw-1 && d[base+4] != THE_BLACK) cnt++;
if (x > 0 && y > 0 && d[base-4-width] != THE_BLACK) cnt++;
if (y > 0 && d[base-width] != THE_BLACK) cnt++;
if (x < cw-1 && y > 0 && d[base+4-width] != THE_BLACK) cnt++;
if (x > 0 && y < ch-1 && d[base-4+width] != THE_BLACK) cnt++;
if (y < ch-1 && d[base+width] != THE_BLACK) cnt++;
if (x < cw-1 && y < ch-1 && d[base+4+width] != THE_BLACK) cnt++;
var color = null;
if (d[base] == THE_BLACK && cnt == 3) {
color = THE_WHITE;
} else if (!(d[base] != THE_BLACK && (cnt == 3 || cnt == 2))) {
color = THE_BLACK;
}
if (color !== null) {
nd[base] = nd[base+1] = nd[base+2] = color;
}
base += 4;
}
// dead cell with 3 neightbours - alive
// live cell with 2 or 3 neightbours - still alive
// all other cases - dead
}
function getLiveNeighbours(id, data) {
var x = id % canvas.width;
var y = parseInt(id / canvas.width);
var cnt = 0;
for (var i = -1; i < 2; i++) {
for (var j = -1; j < 2; j++) {
if ((i != 0 || j != 0) &&
!(x+i < 0 || x+i >= canvas.width || y+j < 0 || y+j >= canvas.height) &&
data.data[4*((y+j)*canvas.width+(x+i))] != THE_BLACK) {
cnt++;
}
}
}
return cnt;
}
function mainLoop() {
var start = new Date();
var data = context.getImageData(0, 0, canvas.width, canvas.height);
var newdata = context.getImageData(0, 0, canvas.width, canvas.height);
spawn(parseInt(0.02*canvas.width*canvas.height), data);
applyRules(data, newdata);
context.putImageData(newdata, 0, 0);
console.log('time delta', new Date().getTime() - start.getTime());
}
var data = context.getImageData(0, 0, canvas.width, canvas.height);
spawn(parseInt(0.2*canvas.width*canvas.height), data);
context.putImageData(data, 0, 0);
setInterval(mainLoop, 50);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment