Skip to content

Instantly share code, notes, and snippets.

@worenga
Created December 7, 2012 23:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save worenga/4237432 to your computer and use it in GitHub Desktop.
Save worenga/4237432 to your computer and use it in GitHub Desktop.
A CodePen by Benedikt Wolters.
<h1>Conway's Game of Live</h1>
<canvas id="c"></canvas>
$(document).ready(
function () {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) window.requestAnimationFrame = function (callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function () {
callback(currTime + timeToCall);
},
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
var GameOfLife = {};
GameOfLife.Dead = 0;
GameOfLife.Alive = 1;
GameOfLife.glider = new Array();
//Glider..
GameOfLife.glider[0] = new Array();
GameOfLife.glider[0][0] = GameOfLife.Dead;
GameOfLife.glider[0][1] = GameOfLife.Alive;
GameOfLife.glider[0][2] = GameOfLife.Dead;
GameOfLife.glider[1] = new Array();
GameOfLife.glider[1][0] = GameOfLife.Dead;
GameOfLife.glider[1][1] = GameOfLife.Dead;
GameOfLife.glider[1][2] = GameOfLife.Alive;
GameOfLife.glider[2] = new Array();
GameOfLife.glider[2][0] = GameOfLife.Alive;
GameOfLife.glider[2][1] = GameOfLife.Alive;
GameOfLife.glider[2][2] = GameOfLife.Alive;
GameOfLife.LWSShip = new Array();
GameOfLife.LWSShip[0]= new Array();
GameOfLife.LWSShip[0][0] = GameOfLife.Dead;
GameOfLife.LWSShip[0][1] = GameOfLife.Alive;
GameOfLife.LWSShip[0][2] = GameOfLife.Alive;
GameOfLife.LWSShip[0][3] = GameOfLife.Alive;
GameOfLife.LWSShip[1]= new Array();
GameOfLife.LWSShip[1][0] = GameOfLife.Alive;
GameOfLife.LWSShip[1][1] = GameOfLife.Dead;
GameOfLife.LWSShip[1][2] = GameOfLife.Dead;
GameOfLife.LWSShip[1][3] = GameOfLife.Alive;
GameOfLife.LWSShip[2]= new Array();
GameOfLife.LWSShip[2][0] = GameOfLife.Dead;
GameOfLife.LWSShip[2][1] = GameOfLife.Dead;
GameOfLife.LWSShip[2][2] = GameOfLife.Dead;
GameOfLife.LWSShip[2][3] = GameOfLife.Alive;
GameOfLife.LWSShip[3]= new Array();
GameOfLife.LWSShip[3][0] = GameOfLife.Dead;
GameOfLife.LWSShip[3][1] = GameOfLife.Dead;
GameOfLife.LWSShip[3][2] = GameOfLife.Dead;
GameOfLife.LWSShip[3][3] = GameOfLife.Alive;
GameOfLife.LWSShip[4]= new Array();
GameOfLife.LWSShip[4][0] = GameOfLife.Alive;
GameOfLife.LWSShip[4][1] = GameOfLife.Dead;
GameOfLife.LWSShip[4][2] = GameOfLife.Alive;
GameOfLife.LWSShip[4][3] = GameOfLife.Dead;
var Config = {};
Config.CellSize = 2;
Config.Height = 200;
Config.Width = 700;
Config.GridColor = "#000";
Config.LiveColor = "red";
Config.DeadColor = "#000"
Config.RowCount = Config.Height / Config.CellSize;
Config.ColCount = Config.Width / Config.CellSize;
var c = document.getElementById('c'),
ctx = c.getContext('2d'),
grid;
GameOfLife.placeFigure = function (fig, x, y) {
for (i = 0; i < fig.length; i++) {
for (j = 0; j < fig.length; j++) {
grid[x + i][y + j] = fig[i][j];
}
}
}
GameOfLife.transposeFigure = function (fig) {
var newfig = new Array();
for (i = 0; i < fig[0].length; i++) {
newfig[i] = new Array();
for (j = 0; j < fig.length; j++) {
newfig[i][j] = fig[j][i];
}
}
return newfig;
}
init = function () {
grid = initGrid();
//GameOfLife.placeFigure(GameOfLife.glider, 0, 0);
//GameOfLife.placeFigure(GameOfLife.transposeFigure(GameOfLife.glider), 15, 15);
//GameOfLife.placeFigure(GameOfLife.glider, 15, 0);
//GameOfLife.placeFigure(GameOfLife.transposeFigure(GameOfLife.glider), 25, 0);
//GameOfLife.placeFigure(GameOfLife.LWSShip, 100, 30);
GameOfLife.placeFigure((GameOfLife.LWSShip), 100, 10);
initCanvas();
renderGrid();
animloop();
}
getPointCell = function (x, y) {
return grid[x][y];
}
initCanvas = function () {
c.width = Config.Width + 1;
c.height = Config.Height + 1;
c.addEventListener('mousedown', startpaint, false);
c.addEventListener('mousemove', paint, false);
c.addEventListener('mouseup', stoppaint, false);
ctx.strokeStyle = Config.GridColor;
ctx.fillStyle = Config.GridColor;
ctx.lineWidth = 1;
ctx.fillRect(0, 0, Config.Width, Config.Height);
}
var paintStarted = false;
function startpaint(ev) {
paintStarted = true;
}
function stoppaint(ev) {
paintStarted = false;
}
function paint(ev) {
if (paintStarted) {
if (ev.layerX || ev.layerX == 0) { // Firefox
ev._x = ev.layerX;
ev._y = ev.layerY;
} else if (ev.offsetX || ev.offsetX == 0) { // Opera
ev._x = ev.offsetX;
ev._y = ev.offsetY;
}
currentDiff[currentDiff.length] = {
x: (ev._x - ev._x % Config.CellSize) / Config.CellSize,
y: (ev._y - ev._y % Config.CellSize) / Config.CellSize
};
grid[(ev._x - ev._x % Config.CellSize) / Config.CellSize][(ev._y - ev._y % Config.CellSize) / Config.CellSize] = (grid[(ev._x - ev._x % Config.CellSize) / Config.CellSize][(ev._y - ev._y % Config.CellSize) / Config.CellSize] + 1) % 2;
}
}
var countNeighbors = function (x, y) {
var count = 0;
for (var i = Math.max(0, x - 1); i <= Math.min(x + 1, Config.ColCount); ++i) {
for (var j = Math.max(0, y - 1); j <= Math.min(y + 1, Config.RowCount); ++j) {
if (i == x && j == y) continue;
count += grid[i][j];
}
}
return count;
}
var currentDiff;
var newState = function () {
currentDiff = new Array();
var changes = 0;
var newGrid = new Array();
for (i = 0; i < grid.length; i++) {
newGrid[i] = new Array();
for (j = 0; j < grid[i].length; j++) {
var neighbors = countNeighbors(i, j);
newGrid[i][j] = grid[i][j];
if (grid[i][j] == GameOfLife.Alive) {
if (neighbors < 2 || neighbors > 3) {
newGrid[i][j] = GameOfLife.Dead;
currentDiff[changes] = {
x: i,
y: j
};
changes++;
}
} else {
if (neighbors == 3) {
newGrid[i][j] = GameOfLife.Alive;
currentDiff[changes] = {
x: i,
y: j
};
changes++;
}
}
}
}
grid = newGrid;
}
var initGrid = function () {
var grid = new Array(Math.round(Config.Width / Config.CellSize) + 1);
for (i = 0; i < grid.length; i++) {
grid[i] = new Array(Math.round(Config.Height / Config.CellSize) + 1);
for (j = 0; j < grid[i].length; j++) {
grid[i][j] = GameOfLife.Dead; //Init all Dead.
}
}
return grid;
}
var renderGrid = function () {
for (var i = 0; i * Config.CellSize < Config.Width; i++) {
for (var j = 0; j * Config.CellSize < Config.Height; j++) {
if (getPointCell(i, j) == GameOfLife.Alive) {
ctx.fillStyle = Config.LiveColor;
} else {
ctx.fillStyle = Config.DeadColor;
}
ctx.fillRect(i * Config.CellSize, j * Config.CellSize, Config.CellSize - 1, Config.CellSize - 1);
}
}
};
var renderDiff = function () {
for (var i = 0; i < currentDiff.length; i++) {
if (getPointCell(currentDiff[i].x, currentDiff[i].y) == GameOfLife.Alive) {
ctx.fillStyle = Config.LiveColor;
} else {
ctx.fillStyle = Config.DeadColor;
}
ctx.fillRect(currentDiff[i].x * Config.CellSize, currentDiff[i].y * Config.CellSize, Config.CellSize - 1, Config.CellSize - 1);
}
};
var render = function () {
renderDiff();
};
function animloop() {
requestAnimationFrame(animloop, c);
if (!paintStarted) {
newState();
}
render();
//
//sleep(1000);
//newState();
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
init()
});
body {
background: #080808;
}
canvas {
display: block;
left: 50%;
margin: -150px 0 0 -350px;
position: absolute;
top: 50%;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment