Conways Game of Life

Previous Next
Processing Sketches
  const gridLines = false;
  const cellSize = 5;
  const canvasWidth = 500;
  const canvasHeight = 500;
  const gridSize = canvasWidth / cellSize;
  var generationHistory = [];

  class Cell {
    constructor(alive, posX, posY) {
        this.alive = alive;
        this.posX = posX;
        this.posY = posY;
    }
  }

  function setup() {
    // initialise grid
    var grid = [];
    for(let i=0; i < gridSize; i++) {
        grid[i] = new Array(gridSize);
    }
    //fill grid with cells.
    for(let i = 0; i < gridSize; i++ ) {
        for(let j = 0; j < gridSize; j++ ) {
            grid[i][j] = new Cell(false, i*cellSize, j*cellSize);
        }
    }
    if (!gridLines){
      noStroke();
    }
    // Random initial state
    for(let i = 0; i < gridSize; i++) {
        for(let j = 0; j < gridSize; j++) {
          let r = Math.random();
          if (r < 0.1){
            grid[i][j].alive = true;
          }          
        }
    }
    generationHistory.push(grid);
    createCanvas(canvasWidth, canvasHeight);
    frameRate(1)
  }

  function updateCell(i, j, currentGenerationGrid, nextGenerationGrid) {
    let count = 0;

    let left = i - 1;
    let right = i + 1;
    let top = j - 1;
    let bot = j + 1;

    // make edges wrap
    if (i === 0) left = gridSize - 1;
    if (i === gridSize - 1) right = 0;
    if (j === 0) top = gridSize - 1;
    if (j === gridSize - 1) bot = 0;

    if(currentGenerationGrid[left][top].alive)count++;
    if(currentGenerationGrid[i][top].alive)count++;
    if(currentGenerationGrid[right][top].alive)count++;
    if(currentGenerationGrid[left][j].alive)count++;
    if(currentGenerationGrid[right][j].alive)count++;
    if(currentGenerationGrid[left][bot].alive)count++;
    if(currentGenerationGrid[i][bot].alive)count++;
    if(currentGenerationGrid[right][bot].alive)count++;

    if((currentGenerationGrid[i][j].alive) && (count < 2 || count > 3)) {
        nextGenerationGrid[i][j].alive = false;
    } else if(count === 3 && !currentGenerationGrid[i][j].alive) {
        nextGenerationGrid[i][j].alive = true;
    } else if(currentGenerationGrid[i][j].alive && (count === 2 || count === 3)) {
        nextGenerationGrid[i][j].alive = true;
    }
  }

  function copyGrid(grid) {
    let copy = [];
    for(let i = 0; i < gridSize; i++) {
        copy[i] = [];
        for (let j=0; j< gridSize; j++){
          copy[i][j] = new Cell(grid[i][j].alive, grid[i][j].posX, grid[i][j].posY);
        }
    }
    return copy;
  }

  function draw() {
    // clear the entire canvas
    background(255);
    var grid = generationHistory[generationHistory.length-1];

    if (gridLines){
      //draw grid 
      fill(200);
      for(let i=0; i < gridSize; i++) {
        for(let j=0; j < gridSize; j++) {
          rect(grid[i][j].posX, grid[i][j].posY, cellSize, cellSize)  
        }
      }
    }

    let currentGenerationGrid = copyGrid(grid);
    let totalGrid = copyGrid(grid);
    let nextGenerationGrid = copyGrid(grid);
    generationHistory.push(nextGenerationGrid);
    if (generationHistory.length > 44){
      generationHistory.shift();
    }

    //draw history 
    var shade = 250;
    for (let h = generationHistory.length-1; h >= 0; h--){
      shade -= 5;
      for(let i = 0; i < gridSize; i++) {
        for(let j = 0; j < gridSize; j++) {
            if (generationHistory[h][i][j].alive && !totalGrid[i][j].alive) {
                totalGrid[i][j].alive = true;
                fill(250-shade,250-shade,shade);
                rect(grid[i][j].posX, grid[i][j].posY, cellSize, cellSize);
            }
        }
      }
    }

    //draw live cells
    fill(0);
    for(let i = 0; i < gridSize; i++) {
        for(let j = 0; j < gridSize; j++) {
            if (grid[i][j].alive) {
                 rect(grid[i][j].posX, grid[i][j].posY, cellSize, cellSize);
            } 
        }
    }

    for(let i = 0; i < gridSize; i++) {
        for(let j = 0; j < gridSize; j++) {
            updateCell(i, j, currentGenerationGrid, nextGenerationGrid);
        }
    }
  }