Making Conway’s Game of Life In JavaScript

The Game of Life is a simulation of cellular automata devised by English mathematician John Conway. Even though it’s referred to as a game the program doesn’t usually involve any user interaction and is just meant to be observed. The game contains a grid of cells which all have one of two possible states, alive or dead. Whether or not a cell is alive or dead is dependent upon the following four rules of the game:

  1. Any live cell with fewer than two live neighbours dies
  1. Any live cell with two or three live neighbours lives on to the next generation.
  1. Any live cell with more than three live neighbours dies
  1. Any dead cell with exactly three live neighbours becomes a live cell

In this article we’ll be using JavaScript to create a basic version of the game.

Page Setup and Variable Definitions

The first thing you need to do before you can create the game is set up a basic HTML document to display it on. All this page needs is a body which contains one canvas element that has an ID. Give the canvas a border so you can see its outer edges easily. It’s height and width will be set later on with JavaScript so don’t worry about that for right now.

<!DOCTYPE HTML>
<html>
<body>
<canvas id="Grid" style="border:1px solid #000">
</canvas>
</body>
</html>

Now once you’ve done this you can begin creating your game. To start you’ll need to define all of the variables that the program will be using.

Firstly you need to get the canvas element ready to be drawn on by creating a drawing object. For more information read this previous article on canvas.

var canvas = document.getElementById('Grid');
var cs = canvas.getContext('2d');

You should define a variable containing how many cells you want the grid to contain. Next define another variable which contains how many pixels large each cell should be.

var CellNumber = 200; //Sets number of Cells 
var cellSize = 4; //Sets pixel size of each cell

You need to use those last two variables that you defined to set the size of your grid. Simply set both the canvases height and width equal to the number of cells multiplied by cell size.

canvas.width = cellSize*CellNumber; //Sets canvas width
canvas.height = cellSize*CellNumber; //Sets canvas height

Lastly you need to define a variable equal to the createArray() function which we’ll be creating in the next section.

var arr = createArray();

Now you can begin creating functions to draw and display the cells.

Drawing and Displaying the Cells

You should start by writing the createArray() function mentioned in the previous section. First define a function that contains an empty array.

function createArray() {
 var arr = []; //Creates an empty array

Next you need to create a for statement which adds a number of empty arrays onto this array equal to the size of the CellNumber variable created earlier. To do this create a for statement which iterates through CellNumber. Inside this for statement create another for statement which also iterates through the CellNumber variable and pushes an empty array onto the end of the original array you defined.

for(var i = 0; i<CellNumber; i++) { //Iterates through total number of cells
 var innerArr = [];
 for(var j = 0; j<CellNumber; j++) {
 innerArr.push(0); 
 }
 arr.push(innerArr); //Pushes an empty array onto the end of arr
 }

To finish up this function have it return the arr variable that was defined at the beginning of it.

return arr;

After this define another function called drawCell which will draw all of the live cells that currently exist in the game. This function takes three values, the x position of the cell, its y position, and whether or not it’s currently alive.

function drawCell(x,y,alive) {

Each cell will be drawn as a rectangle which you can learn more about here in a previous article about how to draw in canvas.

cs.beginPath();
cs.rect(x*cellSize, y*cellSize, cellSize, cellSize);
cs.fillStyle = alive ? 'black' : '#EEE';
cs.fill();

Lastly you should create a function which will display each cell on the page. This function should take one argument, the arr variable which you created earlier on. Once you’ve named the function create a for statement which iterates through the arr variable. Inside this for statement create another for statement which iterates through each array inside the arr variable and draws each cell.

function display(arr) {
 for(var x = 0; x < arr.length; x++) {
 for(var y = 0; y < arr[x].length; y++) {
 drawCell(x,y,arr[x][y]);
 }
 }
}

Now it’s time to randomly populate the grid with live cells and run the game.

Running the Game

Create a function called randPop which takes one argument, the arr variable from earlier. This should iterate through each array within the arr variable and randomly assign some of those arrays to contain live cells.

function randPop(arr) {
 for(var x = 0; x < arr.length; x++) {
 for(y = 0; y < arr[x].length; y++) {
 if(Math.log(Math.random()*10) < -0.6) { 
 arr[x][y]=1; //Randomly Places a live cell down
 }
 }
 }
}

Now create a function which checks if each cell is currently alive. This function should go through the arr variable and check the current status of each cell. Return the number of currently living cells or if there are no living cells just return 0.

function aliveNeighbors(arr, x, y) {
 if(x > 0 && y > 0 && x < CellNumber - 1 && y < CellNumber - 1) {
 var totalAlive = //Calculates the number of currently living cells
 arr[x - 1][y - 1] +
 arr[x][y - 1]+
 arr[x + 1][y - 1] +
 arr[x - 1][y] +
 arr[x + 1][y] +
 arr[x - 1][y + 1] +
 arr[x][y + 1] +
 arr[x + 1][y + 1];
 return totalAlive; //Returns amount of live cells in current generation
 } else {
 return 0;
 }
}

Next create a function called generation which will create each generation of cells after the first, it should take the arr variable you defined earlier as its only argument. This function should iterate through each array within the arr variable and determine if each cell within them will live or die this generation.

function generation(arr) {
 var newArr = createArray();
 for(var x = 0; x < arr.length; x++) {
 for(var y = 0; y < arr[x].length; y++) {
 var cell = arr[x][y];
 var alives = aliveNeighbors(arr, x,y);

 if(cell == 1) {
 if(alives < 2) { newArr[x][y] = 0; //Tests if cell has less then two neighbors } else if(alives == 2 || alives == 3) { newArr[x][y] = 1; // Tests if cell has two or three neighbors } else if(alives > 3) {
 newArr[x][y] = 0; //Tests if cell has three or more neighbors
 }
 } else if(cell == 0 && alives == 3) {
 newArr[x][y] = 1; //Tests if dead cell has three neighbors
 }
 }
 }
 return newArr;
}

Lastly use the setInterval method to set the speed at which each new generation is created and then call the randPop and display functions.

setInterval(function() { //Runs the next generation every 50 milliseconds
 var newArr = generation(arr);
 display(newArr);
 arr = newArr;
}, 50);

randPop(arr);
display(arr);

Here’s an example of what a random game generated by this code may look like.

Further Suggestions

Once you’ve created a basic simulation of Conway’s game of life you can go on to create extremely complex patterns, in fact the game is even proven to be Turing Complete. A few examples which are a bit more simple to create include the Gosper Glider Gun, various still life patterns, and oscillators just to name a few. Instead of having the generation be completely random try instead inserting one of patterns mentioned above and see what happens.

Good Luck!

Download the above source code here.

If you have any comments or questions email them to me at nick@crumbsofcode.com