How I programmed Conway’s Game of Life in React (Lambda School)

Grant Reighard
3 min readDec 12, 2018

--

Conway’s Game of Life is a cellular automaton devised by British mathematician John Horton Conway in 1970.

It has a grid of cells that are either “alive” or “dead” and that turn into the next generation of cells by following four simple rules:

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

How to start

The first step is how most people create React apps: create-react-app <app-name>. This is an alias for npx create-react-app, which needs to be installed globally by npm install -g create-react-app. This process creates the boilerplate code for your app. You can then cd <app-name> and yarn start to open your new app in a browser window.

But what about the grid? How do we get that to show up? This is done using an HTML5 canvas. In your Game.js component, inside the render(){} and return() (the JSX area), write something like this:

The width and height can be hard-coded initially, but in my case, I eventually developed different sizes of grids (small, medium, and large) with different cellSizes.

The grid is drawn using canvas functions:

drawBoard() is called twice, once in componentDidMount() and once after changing the size of the board using a select tag, with a timeout of 10 ms to wait for the canvas to draw.

Now, for toggling the cells on and off. You want this to be an option only when the grid is not animating. This is done with a simple continueAnimating flag set on state.

How this is called, using the flag to prevent toggling when animating:

So now the squares (or “cells”) can be toggled on/yellow or off/blue. My favorite named CSS color is “dodgerblue” if you were curious. Now it’s time to animate. This is done with requestAnimationFrame() which calls itself over and over again. This next block includes the actual logic for checking each neighbor for its alive/dead status (which in my matrices are either 0 or 1) and for following the four game rules.

The rest of the code in the components does as follows:

  1. Toggle button for starting and stopping the animation.
  2. A clear button which clears the grid with a function and a blank matrix.
  3. A function for changing the speed with setTimeout().
  4. A way to change the board size with parameters set on state: cellSize, numX, numY, boardSize. This also sets the firstMatrix, secondMatrix, and clearMatrix to the appropriately-sized ones for the selected size.
  5. An onClick for the canvas, which is what changes the array entries based on coordinates of mouse clicks on the canvas.
  6. A randomizer which uses Math.round() and Math.random() to randomize the grid.
  7. A preset configuration picker, which sets the grid to specific structures with fun behaviors.

And in my JSX:

  1. Start/stop button
  2. Clear button
  3. Three speed buttons, which change the state and thus the setTimeout
  4. Board size drop down
  5. Three dropdowns that are board-size dependent, with preset configurations. This is because the Pulsar is too big for a 15x15 grid and the Gosper glider gun is too big for a 50x50 grid.
  6. A Random button
  7. A generation counter

That sums it up! To play the game, go to my silly domain name.

Thanks, and enjoy!

--

--