What's wrong with my LifeEngine?
LifeEngine.h
#define _LIFEENGINE_H_
#include <iostream>
using std::ostream;
using std::istream;
using std::endl;
class CGrid
{
friend ostream& operator<<(ostream& osOutput, CGrid& GridToPrint);
friend istream& operator>>(istream& isInput, CGrid& gridToPrint);
private:
bool **m_prgbGrid;
int m_iRows;
int m_iCols;
public:
CGrid(int iRows, int iCols);
CGrid(CGrid& oldCGrid);
~CGrid();
bool& OnGet(int iRow, int iCol); //returns reference to cell
int OnGetSize(char cXorY); //returns x or y dimension of CGrid
};
ostream& operator<<(ostream& osOutput, CGrid& GridToPrint);
istream& operator>>(istream& isInput, CGrid& gridToPrint);
class CGameOfLife : public CGrid
{
private:
public:
CGameOfLife(int iRows, int iCols) : CGrid(iRows, iCols){;};
int OnCountNeighbors(int iRow, int iCol);
void OnAdvance(); //impliments rules of game of life for one turn
};
#endif
LifeEngine.cpp
// Definitions for CGrid
CGrid::CGrid(int iRows, int iCols)
{
this->m_iCols = iCols;
this->m_iRows = iRows;
this->m_prgbGrid = new bool*[this->m_iRows];
for(int i = 0; i < this->m_iRows; i++)
{
this->m_prgbGrid[i] = new bool[this->m_iCols];
for(int j = 0; j < this->m_iCols; j++)
{
this->m_prgbGrid[i][j]=false;
}
}
}
CGrid::CGrid(CGrid& oldCGrid)
{
int iCols = oldCGrid.m_iCols;
int iRows = oldCGrid.m_iRows;
this->m_iCols = iCols;
this->m_iRows = iRows;
this->m_prgbGrid = new bool*[this->m_iRows];
for(int i = 0; i < this->m_iRows; i++)
{
this->m_prgbGrid[i] = new bool[this->m_iCols];
for(int j = 0; j < this->m_iCols; j++)
{
this->m_prgbGrid[i][j]=oldCGrid.m_prgbGrid[i][j];
}
}
}
CGrid::~CGrid()
{
delete [] this->m_prgbGrid;
}
bool& CGrid::OnGet(int iRow, int iCol)
{
return this->m_prgbGrid[iRow][iCol];
}
int CGrid::OnGetSize(char cXorY)
{
switch (cXorY)
{
case 'x':
return this->m_iCols;
break;
case 'y':
return this->m_iRows;
break;
default:
std::cout << "x or y not given as parameter in OnGetSize";
exit(1);
break;
}
}
ostream& operator<<(ostream& osOutput, CGrid& gridToPrint)
{
for(int i = 0; i < gridToPrint.OnGetSize('y'); i++)
{
for(int j = 0; j < gridToPrint.OnGetSize('y'); j++)
{
if(gridToPrint.OnGet(i,j))
osOutput << (char)(219);
else
osOutput << (char)(255);
}
osOutput << '\n';
}
osOutput << endl;
osOutput << "theGame sent to stream" << endl;
return osOutput;
}
istream& operator>>(istream& isInput, CGrid& gridToPrint)
{
int iRow;
int iCol;
bool bToggle;
isInput >> iRow;
isInput >> iCol;
isInput >> bToggle;
gridToPrint.OnGet(iRow,iCol) = bToggle;
return isInput;
}
//End Definitions for CGrid
//Definitions for CGameOfLife
int CGameOfLife::OnCountNeighbors(int iRow, int iCol)
{
int iNeighbors = 0;
int iXMin;
int iXMax;
int iYMin;
int iYMax;
//bound X Minimum
if(iCol -1 >= 0)
{
iXMin = iCol-1;
}
else
{
iXMin = 0;
}
//bound Y Minimum
if(iRow -1 >= 0)
{
iYMin = iRow-1;
}
else
{
iYMin = 0;
}
//bound X Maximum
if(iCol+1 < this->OnGetSize('x'))
{
iXMax = iCol+1;
}
else
{
iXMax = this->OnGetSize('x')-1;
}
//bound Y Maximum
if(iRow+1 < this->OnGetSize('y'))
{
iYMax = iRow+1;
}
else
{
iYMax = this->OnGetSize('y')-1;
}
for(int i = iYMin; i <= iYMax; i++)
{
for(int j = iXMin; j <= iXMax; j++)
{
if(this->OnGet(i,j)==true && !(i == iRow && j == iCol))
iNeighbors++;
}
}
return iNeighbors;
}
void CGameOfLife::OnAdvance()
{
int iCols = this->OnGetSize('x');
int iRows = this->OnGetSize('y');
for(int i = 0; i < iRows; i++)
{
for(int j = 0; j < iCols; j++)
{
int iNeighbors = this->OnCountNeighbors(i,j);
bool *pbAlive = &(this->OnGet(i,j)); //gets a pointer reference to the current cell
if(*pbAlive)
{
if(iNeighbors > 3 || iNeighbors < 2)
*pbAlive = false;
}
else
{
if(iNeighbors == 3)
*pbAlive = true;
}
}
}
}
//End Definitions for CGameOfLife
when I do a blinker
* **
then goes to this
**
You are making the classic error with life... you cannot update the grid "in-place".
A generation consists of deciding what should happen to each cell (a birth, a death or no change), then simultaneously applying that across the grid.
Obviously, there is a trivial way to get round this - you build a totally new grid each time, then copy it back over the original. Not so hot, if you want a BIG grid.
You can skip the copy if you alternate the grid in two buffers.
If, as you have done, you treat edges as places where cells can never live, it is very easy to overlap the two buffers, bar for a row (or so).
I always used to prefer to treat the universe as a torus. Overlapping the buffers is a bit more fiddly.
If you want seriously large, long-lived universes, you want to look at the "hashlife" algorithm.
_________________
"Striking up conversations with strangers is an autistic person's version of extreme sports." Kamran Nazeer
Wow! You spent four days in the shower.
_________________
"Striking up conversations with strangers is an autistic person's version of extreme sports." Kamran Nazeer
| Similar Topics | |
|---|---|
| Hello Wrong Planet! |
03 Jul 2026, 1:53 pm |
| wrong planet is back! |
01 Jul 2026, 7:23 pm |
