Translate as much of the game of life algorithm to C++ as you can.
Question
Translate as much of the game of life algorithm to C++ as you can. Write an interactive seed creation function and seed creation function that reads the seed definition from a file.
The Game of Life The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square cells, each of which is in one of two possible states, alive or dead. Every cell interacts with its eight neighbours, which are the cells that are horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur:
-
- Any live cell with less than two live neighbours dies as if caused by under-population.
- Any live cell with two or three live neighbours lives on to the next generation.
- Any live cell with more than three live neighbours dies, as if by overcrowding.
- Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
The initial pattern constitutes the seed of the system. The first generation is created by applying the above rules simultaneously to every cell in the seed—births and deaths occur simultaneously, and the discrete moment at which this happens is sometimes called a tick (in other words, each generation is a pure function of the preceding one). The rules continue to be applied repeatedly to create further generations. “applying the above rules simultaneously” is easy. First, assign the cells of the original 2D array to a new 2D array. Second, look at the original array and follow the rules but apply any changes to the new array. Third, after looking at all the cells in the original array, assign the cells of the new array to the original array. Fourth, and last, discard the new array.
Write a function that counts a cell’s neighbours. The function has 2 parameters – the target cell’s row and column. The function returns an integer. Write a function that determines a cell’s fate – does the cell die, does the cell live to the next generation, does the cell die as if by overcrowding, does the cell, necessarily a dead cell, become a life cell. The function has 2 parameters – the target cell’s row and column. The function returns true if the cell lives and false if it dies.
game of life.cpp
#include <iostream> #include <string> using namespace std; const int gridsize = 256; void copygrid(bool srce[][gridsize], bool dest[][gridsize]); void initgrid(bool srce[][gridsize]); int countNeighbors(bool gen[][gridsize], int row, int col); void computenextgen(bool nowgen[][gridsize], bool nextgen[][gridsize]); int main() { bool nowgen[gridsize][gridsize]; bool nxtgen[gridsize][gridsize]; system("pause"); return 0; } void copygrid(bool srce[][gridsize], bool dest[][gridsize]) { for (int i = 0; i < gridsize; ++i) for (int j = 0; j < gridsize; ++j) dest[i][j] = srce[i][j]; } void initgrid(bool grid[][gridsize]) { for (int i = 0; i < gridsize; ++i) for (int j = 0; j < gridsize; ++j) grid[i][j] = false; } int countNeighbors(bool gen[][gridsize], int row, int col) { int neighborcount = 0; for (int rowoffset = -1; rowoffset <= 1; ++rowoffset) for (int coloffset = -1; coloffset <= 1; ++coloffset) if (0 <= row + rowoffset && row + rowoffset < gridsize && 0 <= col + coloffset && row + coloffset < gridsize && (rowoffset != 0 || coloffset != 0) && gen[row + rowoffset][col + coloffset]) neighborcount++; return neighborcount; } void computenextgen(bool nowgen[][gridsize], bool nextgen[][gridsize]) { for (int i = 0; i < gridsize; ++i) for (int j = 0; j < gridsize; ++j) { int neighborcount = countNeighbors(nowgen, i, j); switch (neighborcount) { case 0: case 1: nextgen[i][j] = false; break; } } }
Summary
The functions that had already been defined functioned perfectly. In the function count Neighbours, only a little change is made. There was a little logical error that was rectified within the if loop. The main method then calls all of the defined functions to acquire the required result.
Explanation
To check the output, the grid size is first stated, which is set to 3. The grid sizes for the two grids, nowgen and nxtgen, are then specified. After that, the user enters the nowgen grid’s input. And the nxtgen parameter is supplied to the initgen() function, which initialises the grid with all false values. The copy grid function is then invoked, with the nowgen grid as the source, and it is copied to the nxtgen grid as the destination. The nowgen and nxtgen parameters are then provided to the computenextgen function. The grid values in the nxtgen are modified in this technique based on the scenario conditions. The copy grid is then called once more to copy nxtgen to nowgen.
Finally, the output is stored in nowgen and it is printed to console as output.
Code
#include <iostream> #include <string> using namespace std; const int gridsize=3; void copygrid(bool srce[][gridsize], bool dest[][gridsize]); void initgrid(bool srce[][gridsize]); int countNeighbors(bool gen[][gridsize], int row, int col); void computenextgen(bool nowgen[][gridsize], bool nextgen[][gridsize]); int main() { bool nowgen[gridsize][gridsize]; cout<<"Enter the nowgen: "<<endl; for(int i=0;i<gridsize;i++) for(int j=0;j<gridsize;j++) cin>>nowgen[i][j]; bool nxtgen[gridsize][gridsize]; initgrid(nxtgen); copygrid(nowgen,nxtgen); cout<<endl; computenextgen(nowgen, nxtgen); copygrid(nxtgen,nowgen); cout<<"\nOutput:\n"; for(int i=0;i<gridsize;i++){ for(int j=0;j<gridsize;j++){ cout<<nowgen[i][j]<<" "; } cout<<endl; } system("pause"); return 0; } void copygrid(bool srce[][gridsize], bool dest[][gridsize]) { for (int i = 0; i < gridsize; ++i) for (int j = 0; j < gridsize; ++j) dest[i][j] = srce[i][j]; } void initgrid(bool grid[][gridsize]) { for (int i = 0; i < gridsize; ++i) for (int j = 0; j < gridsize; ++j) grid[i][j] = false; } int countNeighbors(bool gen[][gridsize], int row, int col) { int neighborcount = 0; for (int rowoffset = -1; rowoffset <= 1; ++rowoffset) for (int coloffset = -1; coloffset <= 1; ++coloffset) if (0 <= row + rowoffset && row + rowoffset < gridsize && 0 <= col + coloffset && col + coloffset < gridsize && (rowoffset != 0 || coloffset != 0) && gen[row + rowoffset][col + coloffset]) neighborcount++; return neighborcount; } void computenextgen(bool nowgen[][gridsize], bool nextgen[][gridsize]) { for (int i = 0; i < gridsize; ++i) for (int j = 0; j < gridsize; ++j) { int neighborcount = countNeighbors(nowgen, i, j); cout<<"Neighbour count for index ("<<i<<", "<<j<<") = "<<neighborcount<<endl; switch (neighborcount) { case 0: nextgen[i][j]=false; break; case 1: nextgen[i][j] = false; break; case 2: nextgen[i][j]=true; break; case 3: nextgen[i][j]=true; break; default: nextgen[i][j]=false; break; } } }
Output
Also, read the Given below-defined UML class diagram.