Game of life program

The program I am trying to write is the game of life. I have all the beginning part set up correctly as the instructor gave us most of it. Now I am stuck at the part where cells need to die and come to life. I don't know if it is an issue with my determining neighbors or my determinNextGeneration function. basically what happens is if the cell is false and has three live neighbor cells it become true (living). if the cell is already true and has 1 or 0 living (true) neighbor cells it dies (false). If the cell is living (true) and has 4 or more living neighbors it dies (false). Finally if the living cell has two or three living neighbors it stays alive. After the code I have put in the file I am reading from for the first generation.

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
  #include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

const int SIZE = 20;


void initGrid(bool life[][SIZE],bool life2[][SIZE]);
void readGrid(bool life[][SIZE], bool life2[][SIZE]);
void printGrid(bool life[][SIZE]);
int livecellNeighbors (bool life[][SIZE],int,int);
int deadcellNeighbors (bool life [][SIZE],int,int);
void determineNextGen(bool life[][SIZE], bool life2 [][SIZE]);


int main()
{
    bool life[SIZE][SIZE];
    bool life2[SIZE][SIZE];

    readGrid(life,life2);
    int neighbors;
    int neighbors2;
    //for (int count = 0; count < 5; count++)
      //  {
            determineNextGen(life, life2);
        //}

    printGrid(life);
    printGrid(life2);
    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;
        }
    }
    for (int row = 0; row < SIZE; row++){
        for (int col = 0; col < SIZE; col++){
            life2[row][col] = false;
        }
    }
}

void printGrid(bool life[][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;
    int neighbors2=0;
          if(life[row][col]== true && life[row][col-1]==true && col-1>=0)
            {
                neighbors++;
            }
          if(life[row][col]== true && life[row+1][col-1]==true && row+1<SIZE && col-1>=0)
            {
                neighbors++;
            }
          if(life[row][col]== true && life[row+1][col]==true & row+1<SIZE)
            {
                neighbors++;
            }
          if(life[row][col]== true && life[row][col+1]==true && col+1<SIZE)
            {
                neighbors++;
            }

         if(life[row][col]== true && life[row-1][col-1]==true && row-1>=0 && col-1>=0 )
            {
                neighbors++;
            }
          if(life[row][col]== true && life[row+1][col+1]==true && row+1<3 && col+1<SIZE)
            {
                neighbors++;
            }
          if(life[row][col]== true && life[row-1][col]==true && row-1>=0)
            {
                neighbors++;
            }
          if(life[row][col]== true && life[row-1][col+1]==true && row-1>=0 && col+1<SIZE)
            {
                neighbors++;
            }


          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<SIZE && col-1>=0)
            {
                neighbors2++;
            }
          if(life[row][col]== false && life[row+1][col]==true & row+1<SIZE)
            {
                neighbors2++;
            }
          if(life[row][col]== false && life[row][col+1]==true && col+1<SIZE)
            {
                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<SIZE)
            {
                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<SIZE)
            {
                neighbors2++;
            }
   return neighbors2;
   return neighbors;
}
/*int deadcellNeighbors (bool life [SIZE][SIZE],int row,int col)
{
       int neighbors2=0;

}*/
void determineNextGen(bool life[][SIZE],bool life2 [][SIZE])
{
    int neighbors, neighbors2;
    for (int row=0;row<SIZE;row++)
    {
        for (int col=0;col<SIZE;col++)
        {
            neighbors=livecellNeighbors(life,row,col);
            neighbors2=livecellNeighbors(life,row,col);
            if (neighbors==0 || neighbors==1)
                life2[row][col]=false;
            if (neighbors>=4)
                life2[row][col]=false;
            if (neighbors==2 || neighbors==3)
                life2[row][col]=true;
            if (neighbors2==3)
                life2[row][col]=true;
            if (neighbors2!=3)
                life2[row][col]=false;
        }
    }

}



this is my file I am starting out with



0 0
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 17
17 5
17 6
18 6
18 16
18 18
19 0
19 3
19 4
19 7


edit: fixed one issue in my code
Last edited on
so it looks like its an issue when i live cell has 2 neighbors but i still dont know why
I am a little closer but still having some issues

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
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

const int SIZE = 20;


void initGrid(bool life[][SIZE],bool life2[][SIZE]);
void readGrid(bool life[][SIZE], bool life2[][SIZE]);
void printGrid(bool life[][SIZE]);
int livecellNeighbors (bool life[][SIZE],int,int);
int deadcellNeighbors (bool life [][SIZE],int,int);
void determineNextGen(bool life[][SIZE], bool life2 [][SIZE]);


int main()
{
    bool life[SIZE][SIZE];
    bool life2[SIZE][SIZE];

    readGrid(life,life2);
    int neighbors;
    int neighbors2;
    for (int count = 0; count < 1; count++)
        {
            determineNextGen(life, life2);

        }

    printGrid(life);
    printGrid(life2);
    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;
        }
    }
    for (int row = 0; row < SIZE; row++){
        for (int col = 0; col < SIZE; col++){
            life2[row][col] = false;
        }
    }
}

void printGrid(bool life[][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<SIZE && col-1>=0)//left bottom
            {
                neighbors++;
            }
          if(life[row][col]== true && life[row+1][col]==true & row+1<SIZE)//bottom
            {
                neighbors++;
            }
          if(life[row][col]== true && life[row][col+1]==true && col+1<SIZE)//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<SIZE)//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<SIZE)//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<SIZE && col-1>=0)
            {
                neighbors2++;
            }
          if(life[row][col]== false && life[row+1][col]==true & row+1<SIZE)
            {
                neighbors2++;
            }
          if(life[row][col]== false && life[row][col+1]==true && col+1<SIZE)
            {
                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<SIZE)
            {
                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<SIZE)
            {
                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];
    }

}

Just an observation which may not help with your problem, but may make your code look better.

You have functions that do adjacency checks, but you use a whole lot if if statements to do them with. It is easy to write a for loop that starts at [row-1][col-1] and checks the 3 by 3 sub array by simple addition of 0, 1, or 2 to the subscripts, with a continue statement on the condition of [1][1] (the current cell). You do have make sure that you don't overstep the main array by limiting processing to start at [1][1] and finish at [MAXROW-1][MAXCOL-1].

If you find yourself writing lots of repetitive code - there is probably a better way - and finding it might mean that your existing problems could go away.

Generally, if you have runtime problems, using the debugger is the most efficient way of finding them.

Hope all goes well 8+)
Your talking about in my 2 neighbor functions?
Yes.

Can you figure how to apply what I said, to them?
I dont understand the 3 by 3 part. there are 8 sides to check

edit never mind i get that part still trying to figure out the for loop though
Last edited on
I have having trouble getting a for loop to work with it. I am still pretty new at programing so things to just pop out at me yet
So you already understand how to do a 3 by 3 array with nested for loops, so do that over the top of your existing array starting at [row-1][col-1], skip the existing cell by using an if statement and a continue.
okay that last post i just deleted was really bad here is where i am at but now the neighbors dont seem to be counting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int livecellNeighbors (bool life[SIZE][SIZE],int row,int col)
{
    int neighbors=0;
         for (int i=-1; row+i<=row+1; i++)
         {
             for (int c=-1;col+c<=col+1;c++)
             {
                 if (i==0 && c==0)

                 if (life[row+i][col+c]==true)
                    neighbors++;
                 }
             }


   return neighbors;
}
okay the neighbors are now counting but how do I check the ones on the edge?


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
int livecellNeighbors (bool life[SIZE][SIZE],int row,int col)
{
    int neighbors=0;

        if (life[row][col]==true)
        {


         for (int i=-1; row+i<=row+1; i++)
         {
             for (int c=-1;col+c<=col+1;c++)
             {
                 if (i==0 && c==0)
                 {

                 }

                 else if (life[row+i][col+c]==true)
                    neighbors++;
                 }
             }
        }


   return neighbors;
}
Edit I didn't see your last 2 posts, but this still applies any way I think.

Try this as a big hint - you need to add to it your self:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const int SubRowMax = 3;
const int SubColMax = 3;

int SubRowStart = row -1;  // improve by testing  that row is not zero to be sure
int SubColStart = col -1; // improve by testing that col is not zero to be sure

for (SubRow = 0;SubRow < SubRowMax; ++SubRow) {
    for(SubCol = 0;SubCol < SubColMax ;++SubCol) {
          if (SubRow == 1 && SubCol ==1 ) { // the current cell - skip it
                continue; // continues current for loop with next value of SubCol
          }
          // your code using this:
           if (life[SubRowStart + SubRow][SubColStart + SubCol] == true) {
                // put the test code here
          }
           
    }
}


Realise that this code has to go inside the for loops that iterate over the whole array

Notice that in your function livecellNeighbors live[row][col] is always true, and in deadcellNeighbors live[row][col] is always false, and for both of them the neighbour is always true, so that tells me that you could combine these 2 functions into 1 function by putting a test into the if statement I have shown.

These bits:

&& row+1<SIZE && col-1>=0

And the like are for ensuring that you you don't overstep the boundaries of your array, and instead should be accounted for by limiting the for loops in the determineNextGen function as I mentioned above:

1
2
    for (int row=1;row<SIZE-1;row++) { // limited to allow for adjacency tests
        for (int col=1;col<SIZE-1;col++) {  // limited to allow for adjacency tests 


Hope all goes well.

Last edited on
that you so much that you have been very helpful I think i get the boundaries part and combining the functions
okay which part of this is checking the boundaries? My last 2 post take care of everything in the middle just not row0 and 19 and col 0 and 19.
Edit - We were thinking the same thing at the same time !!

Some more thoughts :

My idea is OK as long as you don't have to test the cells around the border - for example do you have to apply the neighbour test to [0][0], or any of [*][0], [0][*], or [SIZE] [SIZE] etc? If so, you might have to think up an elegant way of doing this - maybe an IsInArray function returning a bool.

Some other things:

Lines 175 to 182 - can you think of a way to write all those as one short if else statement?

Now that you have the live & dead cells being worked in one function, that logic could go into the nextGeneration function, because then you don't have to worry about alternative ways returning 2 values from the function. Could you rename Neighbours & Neighbours2 to LiveNeighbours & DeadNeighbours?

With lines 169 to 195, you no longer need to process the array twice.

Lines 196 to 202 copy the array - It should be it's own function.

Btw it's a good idea to always use braces even when there is only 1 statement (like on line 199) - it will save you one day when you add more code.

Let us know how you get on - cheers :)
Last edited on
edit: that doesnt work either i was thinking and coding on the fly in the forum with out testing it sorry.

so yes i have to check the neighbors for the borders as well and I will go back and fix all the other things you mentioned but what about something like this for checking boarders and inner all at once. this is with starting the for loop in getNextGeneration back at 0


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int livecellNeighbors (bool life[SIZE][SIZE],int row,int col)
{
    int neighbors=0;

        if (life[row][col]==true)
        {


         for (int i=-1; row+i<=row+1; i++)
         {
             for (int c=-1;col+c<=col+1;c++)
             {
                 if (i==0 && c==0 || row+i<0 || row+i<SIZE || col+c<0 || col+c>SIZE)
                 {

                 }

                 else if (life[row+i][col+c]==true)
                    neighbors++;
                 }
             }
        }
Last edited on
I have to go out for dinner right now - won't be back for 2 hours - try the IsInArray function Idea.

okay thank you very much I will post the final project.
Topic archived. No new replies allowed.