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>