Game of life code error

I m trying to make the game of life on p5.js. I have used a 2d array of CA class object called ‘cell’ and saving every iteration in ‘new_cell’ and finally copying back the values from ‘new _cell’ to ‘cell’. The code works fine when i create the object ‘new_cell’ in the draw loop but gives a weird output when I create the new_cell object with the cell object in the setup loop.(i have commented out the statements for new_cell in setup). I am unable to understand why does it give wrong value when I initialize in setup versus in draw loop when i anyway reassign the values in every draw loop.

let row_tot, col_tot; //total row and col
let cell = [];

let spacer = 10; //cell size

function setup() {
	createCanvas(500, 500);
	frameRate(10);

	//row_tot and col_tot
	row_tot = height / spacer;
	col_tot = width / spacer;



	//initialize cell
	for (let i = 0; i < col_tot; i++) {
		cell[i] = [];
		//	next_cell[i] = [];

		for (let j = 0; j < row_tot; j++) {

			cell[i][j] = new CA();
			//	next_cell[i][j] = new CA();
		}
	}
}


function draw() {

	background(0); //black background

	//initialize cell
	let next_cell = [];
	for (let i = 0; i < col_tot; i++) {

		next_cell[i] = [];

		for (let j = 0; j < row_tot; j++) {
			next_cell[i][j] = new CA();
		}
	}

	//rule
	for (let i = 0; i < col_tot; i++) {
		for (let j = 0; j < row_tot; j++) {

			//edge case

			//count the neighbour
			let sum = 0;

			for (let p = -1; p <= 1; p++) {
				for (let q = -1; q <= 1; q++) {
					let col = (i + p + col_tot) % col_tot;
					let row = (j + q + row_tot) % row_tot;
					sum += cell[col][row].state;
				}
			}
			sum -= cell[i][j].state;
			
			//Game of life rule
			if (cell[i][j].state == 1 && (sum < 2 || sum > 3)) next_cell[i][j].death(); //death
			else if ((cell[i][j].state == 0) && (sum == 3)) next_cell[i][j].birth(); //birth
			else next_cell[i][j] = cell[i][j]; //stasis


		}
	}

	//update old
	cell = next_cell;

	//render
	for (let i = 0; i < col_tot; i++) {
		for (let j = 0; j < row_tot; j++) {
			cell[i][j].show(i, j);
		}
	}
}

class CA {
	constructor() {
		this.state = random(1) < .5 ? 0 : 1;
	}

	show(a, b) {
		let p = a * spacer;
		let q = b * spacer;

		//draw the rec
		if (this.state == 1) {
			noStroke();
			fill(255);
			rect(p, q, spacer, spacer);
		}
	}


	death() {
		this.state = 0;
	}

	birth() {
		this.state = 1;
	}

}


1 Like

Hello,

Try move “let next_cell = [];” at the top and use “next_cell = [];” in draw()

But it is useless to initialize the next_cells in setup() if you immediately re-initialize them at the start of draw()…

1 Like

If i initialize ‘next_cell’ in setup then i wont be re-initializing in draw. I would just reassign the values everytime. But that gives wrong out put. I cant understand why

The reason why you won’t get the result you expect when initializing next_cell in setup is this line:

//update old
cell = next_cell;

But why? Well, that line does not assign a copy of the next_cell array to the cell variable (as one may expect). It makes the cell variable reference (point to) the same array as the next_cell variable. After that line executes, cell and next_cell points to the same array.

next_cell[0][0] = 9;

// This prints 9 to the console.
console.log(cell[0][0]);

Your life program ends up with just one state. That’s probably not what you want. If the above behavior is new to you, read up on the difference between primitive and reference types in JavasScript.

3 Likes

Thank you so much for making it clear

2 Likes