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

Problem: Conway\'s Game of Life adding a stats feature When you press <s>, depen

ID: 3753221 • Letter: P

Question

Problem: Conway's Game of Life adding a stats feature

When you press <s>, depending in how the current state evolved, you will see how many times a cell has been birthed, ‘.’ indicates no change, ‘A’ through ‘Z’ indicated the number of times it has been birthed (corresponding to 1 through 26, capping at 26). We are not keeping track of deaths.
Your task is to implement this functionality. You will need to do the following:
Define a class named Stats with the following public interface:
class Stats {
public:
// Constructor/destructor
Stats();
~Stats();
// Accessors or Getters
void display() const;
// Mutators or Setters
bool record(int r, int c, int val);
private:
// TODO
};

The constructor initializes the Stats’s grid to correspond to the World’s, however Stats keeps tracks of a count of births for each cell, whereas the World simple displays the cells’ state, being represented by characters.
The destructor cleans up the Stats object. Similar to how the World cleans up after itself.
The display member function prints the stats grid similar to what is seen in the example program.
The record function updates the Stats grid at row r and column c by increased that cell by val. The record function should return false if the coordinates are out of bounds, and true otherwise.
The class declaration (with any private members you choose to add to support your implementation) must be in a file named stats.h, and the implementation of the Stats class's member functions must be in stats.cpp. You must not add any other public members to the class. (This implies, for example, that you must not add a public default constructor.) The only member function of the Stats class that may write to cout is Stats::display.
Add a data member of type Stats (not of type pointer-to-Stats) to the World class, and provide this public function to access it; notice that it returns a reference to a Stats object.
class World {

Stats& stats();

};
Whenever the world is updated we must check to see which cells have been birthed, those cells’ position is then updated in the stats object by adding 1 with the Stats::record function. Note that if the cell’s state has not changed or if it has died, we do not record anything.
The Game’s <s> option should be completed to display the current stats grid. Press enter to continue. prompt and wait for the user to respond. (cin.ignore(10000,' '); does that nicely).

What I have so far:

stats.h:

#ifndef stats_H

#define stats_H

#include "world.h"

class Stats

{

public:

Stats();

~Stats();

//Accessors or Getters

void display() const;

// Mutators or Setters

bool record(int r, int c, int val);

private:

int counter = 0;

};

#endif

stats.cpp:

#include "stdafx.h"

#include "stats.h"

#include "world.h"

Stats::Stats()

{

}

Stats::~Stats()

{

}

void Stats::display() const

{

}

bool Stats::record(int r, int c, int val)

{

if (m_world[i][j] == ALIVE)

{

counter++;

}

//then increase the counter for that cell by 1.

//for each iteration of change increase from A-Z

return false;

}

world.h:

#ifndef world_H

#define world_H

#include "life.h"

class World {

public:

// Constructor/destructor

World();

~World();

// Accessors or Getters

void print() const;

bool hasWorldChanged() const;

// Mutators or Setters

bool addLife(Life *life);

void update();

private:

char _getState(char state, char row, char col, bool toggle);

// The rules of Conway's Game of Life requires each cell to

// examine it's neighbors. So, we have to check the entire world

// first before we change it. We can use two copies of the world,

// one to check the current state then another to generate the

// the next state. We can toggle between them each step, to avoid

// having to copy between worlds each step of the game.

char **m_world;

char **m_otherWorld;

bool m_toggle;

};

#endif

world.cpp:

#include "stdafx.h"

#include <iostream>

#include "world.h"

#include "life.h"

World::World() :

m_toggle(true)

{

m_world = new char*[MAX_ROWS];

m_otherWorld = new char*[MAX_ROWS];

for (char i = 0; i < MAX_ROWS; i++) {

m_world[i] = new char[MAX_COLS];

m_otherWorld[i] = new char[MAX_COLS];

}

for (char i = 0; i < MAX_ROWS; i++) {

for (char j = 0; j < MAX_COLS; j++) {

m_world[i][j] = DEAD;

}

}

}

World::~World() {

for (char i = 0; i < MAX_ROWS; i++) {

delete[] m_world[i];

delete[] m_otherWorld[i];

}

delete[] m_world;

delete[] m_otherWorld;

}

void World::print() const {

clearScreen();

if (m_toggle) {

for (char i = 0; i < MAX_ROWS; i++) {

for (char j = 0; j < MAX_COLS; j++) {

std::cout << m_world[i][j];

}

std::cout << std::endl;

}

}

else {

for (char i = 0; i < MAX_ROWS; i++) {

for (char j = 0; j < MAX_COLS; j++) {

std::cout << m_otherWorld[i][j];

}

std::cout << std::endl;

}

}

for (char i = 0; i < MAX_COLS; i++) {

std::cout << '=';

}

std::cout << std::endl;

}

bool World::hasWorldChanged() const {

for (char i = 0; i < MAX_ROWS; i++) {

for (char j = 0; j < MAX_COLS; j++) {

if (m_otherWorld[i][j] != m_world[i][j]) {

return true;

}

}

}

return false;

}

void World::update() {

if (m_toggle) {

for (char i = 0; i < MAX_ROWS; i++) {

for (char j = 0; j < MAX_COLS; j++) {

m_otherWorld[i][j] =

_getState(m_world[i][j], i, j, m_toggle);

}

}

m_toggle = !m_toggle;

}

else {

for (char i = 0; i < MAX_ROWS; i++) {

for (char j = 0; j < MAX_COLS; j++) {

m_world[i][j] =

_getState(m_otherWorld[i][j], i, j, m_toggle);

}

}

m_toggle = !m_toggle;

}

}

char World::_getState(char state, char row, char col, bool toggle) {

int yCoord = row;

int xCoord = col;

char neighbors = 0;

if (toggle) {

for (char i = yCoord - 1; i <= yCoord + 1; i++) {

for (char j = xCoord - 1; j <= xCoord + 1; j++) {

if (i == yCoord && j == xCoord) {

continue;

}

if (i > -1 && i < MAX_ROWS && j > -1 && j < MAX_COLS) {

if (m_world[i][j] == ALIVE) {

neighbors++;

}

}

}

}

}

else {

for (char i = yCoord - 1; i <= yCoord + 1; i++) {

for (char j = xCoord - 1; j <= xCoord + 1; j++) {

if (i == yCoord && j == xCoord) {

continue;

}

if (i > -1 && i < MAX_ROWS && j > -1 && j < MAX_COLS) {

if (m_otherWorld[i][j] == ALIVE) {

neighbors++;

}

}

}

}

}

if (state == ALIVE) {

return (neighbors > 1 && neighbors < 4) ? ALIVE : DEAD;

}

else {

return (neighbors == 3) ? ALIVE : DEAD;

}

}

bool World::addLife(Life *life) {

if (life == nullptr) {

std::cout << "Cannot add nullptr life" << std::endl;

return false;

}

// Should check life extents with world bounds.

for (char i = life->getRow(); i - life->getRow() < life->getHeight(); i++) {

for (char j = life->getCol(); j - life->getCol() < life->getWidth(); j++) {

if (i < MAX_ROWS && j < MAX_COLS) {

m_world[i][j] =

life->getFromFigure(i - life->getRow(), j - life->getCol());

}

}

}

return true;

}

I just need help creating the stats.h and stats.cpp. The rest of the files shouldn't be necessary, if they are I can post.

Explanation / Answer

stats.cpp


#include "stats.h"
#include "world.h"
#include <iostream>

//The constructor initializes the Stats’s grid to correspond to the World’s, however Stats keeps tracks of a count of births for each cell, whereas the World simple displays the cells’ state, being represented by characters.
Stats::Stats(){
    m_statsWorld = new char*[MAX_ROWS];
    for (char i = 0; i < MAX_ROWS; i++) {
        m_statsWorld[i] = new char[MAX_COLS];
    }
  
    for (char i = 0; i < MAX_ROWS; i++) {
        for (char j = 0; j < MAX_COLS; j++) {
            m_statsWorld[i][j] = 0;
        }
    }
}

//The destructor cleans up the Stats object. Similar to how the World cleans up after itself.
Stats::~Stats(){
    for (char i = 0; i < MAX_ROWS; i++) {
        delete[] m_statsWorld[i];
    }
    delete[] m_statsWorld;
}

//The display member function prints the stats grid similar to what is seen in the example program.
// Accessors or Getters
void Stats::display() const{
    for (char i = 0; i < MAX_ROWS; i++) {
        for (char j = 0; j < MAX_COLS; j++) {
            if (m_statsWorld[i][j] == 0)
                std::cout << DEAD;
            else
                std::cout << (char)(m_statsWorld[i][j] + 64);
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

//The record function updates the Stats grid at row r and column c by increasing that cell by val. The record function should return false if the coordinates are out of bounds, and true otherwise.
// Mutators or Setters
bool Stats::record(int r, int c, int val) {
    if (r >= MAX_ROWS || r < 0 || c >= MAX_COLS || c < 0)
        return false;
    else {
        if ((m_statsWorld[r][c] + val) > 26)
            m_statsWorld[r][c] = 26;
        else if ((m_statsWorld[r][c] + val) < 0) //not sure how to handle negative val?
            m_statsWorld[r][c] = 0;
        else
            m_statsWorld[r][c] += val;
        return true;
    }
}


stats.h


#ifndef stats_h
#define stats_h

///////////
/*
When you press <s>, depending in how the current state evolved, you will see how many times a cell has been birthed, ‘.’ indicates no change, ‘A’ through ‘Z’ indicated the number of times it has been birthed (corresponding to 1 through 26, capping at 26).
*/
///////////

class Stats {
public:
    // Constructor/destructor
    Stats();
    ~Stats();
  
    // Accessors or Getters
    void display() const;
  
    // Mutators or Setters
    bool record(int r, int c, int val);
  
private:
    char **m_statsWorld;
};

#endif /* stats_h */

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote