Page 1 of 1 [ 4 posts ] 

ahayes
Veteran
Veteran

User avatar

Joined: 2 Dec 2006
Gender: Male
Posts: 9,506

23 May 2007, 9:30 pm

LifeEngine.h

Code:
#ifndef _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
Code:
#include "LifeEngine.h"


// 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
Code:
***
it turns into this
Code:
 **
* **

then goes to this
Code:
**
**



lau
Veteran
Veteran

User avatar

Joined: 17 Jun 2006
Age: 77
Gender: Male
Posts: 9,798
Location: Somerset UK

24 May 2007, 6:05 am

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


ahayes
Veteran
Veteran

User avatar

Joined: 2 Dec 2006
Gender: Male
Posts: 9,506

28 May 2007, 1:38 am

I realized what I did in the shower and I implemented a linked list to apply changes after deciding what to do with them.



lau
Veteran
Veteran

User avatar

Joined: 17 Jun 2006
Age: 77
Gender: Male
Posts: 9,798
Location: Somerset UK

28 May 2007, 7:15 am

ahayes wrote:
I realized what I did in the shower and I implemented a linked list to apply changes after deciding what to do with them.

Wow! You spent four days in the shower.


_________________
"Striking up conversations with strangers is an autistic person's version of extreme sports." Kamran Nazeer