Conways Game of Life p5js

Viewed 168

am trying to create conways game of life using p5js. (p5js website)

here is a link to a gif of the simulation: Google Drive Link

I have two 2d arrays, one to hold the current grid and one to hold the updated grid. the arrays hold a value of 0 = empty or 1 = active. I use an image to draw the grid with 1 pixel representing a cell in the grid. Now when I run the program it does something I cant explain (Explosive Growth.. See gif), but I think it has something to do with the rules to decide whether a cell should be active or not. Or it could possibly be something to do with me have multiple grids?

any help would be appreciated to help find whats wrong and why its producing these patterns

heres my logic to decide whether a cell should be active or not

for(var x = 0; x < width; x++){
  for(var y = 0; y < height; y++){
    //get cells neighbors
    var n = getNeighbors(x,y);

    //if cell is active
    if(grid[x][y] == 1){
      // #1 - Any live cell with fewer than two live neighbors dies, as if by underpopulation.
      if(n < 2){
        newGrid[x][y] = 0;
      }else if(n > 3){// #3 -Any live cell with more than three live neighbors dies, as if by overpopulation.
        newGrid[x][y] = 0;
      }

      // #2 - Any live cell with two or three live neighbors lives on to the next generation.
      // this doesnt need a statement since if neighbors value is not < 2 or not > 3 then the value can only be 2 or 3
    }else{
      // #4 - Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
      if(n == 3){
        newGrid[x][y] = 1;
      }
    }
  }
}

and just for reference here is the whole source with comments(135 lines)

var grid = [];
var newGrid = [];
var img;

function setup() {
    createCanvas(400, 400);
    frameRate(10);
    //populate grid array
    for (var i = 0; i < width; i++) {
        grid[i] = [];
        for (var j = 0; j < height; j++) {
            var r = random(0, 1);

            if (r > 0.9) {
              grid[i][j] = 1;
            } else {
              grid[i][j] = 0;
            }
        }
    }

    //populate newgrid
    newGrid = grid;

    //create img object
    img = createImage(width, height);

    //populate img pixels
    drawImageUsingGrid();

    //draw img
    image(img, 0, 0);
}

function draw() {

    //loop through grid
    for (var x = 0; x < width; x++) {
        for (var y = 0; y < height; y++) {
            //get cells neighbors
            var n = getNeighbors(x, y);

            //if cell is active
            if (grid[x][y] == 1) {
                // #1 - Any live cell with fewer than two live neighbors dies, as if by underpopulation.
                if (n < 2) {
                    newGrid[x][y] = 0;
                } else if (n > 3) { // #3 -Any live cell with more than three live neighbors dies, as if by overpopulation.
                    newGrid[x][y] = 0;
                }

                // #2 - Any live cell with two or three live neighbors lives on to the next generation.
                // this doesnt need a statement since if neighbors value is not < 2 or not > 3 then the value can only be 2 or 3
            } else {
                // #4 - Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
                if (n == 3) {
                    newGrid[x][y] = 1;
                }
            }
        }
    }

    //set current grid to the new updated grid
    grid = newGrid;

    //set img pixels based upon grid
    drawImageUsingGrid();

    //draw img
    image(img, 0, 0);
}

function getNeighbors(x, y) {
    //hold # of neighbors
    var neighbors = 0;

    //check if neighbor exists at index and is active
    if (grid[x] && grid[x][y - 1] && grid[x][y - 1] == 1) { //top
        neighbors++;
    }
    if (grid[x + 1] && grid[x + 1][y] && grid[x + 1][y] == 1) { //right
        neighbors++;
    }
    if (grid[x] && grid[x][y + 1] && grid[x][y + 1] == 1) { //bottom
        neighbors++;
    }
    if (grid[x - 1] && grid[x - 1][y] && grid[x - 1][y] == 1) { //left
        neighbors++;
    }

    //diagonal neighbors
    if (grid[x - 1] && grid[x - 1][y - 1] && grid[x - 1][y - 1] == 1) {         //topleft
        neighbors++;
    }
    if (grid[x + 1] && grid[x + 1][y - 1] && grid[x + 1][y - 1] == 1) { //topright
        neighbors++;
    }
    if (grid[x - 1] && grid[x - 1][y + 1] && grid[x - 1][y + 1] == 1) { //bottomleft
        neighbors++;
    }
    if (grid[x + 1] && grid[x + 1][y + 1] && grid[x + 1][y + 1] == 1) { //bottomright
        neighbors++;
    }

    return neighbors;
}

function drawImageUsingGrid() {
    //load img pixels to be edited
    img.loadPixels();

    //2d for loop
    for (var i = 0; i < img.width; i++) {
        for (var j = 0; j < img.height; j++) {
            if (grid[i][j] == 0) {
                //get pixel at x,y
                var pix = getPixelIndex(i, j);
                //set pixel rgba
                img.pixels[pix + 0] = 255;
                img.pixels[pix + 1] = 255;
                img.pixels[pix + 2] = 255;
                img.pixels[pix + 3] = 255;
            } else {
                //get pixel at x,y
                var pix = getPixelIndex(i, j);
                //set pixel rgba
                img.pixels[pix + 0] = 0;
                img.pixels[pix + 1] = 0;
                img.pixels[pix + 2] = 0;
                img.pixels[pix + 3] = 255;
            }
        }
    }
    //update img pixels
    img.updatePixels();
}

function getPixelIndex(x, y) {
    return (x + y * width) * 4;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script>

0 Answers
Related