Life

An automated version of Conway's Game of Life.

by Dean Panayotov

HTML

<body>
    <canvas id="life"></canvas>
    <h2 unselectable="on">00:00:0000</h2>    
    <body>

CSS

body {
    background-color: #031634;
    color: #E8DDCB;
    text-align: center
}
h2 {
    font: 16px Tahoma, Helvetica, Arial, Sans-Serif;
    text-align: center;
    color: #EEEEEE;
    text-shadow: 0px 2px 3px #555;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    -o-user-select: none;
    user-select: none;
}

JavaScript

var Life = new Object();
var Grid = new Object();

/**
 *
 * Why is half of the stuff attached to a Life object and the
 * other half to a Grid object?: No good reason. Just to
 * indicate which stuff is related to life cycle and which
 * to grid operations.
 *
 * Controls below @line:302
 *
 */

///// GRID ///////////////////////////////////////////////////

Grid.init = function (m, n) {
    var i, j, column, array = [];
    for (i = 0; i < m; i++) {
        column = [];
        for (j = 0; j < n; j++) {
            column[j] = Life.DEAD;
        }
        array[i] = column;
    }
    return array;
};

Grid.drawOnCanvas = function () {
    var i, j, column;
    for (i = 0; i < Life.grid.length; i++) {
        column = Life.grid[i];
        for (j = 0; j < column.length; j++) {
            if (column[j] == Life.ALIVE) {
                Life.context.fillStyle = Life.COLOR_ALIVE;
            } else {
                Life.context.fillStyle = Life.COLOR_DEAD;
            }
            Life.context.fillRect(Life.CELL_GAP + i * (Life.CELL_SIZE + 2 * Life.CELL_GAP), Life.CELL_GAP + j * (Life.CELL_SIZE + 2 * Life.CELL_GAP), Life.CELL_SIZE, Life.CELL_SIZE);
        }
    }
};

Grid.clone = function (from, to) {
    for (var i = 0; i < from.length; i++) {
        to[i] = from[i].slice(0); //cloning the array...
    }
};

Grid.shiftDown = function () {
    var i, j, column, changes = 0;
    for (i = 0; i < Life.grid.length; i++) {
        column = Life.grid[i];
        j = Life.pile[i];
        while (Life.grid[i][j] == Life.ALIVE) {
            j--;
        }
        Life.pile[i] = j;
        j--; //skip the first empty cell
        while (j >= 0) {
            if (Life.grid[i][j] == Life.ALIVE) {
                Life.grid[i][j] = Life.DEAD;
                Life.grid[i][j + 1] = Life.ALIVE;
                changes++;
            }
            j--;
        }
    }
    if (changes === 0) {
        Life.state = Life.IDLE;
        clearInterval(Life.interval);
   ...