In this tutorial, we are going to implement Conway’s Game of Life in Javascript. The final code is available on my Github account.

The Game of Life is a cellular automaton devised by the mathematician John Horton Conway.

A cellular automaton is a discrete model studied in many scientific fields. It consists of a regular grid of cells, each one with a finite number of states (e.g. ON or OFF). Each cell has neighbours relative to the specific cell. An initial state (t=0) is selected by assigning a state for each cell. A new generation is created advancing t by 1, according to some rules that determine the new state of each cell.

For example, in Conway’s Game of Life, these rules are:

  1. Any live cell with fewer than 2 live neighbours dies as if caused by underpopulation.
  2. Any live cell with 2 or 3 live neighbours lives on to the next generation.
  3. Any live cell with more than 3 live neighbours dies, as if by overpopulation.
  4. Any dead cell with exactly 3 live neighbours becomes a live cell, as if by reproduction.

Flow

We will create the HTML elements such as the canvas, buttons and text to display different information.

Next, we declare all the variables for working with canvas and the map grid. We create the Cell class and some helper functions for initialization, for getting the clicked cell, for getting the neighbours count, for applying the rules over the grid, etc. Then we write the main loop and iterate to the next generation by pressing the “Step” button. That’s basically all.

Code

Firstly we need to create a canvas and the controls in the <body> of empty HTML skeleton.

Next, for the sake of convenience, we create the <script> tag and write the javascript code here, inside the HTML file, although it is recommended to write JavaScript code in a separate file.

Because the canvas is 800 by 500, and the size of the cell will be 20, we create a 40 by 25 grid. We can increase this numbers, but only a 40*25 grid will be rendered if you don’t increase the canvas size as well.

The variables are:

The cell class is the main component of this project. The grid will consist of width*height cells object. A cell has an X position, Y position, a size and the isAlive state, which is true or false. It also has a draw() function that will render the cell on the canvas as rectangles. If the cell is alive, it the color will be black and if its dead is white.

We initialize the grid with cell objects:

Now we need a mechanism to place alive cells on the grid. We are going to implement an eventListener for the canvas in which we are going to map the X and Y mouse position to the cell grid.

Now, in order to apply the rules for this Game of Life, we need a function in which we pass a cell as an argument and we get the number of neighbours of that cell. We need to take extra care for special cases, such as when a cell is near the edge of the grid.

We have now all the functions that are needed in order to apply the rules to every cell of the grid. We can’t apply the rules to the main grid because when we change the state of a cell, the number of neighbours of the cells nearby will change. In order to work around this, we create a temporary map with all the cells of the main map, and we get the number of neighbours from the main grid and we apply the rules on the temporary map.

The main loop of the program is the animate() function. At every call of the function, we “requestAnimationFrame(animate)” to get the infinite loop of the program to draw the cells. But the calls are too fast, so we need to implement a mechanism to control the number of frames rendered per second. Basically, have a time interval which is (1000/FPS). For example, we declared the FPS variable to be 5. This forces a loop cycle to be 1000/5=200ms, which roughly means that we will render 5 generations per second. When the difference between now and the last recorded time is greater than the interval, we apply the rules to the grid and we draw every cell.

The drawCells() function loops through every cell of the grid and calls its draw function.

The last function is automate() which is going to toggle the “isAutomate” variable which tells if we apply the rules every loop frame or not. If not, the “Step” button will control the advancing into the next generations.

In the end, in order for this to work, we need to call initializeMap() function and animate() and we can close the <script> tag.

The full code can be found on my Github account here.

Demo time

A working demo of this Conway’s Game of Life tutorial can be found here!

If you find errors or have suggestions, please leave a comment down below :).