Game of Life Neighbour Checking Not Working

Hi guys,

I've officially given up on this one! I've been pouring over this code for a few hours now and I can't figure out why it's not working properly.

I was recently introduced to Conway's Game of Life and decided to try and implement it as a little coding challenge. I originally wrote it VBA in Excel and it's been working fine. I decided to try and implement it in C++ but I've immediately run into a problem. I've written a function which takes a 2D array as a parameter, along with row and column indices and the row and column bounds of the array. It then checks all in-bounds elements surrounding the row and column indices and counts the number of 'live' neighbours (1 == 'live' and 0 == 'dead').

For the sake of testing I've created a 5x5 array and manually filled it. I'm then looping though it, calling my function for each element and outputting the result to the console window. In the example below you would expect to see a value of 1 for elements [3][3], [3][4] and [4][3] because each has 1 live neighbour. Instead however element [3][3] is correctly identified as having 1 live neighbour but [3][4] and [4][3] aren't. I can't figure out why!

The equivalent function I wrote in VBA works perfectly given the same conditions so the logic appears to be sound. I'm thinking I'm either not doing it the 'C++ way' or there's some very simple, obvious mistake I've made that I just haven't spotted.

I'm not getting any compilation errors or warnings and I'm using Visual Studio Community 2015.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//Constants to define array size
const int ROW = 5;
const int COL = 5;

int main()
{

	//Arrays to hold current and next generations
	int currentGenArr[ROW][COL] = {
		{0, 0, 0, 0, 0} ,
		{0, 0, 0, 0, 0} ,
		{0, 0, 0, 0, 0} ,
		{0, 0, 0, 0, 0} ,
		{0, 0, 0, 0, 1}
	};
	int nextGenArr[ROW][COL];

	//Both arrays begin in the same state so copy currentGenArr to nextGenArr
	copyArrToArr(currentGenArr, nextGenArr);

	//Counters for loops
	int r;
	int c;
	//Counter for live neighbours
	int n = 0;

	for (r = 0; r < ROW; r++) {

		//Reset live neighbour count at the start of each loop
		n = 0;

		for (c = 0; c < COL; c++) {

			n = getLiveNeighbourCount(currentGenArr, r, c, ROW, COL);
			std::cout << "(row/col): (" << r << "," << c << ") n = " << n << std::endl;

		}

	}

	system("pause");

    return 0;

}

int getLiveNeighbourCount(int arr[ROW][COL], int rowIndex, int colIndex, int rowLength, int colLength)
{

	//counter for live neighbours
	int i = 0;
	//the array indices we are working with
	int r = rowIndex;
	int c = colIndex;
	//the bounds of the array
	int WIDTH = colLength - 1;
	int HEIGHT = rowLength - 1;

	//if both r and c are greater than 0 we can safely check left, upper-left and upper elements
	if (r > 0 && c > 0) {

		if (arr[r][c - 1] == 1) { i += 1; } 	//left element
		if (arr[r - 1][c - 1] == 1) { i += 1; }	//upper-left element
		if (arr[r - 1][c] == 1) { i += 1; }	//upper element

		else if (r == 0 && c > 0) {

			//safe to check left element only
			if (arr[r][c - 1] == 1) { i += 1; }

			else if (r > 0 && c == 0) {

				//safe to check upper element only
				if (arr[r - 1][c] == 1) { i += 1; }

			}
		}
	}

	//if both are less than the row and col bounds of the array we can safely check right, lower-right and lower elements
	if (r < HEIGHT && c < WIDTH) {

		if (arr[r][c + 1] == 1) { i += 1; }		//right element
		if (arr[r + 1][c + 1] == 1) { i += 1; }	//lower-right element
		if (arr[r + 1][c] == 1) { i += 1; }		//lower element

		else if (r < HEIGHT && c == WIDTH) {

			//safe to check lower element only
			if (arr[r + 1][c] == 1) { i += 1; }

			else if (r == HEIGHT && c < WIDTH) {

				//safe to check right element only
				if (arr[r][c + 1] == 1) { i += 1; }

			}
		}
	}

	//safe to check upper-right element
	if (r > 0 && c < WIDTH) {

		if (arr[r - 1][c + 1] == 1) { i += 1; }

	}

	//safe to check bottom-left element
	if (r < HEIGHT && c > 0) {

		if (arr[r + 1][c - 1] == 1) { i += 1; }

	}

	return i;

}


Edit: Sorry guys I've no idea what happened with the indenting. I copied the code straight out of Visual Studio and it is all properly indented and spaced etc. there. It's pasted into the forum in a bit of a mess though for some reason. The post preview button doesn't appear to work so I couldn't catch it before I posted. Seems to be fixed now? Anyway, hope you can read it okay. Sorry for the mess up!
Last edited on
The condition on line 66 can never be true, because this condition is evaluated only when the condition on line 60 is true. So when line 66 is reached we know r cannot be equal to 0. You've made other similar logic errors in your code.

If it's not clear, the else on line 66 is associated with the if on line 64.
Thank you so much cire! I knew it was something simple I was overlooking. I've fixed the code as below and it appears to be working correctly now. I'll continue testing to make sure it's robust. Thank you again.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
int getLiveNeighbourCount(int arr[ROW][COL], int rowIndex, int colIndex, int rowLength, int colLength)
{

	//counter for live neighbours
	int i = 0;
	//the array indices we are working with
	int r = rowIndex;
	int c = colIndex;
	//the bounds of the array
	int WIDTH = colLength - 1;
	int HEIGHT = rowLength - 1;

	//if both r and c are greater than 0 we can safely check left, upper-left and upper elements
	if (r > 0 && c > 0) {

		if (arr[r][c - 1] == 1) { i += 1; } 	//left element
		if (arr[r - 1][c - 1] == 1) { i += 1; }	//upper-left element
		if (arr[r - 1][c] == 1) { i += 1; }	//upper element
	}

	else if (r == 0 && c > 0) {

		//safe to check left element only
		if (arr[r][c - 1] == 1) { i += 1; }
	}

	else if (r > 0 && c == 0) {

		//safe to check upper element only
		if (arr[r - 1][c] == 1) { i += 1; }
	}

	//if both are less than the row and col bounds of the array we can safely check right, lower-right and lower elements
	if (r < HEIGHT && c < WIDTH) {

		if (arr[r][c + 1] == 1) { i += 1; }		//right element
		if (arr[r + 1][c + 1] == 1) { i += 1; }	//lower-right element
		if (arr[r + 1][c] == 1) { i += 1; }		//lower element
	}

	else if (r < HEIGHT && c == WIDTH) {

		//safe to check lower element only
		if (arr[r + 1][c] == 1) { i += 1; }
	}

	else if (r == HEIGHT && c < WIDTH) {

		//safe to check right element only
		if (arr[r][c + 1] == 1) { i += 1; }
	}

	//safe to check upper-right element
	if (r > 0 && c < WIDTH) {

		if (arr[r - 1][c + 1] == 1) { i += 1; }
	}

	//safe to check bottom-left element
	if (r < HEIGHT && c > 0) {

		if (arr[r + 1][c - 1] == 1) { i += 1; }
	}

	return i;

}
Last edited on
Topic archived. No new replies allowed.