Game of Life

I am trying to make a game of life. The rules do not appear to be functioning properly. I have concluded that their is something wrong with my counting method, but I can not figure it out. Any help is appreciated. Here is my current code.

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
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#define h 30
#define w 30

using namespace std;

char grid[h][w];
int a=0,b=0;
int f,s;

void blank()//creates a blank grid.
{
    for(a=0;a<30;a++)
    {
        for(b=0;b<30;b++)
        {
            grid[a][b]='-';
        }
    }
}

void print()
{
   for (a=0;a<30;a++)
   {
       for(b=0;b<30;b++)
       {
           cout<<grid[a][b];
       }
       cout<<endl;
   }
}

void split(string a)
{
    string first, second;
    istringstream liness( a );//seperating two numbers
    getline( liness, first, ',' );
    getline( liness, second,  ',' );
    istringstream buffer(first);
    buffer >> f;
    istringstream buff(second);
    buff >> s;
}

void replace()
{
    grid[f][s]='\xDB';
}

void count ()
{
    int neighbors;
    for (a=0;a<30;a++)
    {
        for (b=0;b<30;b++)
        {
            if (grid[a-1][b-1] == '\xDB') neighbors++;
            if (grid[a-1][b] == '\xDB') neighbors++;
            if (grid[a-1][b+1] == '\xDB') neighbors++;
            if (grid[a][b-1] == '\xDB') neighbors++;
            if (grid[a][b+1] == '\xDB') neighbors++;
            if (grid[a+1][b-1] == '\xDB') neighbors++;
            if (grid[a+1][b] == '\xDB') neighbors++;
            if (grid[a+1][b+1] == '\xDB') neighbors++;

            if (grid[a][b] == '\xDB' && neighbors < 2)
             {
                 grid[a][b] = '-';
             }
            else if (grid[a][b] == '\xDB' && neighbors > 3)
             {
                 grid[a][b] = '-';
             }
            else if (grid[a][b] == '\xDB' && neighbors == 2)
            {
                grid[a][b] = '\xDB';
            }
            else if (grid[a][b] == '\xDB' && neighbors == 3)
            {
                grid[a][b] = '\xDB';
            }
             else if (grid[a][b] == '-' && neighbors == 3)
            {
                grid[a][b] = '\xDB';
            }
        }
    }
}

int main()
{
    string number;
    string ready="-1";
    string cnt;
    cout << "Welcome to Conway's Game of Life." << endl << endl;
    cout << "The Rules of Life:" << endl;
    cout << "1. Any live cell with fewer than two live neighbors dies, as if by loneliness." << endl;
    cout << "2. Any live cell with more than three live neighbors dies, as if by \novercrowding." << endl;
    cout << "3. Any live cell with two or three live neighbors lives, unchanged." << endl;
    cout << "4. Any dead cell with exactly three live neighbors comes to life." << endl << endl;
    cout << "To play: Press any key to begin. Enter the column and row of a cell to make \nalive, separated by a comma. ";
    cout << "When you are ready, enter \"-1\" to begin the \nsimulation. Then enter any number to continue or \"-1\" to quit." << endl;
    cout << "Include zeroes when entering grid numbers."<<endl;
    cin.get();
    blank();//creates a blank grid
    print();//prints out current grid
    cin >> number;
    do
    {
        split(number);//numbers are split into two variables f and s
        replace();//replaces specified number with a box
        print();
        cin >> number;
    }while(number!=ready);
    do
    {
        count();//count neighbors and apply rules
        print();
        cin >> cnt;
    }while(cnt!=ready);
    return 0;

}
The problem is you are modifying the grid as you check each cell. The grid you look at to determine the state of the cells in the next cycle should remain the same. You'd then use a copy of the grid which you update with new cell states as you go along checking each cell.

I hope that makes sense because I know exactly what the problem is but I'm having a lot of trouble putting it into words for some reason. Basically, if you just modify the original grid as you loop through the cells, it's going to cause problems. Have a copy of the grid that you use to update, and use the original grid to check cell states. Then at the end of the cycle set the original grid to the copy and repeat.
this is my new code, but I'm still having issues.
for instance, when I use a single block as a test it fills up two lines next to eachother with a spot in the middle where the block was.
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
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#define h 30
#define w 30

using namespace std;

char grid[h][w];
char grid2[h][w];
int a=0,b=0;
int f,s;

void blank(char mat[][w])//creates a blank grid.
{
    for(a=0;a<30;a++)
    {
        for(b=0;b<30;b++)
        {
            mat[a][b]='-';
        }
    }
}

void change()
{
    for (a=0;a<30;a++)
   {
       for(b=0;b<30;b++)
       {
           grid[a][b]=grid2[a][b];
       }
   }
}

void print()
{
   for (a=0;a<30;a++)
   {
       for(b=0;b<30;b++)
       {
           cout<<grid[a][b];
       }
       cout<<endl;
   }
}

void split(string a)
{
    string first, second;
    istringstream liness( a );//seperating two numbers
    getline( liness, first, ',' );
    getline( liness, second,  ',' );
    istringstream buffer(first);
    buffer >> f;
    istringstream buff(second);
    buff >> s;
}

void replace()
{
    grid[f][s]='\xDB';
}

void count ()
{
    int neighbors;
    for (a=0;a<30;a++)
    {
        for (b=0;b<30;b++)
        {
            if (grid[a-1][b-1] == '\xDB') neighbors++;
            if (grid[a-1][b] == '\xDB') neighbors++;
            if (grid[a-1][b+1] == '\xDB') neighbors++;
            if (grid[a][b-1] == '\xDB') neighbors++;
            if (grid[a][b+1] == '\xDB') neighbors++;
            if (grid[a+1][b-1] == '\xDB') neighbors++;
            if (grid[a+1][b] == '\xDB') neighbors++;
            if (grid[a+1][b+1] == '\xDB') neighbors++;

            if (grid[a][b] == '\xDB' && neighbors < 2)
             {
                 grid2[a][b] = '-';
             }
            else if (grid[a][b] == '\xDB' && neighbors > 3)
             {
                 grid2[a][b] = '-';
             }
            else if (grid[a][b] == '\xDB' && neighbors == 2)
            {
                grid2[a][b] = '\xDB';
            }
            else if (grid[a][b] == '\xDB' && neighbors == 3)
            {
                grid2[a][b] = '\xDB';
            }
             else if (grid[a][b] == '-' && neighbors == 3)
            {
                grid2[a][b] = '\xDB';
            }
        }
    }
}

int main()
{
    string number;
    string ready="-1";
    string cnt;
    cout << "Welcome to Conway's Game of Life." << endl << endl;
    cout << "The Rules of Life:" << endl;
    cout << "1. Any live cell with fewer than two live neighbors dies, as if by loneliness." << endl;
    cout << "2. Any live cell with more than three live neighbors dies, as if by \novercrowding." << endl;
    cout << "3. Any live cell with two or three live neighbors lives, unchanged." << endl;
    cout << "4. Any dead cell with exactly three live neighbors comes to life." << endl << endl;
    cout << "To play: Press any key to begin. Enter the column and row of a cell to make \nalive, separated by a comma. ";
    cout << "When you are ready, enter \"-1\" to begin the \nsimulation. Then enter any number to continue or \"-1\" to quit." << endl;
    cout << "Include zeroes when entering grid numbers."<<endl;
    cin.get();
    blank(grid);//creates a blank grid
    print();//prints out current grid
    cin >> number;
    do
    {
        split(number);//numbers are split into two variables f and s
        replace();//replaces specified number with a box
        print();
        cin >> number;
    }while(number!=ready);
    do
    {
        blank(grid2);
        count();//count neighbors and apply rules
        change();
        print();
        cin >> cnt;
    }while(cnt!=ready);
    return 0;

}
In count you access grid[a+1][b+1] when both a and b are 29. 29 is the highest valid index you may use to access either dimension of grid. This results in undefined behavior.

Also in count, neighbors is not assigned an initial value so it could be anything, and it is not reset for each cell.
Last edited on
Topic archived. No new replies allowed.