Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

C++ Help with the Game of Life (John Conway)

I'm writing a program that deals with the Game of Life, a sort of Artificial Life simulation, I'm not sure if it could be considered a game, but this is close enough.

What the program basically does, is it prompts the user for a file name (the name of the seed in a .txt or whatever ), the size of the board, the number of generations to be displayed, and the iteration at which to display them. The seed is mapped out in boolean form blanks are equal to 0's and *'s to 1. The ComputeGen function takes in the board after it has been processed ( you'll see in the code ), and it'll use a brand new blank board to implement the next Gen onto THAT, because tampering with the seed initially will generate incorrect Generations. Then it'll return the next Generation and print it out.

My Main Problem is in my Output Loop, it takes in Seed initially, which should look exactly like this in an external file:
[hr]


*** *
*
**
** *
* * *

[hr]
This should be a 5x5 board of blanks and *'s.
Or it could have different dimensions and different cells, but anyway, the main problem is, when my ComputeGen function takes in board ( which at first should be the seed ) it processes it and the print function displays it, but then when it loops again, that same seed is processed over again. I do not want this, I want the product of the ComputeGen to be processed each time. When the seed is processed and displayed, I then want that output processed and displayed to show my next Generation and so on. Otherwise I'm getting no where.

The second minor problem is that I want to map out the bool board from 1's and 0's to just blanks and *'s. My output so far shows 1's and 0's AND blanks and *'s. That's not my concern yet, I want to fix my logic first.

I don't get it, the problem seems so simple, yet I can't think of anything that'll get this thing to work... I've wracked my brain enough, and I've ran out of ideas. Any help will be greatly appreciated!

Here's the code:
[hr]
#include
#include
#include
using namespace std;

int CountNeighbors( bool **, int, int );
bool ComputeGen( bool **, int );
void print ( bool **, int );


int main()
{


//VAR list------
string filename;
ifstream infile;
char c;
bool **board;
int size;
int numGens;
int numIt;
//--------------




//--------Collect Data input from user------------------------------
cout << "Enter data filename: ";
cin >> filename;
infile.open(filename.c_str()); // Open file ( Seed generation from text file )

if ( !infile )
{
cout << "Cannot locate your file. Check your spelling.
";
system("pause");
exit(0);

}

cout << "Specify size: ";
cin >> size; //get size
cout << "Number of Generations: " << endl;
cin >> numGens;
size += 2; //Create buffer zone to retain same ComputeGen algorithm
cout << "Number of Iterations:
";
cin >> numIt;
board = new bool * [size]; //Reserve memory to create board
//--------------------------------------------------------------------



//------Map Seed File in Bool form----------------------------
for ( int i = 0; i < size; i++ )
board[i] = new bool[size];
for ( int row = 0; row < size; row++ )
{
for( int col = 0; col < size; col++ )
{
infile.get(c);
if ( c == '
' )
infile.get(c);
if ( c == '*' )
board[row][col] = true;
else if ( c == ' ' )
board[row][col] = false;
}
}
//----------------------------------------------------------


//Output Loop-------------------------------------------------------
for ( int j = 0; j < numGens; j++ ) // Generation Loop, specify how many Generations to Compute
{

cout << "Table " << j + 1 << ": Generation " << j << "
"; //Display which Table and Generation

ComputeGen( board, size );

if ( numGens % numIt == 0 ) //Display at whichever iteration specified
{
cout << "

";
print( board, size );
cout << "

";
}

}
//-----------------------------------------------------------------


system( "pause" );
return 0;

}



//*******Display Generations************************
/*Function used to display Generation in terms of *'s
and blanks not 1's and 0's. So far, that's not doing
it's job either.*/
void print( bool ** board, int size )
{
for ( int row = 1; row < size; row++ )
{
for ( int col = 1; col < size; col++ )
{
if ( board[row][col] == 1 )
cout << "*";
else
cout << " ";

cout << board[row][col] << " ";

}
cout << endl;

}

}
//**************************************************




//****Count the Number of Neighbors*********************
// Function used to determine how many neighbors I have
int CountNeighbors(bool ** newBoard, int row, int col)
{
int neighbors = 0;

if ( newBoard[row - 1][col - 1] == true )
neighbors++;
if ( newBoard[row - 1][col] == true )
neighbors++;
if ( newBoard[row - 1][col + 1] == true )
neighbors++;
if ( newBoard[row ][col - 1] == true )
neighbors++;
if ( newBoard[row ][col + 1] == true )
neighbors++;
if ( newBoard[row + 1][col - 1] == true )
neighbors++;
if ( newBoard[row + 1][col] == true )
neighbors++;
if ( newBoard[row + 1][col + 1] == true )
neighbors++;

return neighbors;

}
//*******************************************************




//*******Compute Generations***************************
/* Compute the next Generations. So far, it's computing
the Seed generation over and over again. I need it to
take the output of the loop and compute that to generate
a series of generations until they stabilize.
*/
bool ComputeGen( bool ** board, int size )
{


//--Create different Board to implement new changes
bool ** newBoard;
newBoard = new bool * [size];
for ( int i = 0; i < size; i++ )
newBoard[i] = new bool[size];
//--------------------------------------------------


for ( int row = 1; row < size - 1; row++ )
{
for( int col = 1; col < size - 1; col++)
{

int neighbors = CountNeighbors( newBoard, row,col ); // Store neighbor count in this variable, need to know how many we have in each case



//----Examine live cells----------------------------
if ( board[row][col] == true )
{
if ( neighbors == 2 || neighbors == 3 )
newBoard[row][col] = true;
if ( neighbors < 2 || neighbors > 3 )
newBoard[row][col] = false;
}
//--------------------------------------------------




//----Examine dead cells----------------------------
if ( board[row][col] == false )
if ( neighbors == 3 )
newBoard[row][col] = true;
//--------------------------------------------------


} // End Col Loop


} // End Row Loop

** board = ** newBoard; //I was hoping this would fix the problem, but it doesn't. Still does what it's been doing.

return ** board;

} // End Function
//******************************************************************

[hr]

Comments

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]
    You need two arrays - one for current generation ([italic]CurrentGen[/italic]) and one where you will build next generation ([italic]NextGen[/italic]). The steps for a game look somewhat like that:

    1. Load the source file with seeded cells for a very first generation into an array [italic]CurrentGen[/italic]

    2. Put blanks in all cells of [italic]NextGen[/italic]

    3. Print out the [italic]CurrentGen[/italic] to show how LIFE begins

    4. Using [italic]CurrentGen[/italic] as input generate [italic]NextGen[/italic]
    5. Print out [italic]NextGen[/italic]
    6. Copy all cells of [italic]NextGen[/italic] into corresponding cells of [italic]CurrentGen[/italic]
    7. Blank out all cells in [italic]NextGen[/italic]

    8. Repeat steps 4-7 until LIFE ends

    I think you are missing steps 6,7 in your code.
    Have fun! This program (LIFE) is fun to write.
    I will make a FASM tutorial from LIFE.
    [/color]
  • guesstguesst Member Posts: 46
    : [color=Blue]
    : You need two arrays - one for current generation
    : ([italic]CurrentGen[/italic]) and one where you will build next
    : generation ([italic]NextGen[/italic]). The steps for a game look
    : somewhat like that:
    :
    : 1. Load the source file with seeded cells for a very first
    : generation into an array [italic]CurrentGen[/italic]
    :
    : 2. Put blanks in all cells of [italic]NextGen[/italic]
    :
    : 3. Print out the [italic]CurrentGen[/italic] to show how LIFE begins
    :
    : 4. Using [italic]CurrentGen[/italic] as input generate
    : [italic]NextGen[/italic]
    : 5. Print out [italic]NextGen[/italic]
    : 6. Copy all cells of [italic]NextGen[/italic] into corresponding
    : cells of [italic]CurrentGen[/italic]
    : 7. Blank out all cells in [italic]NextGen[/italic]
    :
    : 8. Repeat steps 4-7 until LIFE ends
    :
    : I think you are missing steps 6,7 in your code.
    : Have fun! This program (LIFE) is fun to write.
    : I will make a FASM tutorial from LIFE.
    : [/color]
    Now, hold on. It can be done, and [link=http://www.atariarchives.org/basicgames/showpage.php?page=100]has been done[/link], in a very clever single array. The way to do it is:

    1. Populate your array.

    2. Print out the current generation.

    3. walk through the array, if a spot is not evenly divisible by 10 (a current block) add 10 to the eight blocks that touch it.

    4. Walk though the array again. Divide each resulting number by 10 and if the result is 2 or 3 then change it to a 1, otherwise make it 0;

    5. goto step 2.

    I implimented an idea like this for a [link=http://www.retroremakes.com/forum2/showpost.php?p=147340&postcount=18]multi-player version of life[/link] (which I plan to redo curses style).
Sign In or Register to comment.