DEV Community

Kacha
Kacha

Posted on

Game of Life with React Native easy grid

I have been learning react native over the past month or two and I decided as a way to learn and familiarise myself with it by making some fun little projects.
For my first project I created Conway's Game of Life using react native easy grid and create-react-native-app. First create a CRNA app and install the grid library.
create-react-native-app GameOfLife && cd GameOfLife
npm install react-native-easy-grid
Then in App.js import easy grid and create the following class:

import React from 'react';
import { StyleSheet, View} from 'react-native';
import {Col, Row, Grid} from 'react-native-easy-grid';
export default class App extends React.Component {
  gridNum = 40; // The number of rows and columns in our grid
  constructor(props){
    super(props);
    let newBoard = this.setupBoard() 
    this.state = {
      board: newBoard
    }
  }
  setupBoard = () => {
    // Create a two dimensional array to represent the grid
    let board = new Array(this.gridNum)
    for (i = 0; i < this.gridNum; i++){
      board[i] = new Array(this.gridNum)
    }
    for(x=0; x< this.gridNum; x++){
      for(y=0; y < this.gridNum; y++){
        // Creates a grid square object that holds a random number 
        // between 0 for a dead cell and 1 for alive 
        // n represents the number of neighbours a cell has
        board[x][y] = {
          cell:Math.floor(Math.random()*2),
          n:0
        }
      }
    }
    return board
  }


  render(){
    return(
      <Grid>
        // Code To be Done
      </Grid>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The above code sets up the board, then I created two functions:
To check for the number of neighbours each cell has and,
A function to get the next generation of cells.

checkNeighbours = () => {
  let oldBoard = this.state.board
  // Ignores the columns and rows on the outermost edges
  for(x=1; x< this.gridNum-1; x++){
    for(y=1; y < this.gridNum-1; y++){
      \\ For every grid cell check how many neighbours it has
      for(i=-1; i< 2; i++){
        for(j=-1; j < 2; j++){
          oldBoard[x][y].n += oldBoard[(x+i)][(y+j)].cell
        }
      }
      \\ Delete the value of the current cell as it was counted in  
      \\ the above calculation
      oldBoard[x][y].n -= oldBoard[x][y].cell
    }
  }
  this.setState({board: oldBoard})
}
newBoard = () => {
  let oldBoard = this.state.board
  let board = this.setupBoard()
  // Set all new board values to zero
  for(let a = 0; a < this.gridNum; a++){
    for(let b=0; b<this.gridNum;b++){
      board[a][b] = {cell:0, n:0}
    }
  }
  for(x=1; x< this.gridNum-1; x++){
    for(y=1; y < this.gridNum-1; y++){
      if((oldBoard[x][y].cell == 1) && oldBoard[x][y].n < 2){
        board[x][y].cell = 0
      } else if((oldBoard[x][y].cell == 1) && oldBoard[x][y].n > 3){
        board[x][y].cell = 0
      } else if((oldBoard[x][y].cell == 0) && oldBoard[x][y].n == 3)
      {
        board[x][y].cell = 1
      } else if((oldBoard[x][y].cell == 1)&& (oldBoard[x][y].n == 3 
                 || oldBoard[x][y].n == 2)){
        board[x][y].cell = 1
      } else{
        board[x][y].cell = oldBoard[x][y].cell
      }
    }
  }
  this.setState({board: board})
}
For the game of life to update these two functions above must be called continuously. For this I created a helper function called "run" and used setInterval() to have it called every second.
constructor(props){
  ... // Above code skipped for brevity
  setInterval(this.run, 1000);
}
run = () => {
  this.checkNeighbours()
  this.newBoard()
}
Enter fullscreen mode Exit fullscreen mode

Finally I render the grid to the screen.

render(){
  return(
    <Grid>
      {this.state.board.map((row, key)=>{
        return <Col key={key}>{row.map((cell, key)=>{
          return <Row style= 
            // If cell is 1(alive) render a color there
            {{backgroundColor:cell.cell==1?'#00FFFF':'#FFF', 
            margin:1}} key={key}></Row>
        })}</Col>
      })}
    </Grid>
  );
}
Enter fullscreen mode Exit fullscreen mode

I know this could probably be done more elegantly in something like three.js but it was a fun experiment. Here is a link to the Github repository. And the final product (which has been sped up slightly).

Game of Life react native app gif

Top comments (1)

Collapse
 
matedemorphy profile image
Joseph Palmezano

react-native-easy-grid doesn't do anything of what the docs says it does. It's useless