DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

Cover image for Developing a Conway's Game of Life algorithm in Javascript
Gordon Caister
Gordon Caister

Posted on

Developing a Conway's Game of Life algorithm in Javascript

First we will start with our possibilities:

Given the possibilities of a cell's neighbours where the cell is 'C' there are 8 possible neighbours as detailed in the tables below, the first table would be cardinal direction while the second table is a relative coordinate where the first digit represents x or the rows, and the second represents y or the columns. I.e. SW is relatively 1 row further than C and -1 column further than C.

NW  N  NE 
W   C  E  
SW  S  SE 

[
 [-1,-1],
 [-1,0],
 [-1,1],
 [0,-1],
 [0,0],
 [0,1],
 [1,-1],
 [1,0],
 [1,1]
]

We need to cycle through each cell in the total grid and compare each of its neighbours and see how many of its neighbours are alive.

To this end, I have represented alive with โ€˜1โ€™ and dead with โ€˜0โ€™ which in javascript equate to truthy and falsy respectively, while still maintaining their integer value.I am using this to my advantage.

Duplicate the existing grid.
For i in rows,
For j in columns
For x,y in possibilities
We will add the current row index (i) to the possible x value
We will add the current col index (j) to the possible y value
If the combined x is greater than or equal to 0 and less than the number of rows and the combined y is greater than or equal to 0 and less than the number of columns:
Add 1 to the total number of neighbours for the current cell
Once weโ€™re finished finding number of neighbours: if the neighbours is greater than 3 or less than 2, set the current cells value to 0 (Rule 1 and 3)
If the current cellโ€™s value is 0 and the number of neighbours is 3, set the current cell to 1 (alive)
All other cells should be left alone
Set the existing grid equal to the altered duplicated grid

    const tempGrid = JSON.parse(JSON.stringify(grid))

    for(let i = 0; i < rows; i++){
      for(let j = 0; j < cols; j++){
        let neighbours = 0;
        possibilities.forEach(([x,y])=> {
          const nextI = i + x;
          const nextJ = j + y;
          if(nextI >= 0 && nextI<rows && nextJ >= 0 && nextJ < cols){
            neighbours += grid[nextI][nextJ] 
          }
        });
        if (neighbours < 2 || neighbours > 3){
          tempGrid[i][j] =  0;
        } else if (grid[i][j] === 0 && neighbours === 3) {
          tempGrid[i][j] = 1;
        }
      };
    }

Given the above code requires a few other pieces of data to run I will include how they existed in my code. I was using React to run my frontend so I used the useState hook to maintain the state of my grid.


const rows = 50
const cols = 50

const possibilities = [
  [-1,-1],
  [-1,0],
  [-1,1],
  [0,1],
  [1,1],
  [1,0],
  [1,-1],
  [0,-1],
]

const zeroArray = (rows,cols)=> {

  let arr = new Array(rows);
  for(let i = 0; i < arr.length; i++){
    arr[i] = new Array(cols);
    for(let j = 0; j < rows; j++){
      arr[i][j] = 0
    }
  }
  return arr;
}

const [grid, setGrid] = useState(zeroArray)

I kept a reference to zeroArray because I wanted to include a function that cleared the board and reset all cells to 0.

Top comments (0)

Now it's your turn.

ย 
Join DEV and share your story.