# Problem with Game of Life program

Printable View

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 08-11-2012
ex-mortis
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.
• 08-11-2012
std10093
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) :)
• 08-11-2012
ex-mortis
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.
• 08-11-2012
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.
• 08-11-2012
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? :)
• 08-11-2012
std10093
Quote:

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 :)
• 08-11-2012
Salem
> if(grid[x-1][y]=='0') ++count;
Beware of array overruns (and underruns).
You start with x and y at 0.
• 08-11-2012
ex-mortis
Quote:

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.

Quote:

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.

Quote:

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.
• 08-11-2012
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.
• 08-11-2012
oogabooga
Quote:

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.
• 08-11-2012
ex-mortis
Quote:

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.

Quote:

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.
• 08-12-2012
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 :mad:
• 08-12-2012
ex-mortis
Quote:

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 :mad:

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.
• 08-12-2012
ZuK
You're still not checking for array overrun.
You should call initNextGrid() after arrayCopy().
Kurt
• 08-12-2012
ex-mortis
Quote:

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.
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last