Include
Include
#include <memory>
#include <vector>
#include <algorithm>
class Cell
{
public:
enum class State {ALIVE,DEAD};
Cell(int x,int y):_x(x),_y(y) {_state = State::ALIVE;}
int getX()const
{
return _x;
}
int getY()const
{
return _y;
}
State getState()const
{
return _state;
}
void setState(State state)
{
_state = state;
}
private:
//(x,y) represents the position on the grid
int _x;
int _y;
State _state;
};
typedef std::shared_ptr<Cell> CellPtr;
class Cells
{
public:
Cells();
void tick();
vector<CellPtr> getCells(){return _cells;}
int getGeneration()const;
private:
void seed();
int _generation;
CellPtr getCellFromCollection(int,int);
int countAliveNeighbours(CellPtr);
vector<CellPtr> _cells;
};
Cells::Cells()
{
seed();
_generation = 1;
}
void Cells::seed()
{
int BoardWidth = 10;
int BoardHeight = 10;
for(int row = 0; row < BoardHeight; row++)
{
for(int col = 0; col < BoardWidth; col++)
{
CellPtr newCell = make_shared<Cell>(row,col);
//Introduce randomness - that alter the states of the cells
_cells.push_back(newCell);
}
}
}
CellPtr Cells::getCellFromCollection(int x, int y)
{
for(auto cell: _cells)
{
if(cell->getX() == x && cell->getY() == y)
return cell;
}
return nullptr;
}
int Cells::countAliveNeighbours(CellPtr cell)
{
vector<pair<int,int>> directions = {{0,1},{1,1},{1,0},{-1,1},{0,-1},{-1,-1},{-1,0},{1,-1}};
int count = 0;
for(auto& direction: directions)
{
int nx = cell->getX()+direction.first;
int ny = cell->getY()+direction.second;
auto neighbour = getCellFromCollection(nx,ny);
if(neighbour != nullptr)
{
if(neighbour->getState() == Cell::State::ALIVE)
count++;
}
}
return count;
}
void Cells::tick()
{
for(auto cell: _cells)
{
int numberAliveNeighbours = countAliveNeighbours(cell);
if(numberAliveNeighbours < 2)
cell->setState(Cell::State::DEAD);
if(numberAliveNeighbours == 3 && cell->getState() == Cell::State::DEAD)
cell->setState(Cell::State::ALIVE);
if(numberAliveNeighbours > 3)
cell->setState(Cell::State::DEAD);
}
_generation++;
}
void printState(Cell::State state)
{
switch(state)
{
case Cell::State::DEAD:
cout << "Dead ";
break;
case Cell::State::ALIVE:
cout << "Alive ";
break;
default:;
}
}