Game of Life HELP PLEASE

I am working on a game of life challenge and I am having trouble matching my final output to the one provided. Here is the program requirements, final output and my code.

Each cell has a total of up to 8 neighbors, including the 4 immediately adjacent cells and the 4 diagonal cells. The rules for the creation of each cell in the next generation are as follows:

If the cell is currently empty:
If the cell has exactly three living neighbors, it will come to life in the next generation.
If the cell has any other number of living neighbors, it will remain empty.
If the cell is currently living:
If the cell has one or zero living neighbors, it will die of loneliness in the next generation.
If the cell has four or more living neighbors, it will die of overcrowding in the next generation.
If the cell has two or three neighbors, it will remain living.
All births and deaths occur simultaneously (make sure you don't get this one wrong!).

01234567890123456789
 0*  * *   *         *
 1      *       * *
 2    *  *   *  *** *
 3  *  *   **      * *
 4*  * *   *
 5  ** *         ***
 6     **   ** **  **
 7      * *     * *
 8 *   *  * *      *
 9   ** **
10*        *         *
11 *** * **     *  * *
12    *** *
13**     *  **  *****
14  *        * * * * *
15           * *    *
16 **  *  *       *
17     **
18      *         * *
19*  **  *
(ORIGINAL GRID) GAME OF LIFE STATISTICS

Total alive in row 10 = 3
Total alive in col 10 = 4
Total dead in row 16 = 15
Total dead in col 1 = 16
Total alive = 101
Total dead = 299

  01234567890123456789
 0
 1    ***       * **
 2     **   *   * * *
 3   * ** ***    ****
 4 * * **  **      **
 5  ** *    *   *****
 6    ****     **   *
 7      *   ** **** *
 8    **  **
 9    ******
10 *   *            *
11 *** * ***        *
12*  ***  **    *
13 *   ***  *** ** **
14 *         * * *   *
15 **           * ***
16     **
17     ***         *
18    * **
19

The grid after 1 generations have passed.
(GENERATION #1) GAME OF LIFE STATISTICS

Total alive in row 10 = 3
Total alive in col 10 = 6
Total dead in row 16 = 18
Total dead in col 1 = 14
Total alive = 113
Total dead = 287

  01234567890123456789
 0     *
 1    * *         **
 2          *   *   *
 3  *     *  *   *   *
 4   *   **  *  *    *
 5  **   * **  ****  *
 6   **  *  ***     **
 7        *** ** * *
 8    *         **
 9       * *
10 * *
11** * * * *
12*  *       * *** **
13***  ********  ** *
14**    *   ** *     *
15 **           *****
16     * *        * *
17    *
18       *
19

The grid after 2 generations have passed.
(GENERATION #2) GAME OF LIFE STATISTICS

Total alive in row 10 = 2
Total alive in col 10 = 6
Total dead in row 16 = 16
Total dead in col 1 = 15
Total alive = 99
Total dead = 301

  01234567890123456789
 0     *
 1     *           *
 2               ****
 3       *****  **  **
 4   *   *   ***  * **
 5  *   ** *   ***   *
 6  ***  *         ***
 7   **   *** ** ** *
 8          *  ****
 9
10**  * *
11** *          *
12   * *     * *** **
13  *  *****     ** **
14     ** *    *     *
15***   *       *** **
16                * *
17      *
18
19

The grid after 3 generations have passed.
(GENERATION #3) GAME OF LIFE STATISTICS

Total alive in row 10 = 4
Total alive in col 10 = 3
Total dead in row 16 = 18
Total dead in col 1 = 17
Total alive = 97
Total dead = 303

  01234567890123456789
 0
 1                 **
 2        ***   **   *
 3       ***** **
 4           *    **
 5  * * **     ****
 6  * ****  * *    * *
 7  * *   ******    **
 8          ****  **
 9              **
10***
11** * *       ***
12 * * * **    *   ***
13        **  ** **  *
14  *     **
15 *   ***      *** **
16 *              * **
17
18
19

The grid after 4 generations have passed.
(GENERATION #4) GAME OF LIFE STATISTICS

Total alive in row 10 = 3
Total alive in col 10 = 5
Total dead in row 16 = 16
Total dead in col 1 = 15
Total alive = 95
Total dead = 305

  01234567890123456789
 0
 1         *        *
 2       *   * ***  *
 3       *   **** *
 4      *  * *    **
 5    *  *   *****  *
 6 ** *     *    *** *
 7    * ***       *  *
 8               ****
 9 *         ******
10* *          *
11   *  *      **   *
12**    ****       ***
13  *         *** ** *
14      *  *   *   ***
15 **   ***      ** **
16      *         * **
17
18
19

The grid after 5 generations have passed.
(GENERATION #5) GAME OF LIFE STATISTICS

Total alive in row 10 = 3
Total alive in col 10 = 1
Total dead in row 16 = 16
Total dead in col 1 = 16
Total alive = 95
Total dead = 305

Last edited on
HERE IS MY CODE SO FAR
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
class="centertext">#include <iostream> #include <fstream> #include <iomanip> using namespace std; const int SIZE = 20; int GetTotal (bool life[][SIZE]); int GetRowTotal (bool life[][SIZE],int); int GetColumnTotal (bool life[][SIZE],int); void initGrid(bool life[][SIZE], bool life2[][SIZE]); void readGrid(bool life[][SIZE], bool life2[][SIZE]); void printGrid(bool life[][SIZE], bool life2[][SIZE]); int livecellNeighbors (bool life[][SIZE], bool life2[][SIZE],int,int); int deadcellNeighbors (bool life[][SIZE], bool life2[][SIZE],int,int); void determineNextGen(bool life[][SIZE],bool life2 [][SIZE]); int main() { bool life[SIZE][SIZE]; bool life2[SIZE][SIZE]; readGrid(life,life2); printGrid(life, life2); int neighbors; int neighbors2; for (int count = 0; count < 4; count++) { determineNextGen(life,life2); } printGrid(life,life2); /*readGrid(life); for (int count = 0; count < 2; count++) { determineNextGen(life, life2); printGrid(life); cout<<endl; cout<<"Total alive in row 10 = "<<GetRowTotal(life,10)<<endl; cout<<"Total alive in col 10 = "<<GetColumnTotal(life,10)<<endl; cout<<"Total dead in row 16 = "<<20-GetRowTotal(life,16)<<endl; cout<<"Total dead in col 1 = "<<20-GetColumnTotal(life,1)<<endl; cout<<"Total alive = "<<GetTotal(life)<<endl; cout<<"Total dead = "<<400-GetTotal (life)<<endl; cout<<endl; } */ return 0; } /*------------------------------------------------------- readGrid (and related functions) ---------------------------------------------------------*/ void readGrid(bool life[][SIZE], bool life2[][SIZE]) { ifstream infile("bacteria.txt"); int numBacteria, row, col; initGrid(life, life2); infile >> row >> col; while (infile){ life[row][col] = true; infile >> row >> col; } infile.close(); } void initGrid(bool life[][SIZE], bool life2[][SIZE]) { for (int row = 0; row < SIZE; row++) { for (int col = 0; col < SIZE; col++) { life[row][col] = false; } } } void printGrid(bool life[][SIZE], bool life2[][SIZE]) { cout << " 01234567890123456789" << endl; for (int row = 0; row < SIZE; row++) { cout << setw(2) << row; for (int col = 0; col < SIZE; col++) { if (life[row][col]) { cout << "*"; } else { cout << " "; } } cout << endl; } } int livecellNeighbors (bool life[SIZE][SIZE],int row,int col) { int neighbors=0; if(life[row][col]== true && life[row][col-1]==true && col-1>=0)//left { neighbors++; } if(life[row][col]== true && life[row+1][col-1]==true && row+1<=20 && col-1>=0)//left bottom { neighbors++; } if(life[row][col]== true && life[row+1][col]==true && row+1<20)//bottom { neighbors++; } if(life[row][col]== true && life[row][col+1]==true && col+1<20)//right { neighbors++; } if(life[row][col]== true && life[row-1][col-1]==true && row-1>=0 && col-1>=0 )//top left { neighbors++; } if(life[row][col]== true && life[row+1][col+1]==true && row+1<3 && col+1<=20)//bottom right { neighbors++; } if(life[row][col]== true && life[row-1][col]==true && row-1>=0)//top { neighbors++; } if(life[row][col]== true && life[row-1][col+1]==true && row-1>=0 && col+1<20)//top right { neighbors++; } return neighbors; } int deadcellNeighbors (bool life [SIZE][SIZE],int row,int col) { int neighbors2=0; if(life[row][col]== false && life[row][col-1]==true && col-1>=0) { neighbors2++; } if(life[row][col]== false && life[row+1][col-1]==true && row+1<=20 && col-1>=0) { neighbors2++; } if(life[row][col]== false && life[row+1][col]==true && row+1<20) { neighbors2++; } if(life[row][col]== false && life[row][col+1]==true && col+1<20) { neighbors2++; } if(life[row][col]== false && life[row-1][col-1]==true && row-1>=0 && col-1>=0 ) { neighbors2++; } if(life[row][col]== false && life[row+1][col+1]==true && row+1<3 && col+1<=20) { neighbors2++; } if(life[row][col]== false && life[row-1][col]==true && row-1>=0) { neighbors2++; } if(life[row][col]== false && life[row-1][col+1]==true && row-1>=0 && col+1<20) { neighbors2++; } return neighbors2; } void determineNextGen(bool life[][SIZE],bool life2 [][SIZE]) { int neighbors=0,neighbors2=0; for (int row=0;row<SIZE;row++) { for (int col=0;col<SIZE;col++) { neighbors=livecellNeighbors(life,row,col); if (neighbors<=1) life2[row][col]=false; if (neighbors>=4) life2[row][col]=false; if (neighbors==2) life2[row][col]=true; if (neighbors==3) life2[row][col]=true; } } for (int row=0;row<SIZE;row++) { for (int col=0;col<SIZE;col++) { neighbors2=deadcellNeighbors(life,row,col); if (neighbors2==3) life2[row][col]=true; } } for (int row=0;row<SIZE;row++) { for (int col=0;col<SIZE;col++) life[row][col]=life2[row][col]; } } int GetTotal (bool somearray[][SIZE]) { int total=0; for(int i=0;i<SIZE;i++) { for (int j=0;j<SIZE;j++) total=total+somearray[i][j]; } return total; } int GetRowTotal (bool somearray[][SIZE],int row) { int RowTotal=0; for (int j=0;j<SIZE;j++) RowTotal=RowTotal+somearray[row][j]; return RowTotal; } int GetColumnTotal (bool somearray[][SIZE],int col) { int ColumnTotal=0; for (int i=0;i<SIZE;i++) ColumnTotal=ColumnTotal+somearray [i][col]; return ColumnTotal; }




AND THE FIRST GRID SPECS THAT BACTERIA.TXT IS READING
0 0
0 3
0 5
0 9
0 19
1 6
1 14
1 16
2 4
2 7
2 11
2 14
2 15
2 16
2 18
3 2
3 5
3 9
3 10
3 17
3 19
4 0
4 3
4 5
4 9
5 2
5 3
5 5
5 15
5 16
5 17
6 5
6 6
6 10
6 11
6 13
6 14
6 17
6 18
7 6
7 8
7 14
7 16
8 1
8 5
8 8
8 10
8 17
9 3
9 4
9 6
9 7
10 0
10 9
10 19
11 1
11 2
11 3
11 5
11 7
11 8
11 14
11 17
11 19
12 4
12 5
12 6
12 8
13 0
13 1
13 7
13 10
13 11
13 14
13 15
13 16
13 17
13 18
14 2
14 11
14 13
14 15
14 17
14 19
15 11
15 13
15 18
16 1
16 2
16 5
16 8
16 16
17 5
17 6
18 6
18 16
18 18
19 0
19 3
19 4
19 7
Last edited on
Indent everything with [code]... my god this is a mess
Better now?
Your requirements tell you that there are different conditions to meet if the cell is empty or living. You never check to see if the cell you're processing is empty or alive.
so I need another function to check if the cell is alive or dead then feed that info into functions
int livecellNeighbors and int deadcellNeighbors ?
You need one function to count the number of live neighbors. The number of live neighbors doesn't change if the cell you're processing is alive or empty. The only thing that changes is what you do with that number once you have it.

Your determineNextGen is functionally equivalent to this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void determineNextGen(bool life[][SIZE],bool life2 [][SIZE])
{
    int neighbors2=0;

    for (int row=0;row<SIZE;row++)
    {
        for (int col=0;col<SIZE;col++)
        {
            neighbors2=deadcellNeighbors(life,row,col);
            if (neighbors2==3)
                life2[row][col]=true;
        }
    }

    for (int row=0;row<SIZE;row++)
    {
        for (int col=0;col<SIZE;col++)
            life[row][col]=life2[row][col];
    }
}


The second set of loops overwrites anything done by the first.
I dont think that is correct because mu original determineNextGen function is closer to the final output then the one you provided. I think the problem lies within how I am checking the cells in my DeadCell and LivingCell neighbors function.
Mmm.. you're right. They're not equivalent. I was thinking along the lines of their being an else life2[row][col]=false on line 12.

Unfortunately, that doesn't make them right. ;)
On further analysis, I believe you do handle the logic right for the alive/dead situation, albeit in a rather convoluted way.

However, you access outside the array bounds of your array, which results in undefined behavior, and you're using magic numbers which has led to an unfortunate mistake in your neighbor counting functions.
Where am I accessing outside the array bounds, and what magic numbers are you talking about?
Where am I accessing outside the array bounds

Anywhere you have code like this: life[row][col-1]==true && col-1>=0 and access the array before you check to see if the index is out of bounds.

what magic numbers are you talking about?

20, 0... 3.
Any idea on the logic for the livingcell and deadcell algorithm?
Like I said, I believe you're handling that correctly, although you're making it more complicated than it needs to be.

I'd fix the magic number problem. You're also using <= in your neighbor counting functions where < is called for.
So what would you suggestions for fixing the magic numbers?
So what would you suggestions for fixing the magic numbers?


Well, personally, I'd probably code up something like this:
1
2
3
4
5
6
7
8
9
10
bool inBounds(int row, int col)
{
    const int beg = 0;
    const int end = SIZE;

    bool row_in_bounds = row >= beg && row < end;
    bool col_in_bounds = col >= beg && col < end;

    return row_in_bounds && col_in_bounds;
}


and then the neighbor counting functions would end up looking something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int livecellNeighbors(bool life[SIZE][SIZE], int row, int col)
{
    if (life[row][col] == false)
        return 0;

    int neighbors = 0;

    if (inBounds(row, col - 1) && life[row][col - 1])
        ++neighbors;

    if (inBounds(row + 1, col - 1) && life[row + 1][col - 1])
        ++neighbors;

    // ... 
So how would I call the inBoards function?
There is an example in the post where it's defined? (inBounds, not inBoards, although I suppose either works as long as you're consistent.)
Topic archived. No new replies allowed.