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

// FILE GameOfLife.h // CLASSES: GamOfLife, Cell(in the namespace csci2312) // /

ID: 3789646 • Letter: #

Question

// FILE GameOfLife.h

// CLASSES: GamOfLife, Cell(in the namespace csci2312)

//

// DESCRIPTION: https://en.wikipedia.org/wiki/Conway%27s_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, or "populated" or "unpopulated"

// 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 fewer 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 over-population.

// 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 happes 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.

//

//

//////////////// GameOfLife /////////////////////////

// HIGH LEVEL DESIGN

// State the key points of your high level design:

// - What are the GameOfLife (GOL) class' responsibilities?

// GOL houses the Cells in a matrix.

// It sets and executes all the rules on the Cells (future idea: imagine this responsibility given to a Cell)

// - What are the responsibilities of a Cell?

// A Cell knows and can articulate its state (even if it is dead :)

// - What data structure(s) of cells will you use to model and implement the board?

// This implementation will use static two-dimensional arrays

// - How will you go about keeping track of the current and next cell populations?

// One array will hold the current state, and the second array will hold the calculated next generation state.

// After the current state is displayed, the next state will be copied over the current state for subsequent display

// [ OPTIONAL STUDENT TASK: briefly describe another, perhaps more efficient, implementation idea ]

// - How will you go about game boundary conditions (edges and corners)?

// [ STUDENT TASK: fill in your implementation approach. With "halo" approach, you will need a board of size MAX_BOARD+2]

// - How will you handle error conditions (when a method fails in any way)?

// A method with a known risk of failure will return a success/fail (zero/one) status.

// Every calling layer will propagate the status code to the outer layer, and the most outer layer (the main) will exit

//

// A PRECONDITION states what must be true when/before a function is invoked.

// The responsibility to meet/check the pre-condition belongs with the calling layer.

// If that condition is not met, the behavior of the called function is not predictable and may result in failure

//

// A POSTCONDITION states what is the function outcome, and if/how the state of the object(s) has changed

//

// =================== PUBLIC CLASS API - Cell

// CONSTRUCTORS:

// Cell();

// POSTCONDITION: Creates a dark/dead Cell

//

// MODIFIERS/MUTATORS:

// void setState(bool newState);

// POSTCONDITION: Cell's state is set to the new state

//

// ACCESSORS:

// bool getState();

// POSTCONDITION: Returns Cell's state. True if alive/lit, and false if dead/dark

//

// =================== PRIVATE CLASS MEMBERS - Cell

//

// bool state;

//

// =================== PUBLIC CLASS API - GameOfLife

// MEMBER CONSTANTS:

// const static size_t MAX_BOARD

// The max size of the visible gameboard. The actual size will be passed into the game's constructor.

//

// CONSTRUCTORS:

// GameOfLife();

// POSTCONDITION: Creates a maximum size matrix of dark cells

//

// GameOfLife(size_t boardSize);

// PRECONDITION: boardSize is not greater than MAX_BOARD

// POSTCONDITION: Creates a boardSize-size matrix of dark cells. Sets boardSize private member.

//

// MODIFIERS/MUTATORS:

//

// int seedBoard(string fileName);

// FUNCIONALITY: Initializes the board; reads the configuration of lit from a text file. Returns 0/1 for sucsess/failure

// POSTCONDITION: Board is successfully seeded with a known predictable pattern, method returns 0 (zero) to indicate success.

// If the operation failed (could not open the file, wrong file format, etc), the function returns 1.

//

// void seedBoard(size_t seeds);

// FUNCTIONALITY: Initializes the board with seeds-number of lit cells at randomly generated locations.

// PRECONDITION: Number of seeds requested is not greater than maximum matrix capacity

// POSTCONDITION: Board is successfully seeded

//

// void run( );

// FUNCTIONALITY: Starts the simulation. Asks a user if to generate another iteration, or if to end

// POSTCONDITION: Simulation has run

// void run(unsigned int numberOfIterations);

// FUNCTIONALITY: Starts the simulation.

// POSTCONDITION: Simulation has run

//

// =================== PRIVATE CLASS MEMBERS - GameOfLife

//

// void nextGeneration();

// FUNCTIONALITY: Calculates the next state of the population of Cells

// POSTCONDITION: Next state has been calculated and is ready to display

//

// =================== NON-MEMBER FUNCTIONS

//

// ostream& operator << (ostream& out, const GameOfLife& board)

// POSTCONDITION: The game board has been displayed (printed to ostream out, which,

// in turn, has been returned to the calling function)

//

#pragma once

#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

#pragma once

#include <iostream> // Provides ostream

#include <string> // String operations

#include <cstdlib> // Randomizer

#include <stdio.h>

#include<stdlib.h>

#include<time.h>

namespace csci2312

{

   using std::string;

   using std::ostream;

   using std::istream;

// size of the grid 52 x 102

void duplicate(int array1[52][102], int array1[52][102])

{

for (int j=0; j<52; j++)

{

      for (int i=0; i<102; i++)

             array2[j][i] = array1[j][i];

}

}

void gol(int array[52][102], char n)

{

int temp[52][102];

copy(array, temp);

                for(int j = 1; j < 51; j++)

                {

                                for(int i = 1; i < 101; i++)                                                

                                {             

                                                if(n == 'm')

                                                {

int count = 0;

                                                                count = array[j-1][i] +

                                                                                array[j-1][i-1] +

                                                                                array[j][i-1] +

                                                                                array[j+1][i-1] +

                                                                                array[j+1][i] +

                                                                                array[j+1][i+1] +

                                                                                array[j][i+1] +

                                                                                array[j-1][i+1];

                                                                //The cell dies.

        if(count < 2 || count > 3)

                                                                                temp[j][i] = 0;

                                                                //The cell stays the same.

        if(count == 2)

                                                                                temp[j][i] = array[j][i];

                                                                //The cell either stays alive, or is "born".

        if(count == 3)

                                                                                temp[j][i] = 1;

                                                }

                                                else if(n== 'v')

                                                {

int count = 0;

                                                                count = array[j-1][i] +

                                                                                array[j][i-1] +

                                                                                array[j+1][i] +

                                                                                array[j][i+1];     

        //The cell dies.

                                                                if(count < 2 || count > 3)

                                                                                temp[j][i] = 0;

                                                                //The cell stays the same.

        if(count == 2)

                                                                                temp[j][i] = array[j][i];

                                                                //The cell either stays alive, or is "born".

        if(count == 3)

                                                                                temp[j][i] = 1;

                                                }                                                             

                                }

                }

void show(int array[52][102])

{

                for(int j = 1; j < 51; j++)

                {

                                for(int i = 1; i < 101; i++)                                                

                                {             

                                                if(array[j][i] == 1)

                                                                cout << '*';

                                                else

                                                                cout << ' ';

                                }

                                cout << endl;

                }

}

   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);

  

}

int main()

{

int basic[52][102]; // basic cell or generation

int req[52][102];   // required

int dup[52][102]; // duplicate

char n; // neighbor

bool comp; // compare

   do

      {

         cout<<”Enter the neighbor (m or v) :”;

         cin>>n;

     } while(n != ‘m’ && n != ‘v’);

       srand(time(NULL));

          for(int j=1; j<51; j++)

           {

                   for(int i=1; i<101;i++)

                   basic[j][i] = rand()%2;

gol( basic, n);

             }

         

          if(i==0)

{

             duplicate(basic, req);

             duplicate(req, dup);

              i++;

         }

show();

return 0;

}