I made the game of Life in C++ for a highschool class project. The website we're using doesn't have an autograder for C++, and my programming teacher doesn't really know how to program... so I'd love some external feedback! While I believe this simulation works, I'm not sure about the quality of the code. I tried making it as readable and fluid as possible, but I'm new to C++. Let me know how "C++" this code is, and about any pitfalls I may have dug myself into.
I'm unsure what version of C++ this website uses, but I believe its pre-C++11? (Due to a lack of smart pointers.)
I highly reccomend running it on the website here: https://codehs.com/sandbox/drakepickett/game-of-life
p.s. - I added console clearing and such just as a cheeky experiment to make it look nice. Not sure how safe console clearing with my method is :)
Thank you very much!
Here is the raw code:
#include "util.h"
#include <vector>
#include <chrono>
#include <thread>
using namespace std;
struct Board
{
int BOARD_SIZE;
char liveCell;
char deadCell;
vector<vector<char> > cells;
void populateBoard()
{
int numLive = readInt(1, BOARD_SIZE*BOARD_SIZE, "Please enter number of active cells between 1 and " + to_string(BOARD_SIZE*BOARD_SIZE)+ ": ");
for (int i = 0; i < numLive; i++)
{
int x, y;
while (true)
{
x = randInt(0, this->BOARD_SIZE-1);
y = randInt(0, this->BOARD_SIZE-1);
if (this->cells[x][y] == this->deadCell) break;
}
this->cells[x][y] = this->liveCell;
}
}
Board(int size, char liveCell, char deadCell)
{
this->BOARD_SIZE = size;
this->liveCell = liveCell;
this->deadCell = deadCell;
for (int i = 0; i < this->BOARD_SIZE; i++)
{
vector<char> row;
for (int j = 0; j < this->BOARD_SIZE; j++)
{
row.push_back(this->deadCell);
}
this->cells.push_back(row);
}
populateBoard();
}
int getNumNeighbors(int row, int column)
{
int numNeighbors = 0;
vector<int> xRange;
vector<int> yRange;
if (row > 0) yRange.push_back(-1);
yRange.push_back(0);
if (row < this->cells.size()-1) yRange.push_back(1);
if (column > 0) xRange.push_back(-1);
xRange.push_back(0);
if (column < this->cells.size()-1) xRange.push_back(1);
for (int y : yRange)
{
for (int x : xRange)
{
if (x == 0 && y == 0) continue;
//cout <<"Y: " << row << " | Row: " << row+y << " _ X: " << column << " | Column: " << column + x << endl;
if (this->cells[row+y][column+x] == this->liveCell) numNeighbors++;
//cout << "We made it!" << endl;
}
}
return numNeighbors;
}
void update()
{
vector<vector<char> > b = this->cells;
for (int i = 0; i < this->BOARD_SIZE; i++)
{
for(int j = 0; j < this->BOARD_SIZE; j++)
{
int numNeighbors = getNumNeighbors(i, j);
if (this->cells[i][j] == this->liveCell && !(numNeighbors == 2 || numNeighbors == 3)) b[i][j] = this-> deadCell;
if (this->cells[i][j] == this->deadCell && numNeighbors == 3) b[i][j] = this->liveCell;
}
}
this->cells = b;
}
void print()
{
for (int i = 0; i < this->BOARD_SIZE; i++)
{
for (int j = 0; j < this->BOARD_SIZE; j++)
{
cout << this->cells[i][j] << " ";
}
cout << endl;
}
}
};
void cls()
{
using namespace std::chrono_literals;
this_thread::sleep_for(1000ms);
std::cout << "\x1B[2J\x1B[H";
}
int main()
{
Board board(15, 'X', '-');
int numIterations = readInt(0, 1000, "Run how many iterations? (0-1000): ");
for (int i = 0; i < numIterations; i++)
{
cls();
cout << "Iteration " << i << endl;
board.print();
board.update();
}
cls();
cout <<"Final Board" << endl;
board.print();
return 0;
}