Conway's Game of Life

I read about Conway's Game of Life, a cellular automaton, and decided programming a simple version of it.

I just want some feedback to see how it can be improved or if there is a better way of doing it. Let me know what you think.

Also, if knew how to program graphics (which I don't), would I be able to use the array to determine what to show or would I have to do something completely different?

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
#include <iostream>
#include <iomanip>
#define H 30 //Define height
#define W 30 //Define width
using namespace std;

void clear(bool mat[][W]) //Sets matrix to all dead
{
    for (int m = 0; m < H; m++)
    {
        for (int n = 0; n < W; n++)
            mat[m][n] = 0;
    }
}

void print(bool mat[][W]) //Prints matrix to screen
{
     cout << setw(3) << " ";
     for (int p = 0; 5*p < W; p++) cout << setw(5) << 5*p+1;
     cout << endl;
     for (int m = 0; m < H; m++)
     {
         cout << setw(3) << m+1;
         for (int n = 0; n < W; n++)
         {
             if (mat[m][n]) cout << "\xDB";
             else cout << /*"\xB1"*/"-";
         }
         cout << endl;
     }
}

void print2(unsigned int mat[][W]) //Prints matrix to screen
{
     for (int m = 0; m < H; m++)
     {
         for (int n = 0; n < W; n++)
             cout << mat[m][n] << " ";
         cout << endl;
     }
}

void calculate(bool mata[][W], bool matb[][W])
{
     unsigned int neighbors;
     for (int m = 0; m < H; m++)
     {
         for (int n = 0; n < W; n++)
         {
             neighbors = 0;
             //Begin counting number of neighbors:
             if (mata[m-1][n-1] == 1) neighbors += 1;
             if (mata[m-1][n] == 1) neighbors += 1;
             if (mata[m-1][n+1] == 1) neighbors += 1;
             if (mata[m][n-1] == 1) neighbors += 1;
             if (mata[m][n+1] == 1) neighbors += 1;
             if (mata[m+1][n-1] == 1) neighbors += 1;
             if (mata[m+1][n] == 1) neighbors += 1;
             if (mata[m+1][n+1] == 1) neighbors += 1;
             
             //Apply rules to the cell:
             if (mata[m][n] == 1 && neighbors < 2)
                matb[m][n] = 0;
             else if (mata[m][n] == 1 && neighbors > 3)
                matb[m][n] = 0;
             else if (mata[m][n] == 1 && (neighbors == 2 || neighbors == 3))
                matb[m][n] = 1;
             else if (mata[m][n] == 0 && neighbors == 3)
                matb[m][n] = 1;
         }
     }
}

void swap(bool mata[][W], bool matb[][W]) //Replaces first matrix with second
{
     for (int m = 0; m < H; m++)
     {
         for (int n = 0; n < W; n++)
             mata[m][n] = matb[m][n];
     }
}
     

int main()
{
    bool now[H][W], next[H][W]; //Creates now and then matrixes
    int x, y, cont; //Used for user input
    
    cout << left << "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 space. ";
    cout << "When you are ready, enter \"-1\" to begin the \nsimulation. Then enter any number to continue or \"-1\" to quit." << endl;
    cin.get();
    
    clear(now);
    print(now);
    
    do //Get initial state
    {
        cin >> x;
        if (x == -1) break; //User is done inputting
        cin >> y;
        now[y-1][x-1] = 1; //Sets cell to alive
        print(now); //Updates screen
    }while(x != -1);
    
    do //Keep updating new generations
    {
        clear(next);
        calculate(now, next);
        swap(now, next);
        print(now);
        cin>>cont;
    }while(cont != -1);
    
    return 0;
} 
By the way, I'm trying to make input easier by using the Enter key to progress to each new generation and also by using "Q" instead of "-1" to exit the program.

I keep trying different ways, like:
1
2
getline(cin, cont);
cin.ignore(numeric_limits<streamsize>::max(),'\n');


I keep changing stuff around, but I get weird errors such as when I type "-1" to finish inputing the initial state and start the simulation, it jumps two generations ahead. Also, I need to hit Enter twice to progress to the next generation.

Can somebody explain how input works, and what is going on here?
Last edited on
Conway's game of life is a fun project. It's quite entertaining to watch too :)

It looks like, in your function calculate(), your "for" loops go from 0 to H or W. The problem is, you then test the state of each cell just around mata[n][m]. that means when n or m is 0, you're testing mata[-1][m] and mata[n][-1], respectively. And when n or m is equal to (H or W) -1, you're testing mata[H][m], and mata[n][W]. In these four cases, you're testing outside the actual boundaries of your array, which can cause crashes. You just need to test a smaller area:
1
2
    for (int m = 1; m < H-1; m++){
         for (int n = 1; n < W-1; n++){

As a consequence of this, a buffer zone with a thickness of one cell will be permanently "dead" all around the edges of your game. However, you can just not display those cells, and the user will never know the difference.

As for graphics, my own method was to use win32. however, I don't think you want to open that whole can of worms until you're sure that everything works. But if you do eventually get to that point, to answer your question: it is entirely possible to know what to draw to the screen just using the array you've got.

Nice job so far, man.
Yes, I realized I had a problem near the edges of my matrix array, but I wasn't sure how to fix this.

Thanks for the advice.
Topic archived. No new replies allowed.