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?
#include <iostream>
#include <iomanip>
#define H 30 //Define height
#define W 30 //Define width
usingnamespace 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(unsignedint 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])
{
unsignedint 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;
elseif (mata[m][n] == 1 && neighbors > 3)
matb[m][n] = 0;
elseif (mata[m][n] == 1 && (neighbors == 2 || neighbors == 3))
matb[m][n] = 1;
elseif (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 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?
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.