# Thread: Problem with Game of Life program

1. ## Problem with Game of Life program

Code:
```#include <iostream>
#include <cstdlib>
#include <Windows.h>

char grid[25][25];

void turnOn(int x, int y);
void turnOff(int x, int y);
bool lhmt3(int x, int y);
bool lh2o3(int x, int y);
bool lhlt2(int x, int y);
bool dhe3(int x, int y);
int gridCheck(int x, int y);
void printGrid();
void initGrid();
void Game();

int main(){
initGrid();
turnOn(10,15);
turnOn(10,16);
turnOn(9,15);
turnOn(11,15);
turnOn(10,14);
printGrid();
Game();
}
// Activate cell
void turnOn(int x, int y){
grid[x][y] = '0';
}
// Kill cell
void turnOff(int x, int y){
grid[x][y] = '-';
}
// Check whether living cell has more than three neighbours
bool lhmt3(int x, int y){
if(gridCheck(x, y) > 3){
return true;
} else {
return false;
}
}
// Check whether living cell has two or three neighbours
bool lh2o3(int x, int y){
if(gridCheck(x, y) == 2 or gridCheck(x, y) == 3){
return true;
} else {
return false;
}
}
// Check whether living cell has less than two neighbours
bool lhlt2(int x, int y){
if(gridCheck(x, y) < 2){
return true;
} else {
return false;
}
}
// Check whether dead cell has exactly three neighbours
bool dhe3(int x, int y){
if(gridCheck(x, y) == 3){
return true;
} else {
return false;
}
}
// Scan adjacent cells for life
int gridCheck(int x, int y){
int count = 0;
if(grid[x-1][y]=='0') ++count;
if(grid[x-1][y-1]=='0') ++count;
if(grid[x][y-1]=='0') ++count;
if(grid[x+1][y-1]=='0') ++count;
if(grid[x+1][y]=='0') ++count;
if(grid[x+1][y+1]=='0') ++count;
if(grid[x][y+1]=='0') ++count;
if(grid[x-1][y+1]=='0') ++count;
return count;
}

void printGrid(){
for(int x=0;x<25;++x){
for(int y=0;y<25;++y){
std::cout << grid[x][y] << " ";
}
std::cout << std::endl;
}
}

void initGrid(){
for(int x=0;x<25;++x){
for(int y=0;y<25;++y){
grid[x][y] = '-';
}
}
}

void Game(){
while (true){
for(int x=0;x<25;++x){
for(int y=0;y<25;++y){
if((grid[x][y] == '0') and (lhmt3(x, y) == true)){
std::cout << lhmt3(x,y);
turnOff(x, y);
}
if((grid[x][y] == '0') and (lh2o3(x, y) == true)){
}
if((grid[x][y] == '0') and (lhlt2(x, y) == true)){
turnOff(x, y);
}
if((grid[x][y] == '-') and (dhe3(x, y) == true)){
std::cout << "i am dead";
turnOn(x, y);
}
}
}
system("PAUSE");
system("CLS");
printGrid();
}
}```
This doesn't do what it's supposed to. In a functional Life program what should happen is the middle cell dies and the corner cells are activated. Perhaps there's something wrong with my conditionals but they look pretty good to me and I can't figure out what's wrong. If someone could read through it I'd appreciate it.

P.S. The system("PAUSE") and cout statements in Game() are there only for debugging reasons.

EDIT: Some sample output:

Code:
```- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - 0 - - - - - - - - -
- - - - - - - - - - - - - - 0 0 0 - - - - - - - -
- - - - - - - - - - - - - - - 0 - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
i am dead11Press any key to continue . . .```
The 1s are the result of the lhmt3() function in Game(), and the "i am dead" is the result of the dhe3() function. Obviously these numbers are incorrect. There should only be one "true" and it should output "i am dead" four times.

Code:
```- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - 0 - - - - - - - - - -
- - - - - - - - - - - - - - 0 - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
Press any key to continue . . .```
And it doesn't work.

2. I do not what game of life is.And i am sorry that i can not understand what you mean the problem is.I mean i can not see what you want to achieve,so you can explain me a little bit(if you wish and if you see that you get no answers,because other members may understand)

3. Sorry. The Game of Life is a non-interactive "game" that is "played" on a grid with any number of cells (in my program it's 25x25). Each cell can either be "dead" or "alive" and the game has four rules to determine what cells live and die. I'm just going to copy paste from Wikipedia because it explains it very well:

1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
2. Any live cell with two or three live neighbours lives on to the next generation.
3. Any live cell with more than three live neighbours dies, as if by overcrowding.
4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

So I have specific functions to test these conditions and then I either activate or deactivate the cells depending on the result of the conditionals. Check my comments, they should tell you what I'm trying to do with the functions. My program doesn't work however because I am not getting to expected result, which is a square in the 2nd cycle.

4. You need to use another grid (2 dimensional array) to calculate the next generation of cells. With only one grid, the next generation is calculated from a mixture of the current generation and the next generation.

5. I think that the problem is not in your code that in something you got wrong by the rules of the game or by examining the output.

Mind that the cell with coordinates 9,14 is going to regenerate(because it has 3 neighbours ).So i would say that the output is correct.The cells that alive after the first round are the 9,14 and the 10,14.That is correct i would say,isn't it?

6. Originally Posted by christop
You need to use another grid (2 dimensional array) to calculate the next generation of cells. With only one grid, the next generation is calculated from a mixture of the current generation and the next generation.
The answer i gave ex-Mortis considers that you were aware of what christop said and calculates the output with the mixture he said

7. > if(grid[x-1][y]=='0') ++count;
Beware of array overruns (and underruns).
You start with x and y at 0.

8. Originally Posted by std10093
I think that the problem is not in your code that in something you got wrong by the rules of the game or by examining the output.

Mind that the cell with coordinates 9,14 is going to regenerate(because it has 3 neighbours ).So i would say that the output is correct.The cells that alive after the first round are the 9,14 and the 10,14.That is correct i would say,isn't it?
Nope. See for yourself.

Originally Posted by christop
You need to use another grid (2 dimensional array) to calculate the next generation of cells. With only one grid, the next generation is calculated from a mixture of the current generation and the next generation.
Can you elaborate? I don't really understand.

Originally Posted by Salem
> if(grid[x-1][y]=='0') ++count;
Beware of array overruns (and underruns).
You start with x and y at 0.
Hadn't considered it. At the moment I'm only testing the middle of the board so it isn't a problem, but I'll fix it.

9. What I mean is that as you generate the next generation in each cycle, you're partially overwriting the current generation, which affects the results of the next generation.

For example, if a cell dies, it is no longer counted as a living neighbor for several other cells surrounding it when it should still be counted, and if a new cell is born it is then counted as a living neighbor when it shouldn't be.

By using two arrays, you read cells from the "current" generation array and write cells to the "next" generation array.

10. Originally Posted by ex-mortis
Can you elaborate? I don't really understand.
If you make the changes in the same grid then the changed positions will be used in some of the decisions.
Instead, leave the original grid alone and use another grid to create the new state.
Then either copy it back to the original grid or use a buffer-switching technique.

11. Originally Posted by oogabooga
If you make the changes in the same grid then the changed positions will be used in some of the decisions.
Instead, leave the original grid alone and use another grid to create the new state.
Then either copy it back to the original grid or use a buffer-switching technique.
Originally Posted by christop
What I mean is that as you generate the next generation in each cycle, you're partially overwriting the current generation, which affects the results of the next generation.

For example, if a cell dies, it is no longer counted as a living neighbor for several other cells surrounding it when it should still be counted, and if a new cell is born it is then counted as a living neighbor when it shouldn't be.

By using two arrays, you read cells from the "current" generation array and write cells to the "next" generation array.
Makes sense now that I think about it. Thanks for the tips, I'll get to work.

12. Quote Originally Posted by Salem View Post
> if(grid[x-1][y]=='0') ++count;
> Beware of array overruns (and underruns).
> You start with x and y at 0.
> Hadn't considered it. At the moment I'm only testing the middle of the board so it isn't a problem, but I'll fix it.

> for(int x=0;x<25;++x)
> for(int y=0;y<25;++y)
You might only have something interesting in the middle of the board, but you are still checking ALL of it.

Your program is screwed on the very first iteration of your loop.

Oh, and people who ignore buffer overruns "until later" make me

13. Originally Posted by Salem
Quote Originally Posted by Salem View Post
> if(grid[x-1][y]=='0') ++count;
> Beware of array overruns (and underruns).
> You start with x and y at 0.
> Hadn't considered it. At the moment I'm only testing the middle of the board so it isn't a problem, but I'll fix it.

> for(int x=0;x<25;++x)
> for(int y=0;y<25;++y)
You might only have something interesting in the middle of the board, but you are still checking ALL of it.

Your program is screwed on the very first iteration of your loop.

Oh, and people who ignore buffer overruns "until later" make me
Sorry, that's not what I was trying to say. I simply commented erroneously that it wasn't a problem but that I was going to fix it. Is this adequate enough?

Code:
```// Scan adjacent cells for life
int gridCheck(int x, int y){
int count = 0;

//To avoid array underrun
if(x>=1){
if(grid[x-1][y]=='0') ++count;
}
if (x>=1 and y<24)
if(grid[x-1][y+1]=='0') ++count;
}
if (y>=1){
if(grid[x][y-1]=='0') ++count;
}
if (x<24 and y>=1){
if(grid[x+1][y-1]=='0') ++count;
}
if (x>=1 and y>=1){
if(grid[x-1][y-1]=='0') ++count;
}
if (x<24){
if(grid[x+1][y]=='0') ++count;
}
if (x<24 and y<24){
if(grid[x+1][y+1]=='0') ++count;
}
if (y<24){
if(grid[x][y+1]=='0') ++count;
}

return count;
}```
Here's my updated source code:

Code:
```#include <iostream>
#include <cstdlib>
#include <Windows.h>

char grid[25][25];
char nextGrid[25][25];

void turnOn(int x, int y);
void turnOff(int x, int y);
bool lhmt3(int x, int y);
bool lh2o3(int x, int y);
bool lhlt2(int x, int y);
bool dhe3(int x, int y);
int gridCheck(int x, int y);
void printGrid();
void initGrid();
void initNextGrid();
void arrayCopy();
void Game();

int main(){
initGrid();
initNextGrid();
turnOn(10,15);
turnOn(10,16);
turnOn(9,15);
turnOn(11,15);
turnOn(10,14);
Game();
}
// Activate cell
void turnOn(int x, int y){
grid[x][y] = '0';
}
// Activate next gen cell
void turnOnNext(int x, int y){
nextGrid[x][y] = '0';
}
// Kill cell
void turnOff(int x, int y){
grid[x][y] = '-';
}
// Kill next gen cell
void turnOffNext(int x, int y){
nextGrid[x][y] = '-';
}
// Check whether living cell has more than three neighbours
bool lhmt3(int x, int y){
if(gridCheck(x, y) > 3){
return true;
} else {
return false;
}
}
// Check whether living cell has two or three neighbours
bool lh2o3(int x, int y){
if(gridCheck(x, y) == 2 or gridCheck(x, y) == 3){
return true;
} else {
return false;
}
}
// Check whether living cell has less than two neighbours
bool lhlt2(int x, int y){
if(gridCheck(x, y) < 2){
return true;
} else {
return false;
}
}
// Check whether dead cell has exactly three neighbours
bool dhe3(int x, int y){
if(gridCheck(x, y) == 3){
return true;
} else {
return false;
}
}
// Scan adjacent cells for life
int gridCheck(int x, int y){
int count = 0;

//To avoid array underrun
if(x>=1){
if(grid[x-1][y]=='0') ++count;
if(grid[x-1][y+1]=='0') ++count;
}
if (y>=1){
if(grid[x][y-1]=='0') ++count;
if(grid[x+1][y-1]=='0') ++count;
}
if (x>=1 and y>=1){
if(grid[x-1][y-1]=='0') ++count;
}
if(grid[x+1][y]=='0') ++count;
if(grid[x+1][y+1]=='0') ++count;
if(grid[x][y+1]=='0') ++count;

return count;
}

void printGrid(){
for(int x=0;x<25;++x){
for(int y=0;y<25;++y){
std::cout << grid[x][y] << " ";
}
std::cout << std::endl;
}
}

void initGrid(){
for(int x=0;x<25;++x){
for(int y=0;y<25;++y){
grid[x][y] = '-';
}
}
}
void initNextGrid(){
for(int x=0;x<25;++x){
for(int y=0;y<25;++y){
nextGrid[x][y] = '-';
}
}
}

void arrayCopy(){
for(int x=0;x<25;++x){
for(int y=0;y<25;++y){
grid[x][y] = nextGrid[x][y];
}
}
}

void Game(){
printGrid();
while (true){
for(int x=0;x<25;++x){
for(int y=0;y<25;++y){
if((grid[x][y] == '0') and (lhmt3(x, y) == true)){
std::cout << lhmt3(x,y);
turnOffNext(x, y);
}
if((grid[x][y] == '0') and (lh2o3(x, y) == true)){
}
if((grid[x][y] == '0') and (lhlt2(x, y) == true)){
turnOffNext(x, y);
}
if((grid[x][y] == '-') and (dhe3(x, y) == true)){
std::cout << "i am dead";
turnOnNext(x, y);
}
}
}
arrayCopy();
system("PAUSE");
system("CLS");
printGrid();
}
}```
Right now it "works" in the sense that in the first generation all of the conditionals return the correct values and the 2nd generation of cells is printed correctly. But for some reason the if statements do not run at all (or all return false) and there is no 3rd generation. From what I can tell it should copy the 2nd generation values to the first generation and run another check on all of the cells. I think maybe the sequence is somehow screwed up but I cannot spot the error.

14. You're still not checking for array overrun.
You should call initNextGrid() after arrayCopy().
Kurt

15. Originally Posted by ZuK
You're still not checking for array overrun.
You should call initNextGrid() after arrayCopy().
Kurt
1. I'm not? What is the proper way to check for an overrun then?

2. I already tried it, it doesn't work. The error is definitely in the conditionals because they return false or don't run at all instead of returning true like they should.

Popular pages Recent additions