Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

implemement the game.cpp by the header file given. And create main.cpp to make t

ID: 3786562 • Letter: I

Question

implemement the game.cpp by the header file given. And create main.cpp to make the program work.

The game is called the game of life, https://en.wikipedia.org/wiki/Conway's_Game_of_Life

game.h:

#include <iostream> // Provides ostream

#include <string> // String operations

#include <cstdlib> // Randomizer

namespace csci2312

{

   using std::string;

   using std::ostream;

   using std::istream;

   class Cell

   {

       friend class GameOfLife;

   public:

       static const char alive ='o'; // alive image

       static const char dead = '-'; // dead image

  

       // Default constructor sets the cell's state to false

       Cell();

       // Custom constructor sets the cell's state as per argument

       Cell(bool state);

       // Empty destructor

       ~Cell();

       // Accessors have no intention to modify the object, so it is a good practice to make them 'const' functions

       bool getState() const;

       // Mutator to change cell's state

       void setState(bool newState);

      

       // Accessor to see the 'face'

       char getFace() const;

   private:

       bool state;

       char face;

      

   };

class GameOfLife

{

      

public:

       static const unsigned int MAX_BOARD = 30;

  

       GameOfLife();

       GameOfLife(size_t boardSize);

       ~GameOfLife();

  

       int seedBoard(string fileName);

       void seedBoard(size_t seeds);

       void run();

       void run(unsigned int numberOfIterations);

       // ADVANCED

       // A const(!) accessor method that returns a handle to the private currentLife array.

       // The return type must also be 'const' because we return a pointer to a static array, and these are fixed

       // It is just an example. It is not needed if we have a friend operator.      

       const Cell(*getCurrentLife() const )[MAX_BOARD+2] { return currentLife; };

       ///////////////////////////////////////////////////////

       // friend operator can access private members of GameOfLife

       friend ostream& operator << (ostream& out, const GameOfLife& board);

       friend istream& operator >> (istream& in, const GameOfLife& board);

      

private:      

       bool executeRules(unsigned int countAlive, bool currentState);

       // With "Halo" approach we need a bigger board

       Cell currentLife[MAX_BOARD + 2][MAX_BOARD + 2];

       Cell nextLife[MAX_BOARD + 2][MAX_BOARD + 2];

       // ADVANCED

       // Example how to declare variable cl as a pointer/handle to our array of Cells of size HALO_BOARD

       // The accessor method getCurrentLife() above uses the same syntax for the return type

       const Cell(*cl)[MAX_BOARD + 2] = currentLife;

       ////////////////////////////////////////////////////////

  

      size_t boardSize; // Board size requested in the constructor  

};

  

// NON-MEMBER OUTPUT FUNCTIONS

// Display cell's state with alive/dead face

   ostream& operator << (ostream& out, const Cell& cell);

  

}

Explanation / Answer

For the given game.h, game.cpp is implemented and also the main program gamemain.cpp is implemented. Sample output is shown at end. Please do rate the answer if it helped.

game.h

#include <iostream> // Provides ostream
#include <string> // String operations
#include <cstdlib> // Randomizer

namespace csci2312

{
using std::string;
using std::ostream;
using std::istream;
class Cell
{
friend class GameOfLife;
public:
  
static const char alive ='o'; // alive image
static const char dead = '-'; // dead image

// Default constructor sets the cell's state to false
Cell();

// Custom constructor sets the cell's state as per argument
Cell(bool state);

// Empty destructor
~Cell();

// Accessors have no intention to modify the object, so it is a good practice to make them 'const' functions
bool getState() const;

// Mutator to change cell's state
void setState(bool newState);

// Accessor to see the 'face'
char getFace() const;
  
private:
bool state;
char face;
};

class GameOfLife
{
public:
  
static const unsigned int MAX_BOARD = 30;
GameOfLife();
GameOfLife(size_t boardSize);
~GameOfLife();
int seedBoard(string fileName);
void seedBoard(size_t seeds);
void run();
void run(unsigned int numberOfIterations);
// ADVANCED
// A const(!) accessor method that returns a handle to the private currentLife array.
// The return type must also be 'const' because we return a pointer to a static array, and these are fixed
// It is just an example. It is not needed if we have a friend operator.

const Cell(*getCurrentLife() const )[MAX_BOARD+2] { return currentLife; };

///////////////////////////////////////////////////////
// friend operator can access private members of GameOfLife

friend ostream& operator << (ostream& out, const GameOfLife& board);
friend istream& operator >> (istream& in, GameOfLife& board);

private:
bool executeRules(unsigned int countAlive, bool currentState);
// With "Halo" approach we need a bigger board

Cell currentLife[MAX_BOARD + 2][MAX_BOARD + 2];
Cell nextLife[MAX_BOARD + 2][MAX_BOARD + 2];

// ADVANCED
// Example how to declare variable cl as a pointer/handle to our array of Cells of size HALO_BOARD

// The accessor method getCurrentLife() above uses the same syntax for the return type
const Cell(*cl)[MAX_BOARD + 2] = currentLife;

////////////////////////////////////////////////////////
size_t boardSize; // Board size requested in the constructor

};

// NON-MEMBER OUTPUT FUNCTIONS

// Display cell's state with alive/dead face
ostream& operator << (ostream& out, const Cell& cell);

}

  

game.cpp

#include "game.h"
#include <fstream>
using namespace std;
namespace csci2312
{
Cell::Cell()
{
state = false;
face = dead;
}
  
Cell::Cell(bool state)
{
this->state = state;
if(state)
face = alive;
else
face = dead;
}
  
Cell::~Cell()
{}
  
bool Cell::getState() const
{
return state;
}
  
// Mutator to change cell's state
void Cell::setState(bool newState)
{
this->state = newState;
if(state)
face = alive;
else
face = dead;
}
  
  
  
// Accessor to see the 'face'
char Cell::getFace() const
{
return face;
}
  
  
GameOfLife::GameOfLife()
{
boardSize = 0;
}
GameOfLife::GameOfLife(size_t boardSize)
{
this->boardSize = boardSize;
}
GameOfLife::~GameOfLife()
{
  
}
int GameOfLife::seedBoard(string fileName)
{
ifstream infile(fileName.c_str());
if(!infile.is_open())
{
cout << "Could not load file " << fileName << endl;
boardSize = 0;
}
else
infile >> *this;
infile.close();
return boardSize;
  
  
}
void GameOfLife::seedBoard(size_t seeds)
{
boardSize = seeds;
for(int i = 1; i <= boardSize; i++)
for(int j = 1; j <= boardSize; j++)
currentLife[i][j].setState(false);
}
void GameOfLife::run()
{
int live;
for(int i = 1; i <= boardSize; i++)
{
for(int j = 1; j <= boardSize; j++)
{
//count living neighbors
live = 0;
for(int r = i - 1; r <= i + 1; r++)
{
for(int c = j - 1; c <= j + 1; c++)
{
if(r == i && c == j) //don't count the current cell
continue;
else if(r >= 1 && r <= boardSize && c>= 1 && c <= boardSize && currentLife[r][c].getState())
live++;
}
}
  
//execute rules to find out next generation state
nextLife[i][j].setState(executeRules(live, currentLife[i][j].getState()));
  
}
  
}
  
//copy back the values
for(int i = 1; i <= boardSize; i++)
for(int j = 1; j <= boardSize; j++)
currentLife[i][j].setState(nextLife[i][j].getState());
}
  
void GameOfLife::run(unsigned int numberOfIterations)
{
for(int i = 1; i <= numberOfIterations; i++)
run();
}

  
bool GameOfLife::executeRules(unsigned int countAlive, bool currentState)
{
if(currentState == true) //living
{
if(countAlive < 2 || countAlive > 3)
return false;
else
return true;
}
else
{
if(countAlive == 3) //dead cell with exactly 3 living neighbors comes to life
return true;
else
return false;
}
}
///////////////////////////////////////////////////////
// friend operator can access private members of GameOfLife
  
ostream& operator << (ostream& out, const csci2312::GameOfLife& board)
{
for(int i =1 ; i <= board.boardSize; i ++)
{
out << endl;
for(int j = 1; j <= board.boardSize; j++)
out << board.currentLife[i][j];
  
}
out << endl;
return out;
}
  
istream& operator >> (istream& in, csci2312::GameOfLife& board)
{
in >> board.boardSize;
int status;
for(int i = 0 ; i < board.boardSize; i++)
{
for(int j = 0; j < board.boardSize; j++)
{
in >> status;
board.currentLife[i][j].setState(status == 1);
}
}
return in;
}
ostream& operator << (ostream& out, const csci2312::Cell& cell)
{
out << cell.getFace();
return out;
}


}

gamemain.cpp

#include "game.h"
#include <fstream>
#include <iostream>
using namespace csci2312;
using std::cout;
using std::cin;
using std::endl;
int main()
{
GameOfLife gol;
string filename;
int n;
  
std::cout << "Enter filename containing 1st generation: ";
std::cin >> filename;
gol.seedBoard(filename);
  
cout << "How many generations? ";
cin >> n;
  
for(int i = 0; i <=n; i++)
{
cout << "Generation " << i << endl;
cout << gol;
gol.run();
}
  
return 0;
}

input file: gol.txt

9
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0
0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0

output

Enter filename containing 1st generation: gol.txt
How many generations? 3
Generation 0

---------
---------
---------
--ooo----
---o-----
---------
---------
---------
---------
Generation 1

---------
---------
---o-----
--ooo----
--ooo----
---------
---------
---------
---------
Generation 2

---------
---------
--ooo----
---------
--o-o----
---o-----
---------
---------
---------
Generation 3

---------
---o-----
---o-----
--o-o----
---o-----
---o-----
---------
---------
---------