Need help with "Game of Life".

The program we are working on is the "Game of Life". The main problem we are having is storing the board information from the given text file (that we must use).

- how do we get our lines of text to be put directly into our array (skipping the string business) and allow for infinite size (not limited to 10 lines). We think we need to do while loops for this some how but cant figure out how?

-We have to pull the pattern from the given text file (attached), Is there a better way to read the first line form it to get board parameters. we tried to use this bit bellow to change it to integers by using substrings? The first line has four numbers the columns and rows of the board then the column and row to start the initial pattern on. Looks like,

30 50 10 15
*** *** *
** *** **
**** *****
** ****


- here is our code so far



#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

int main()
{

fstream openfile;

char file1[50];
cout << "Please enter the file you wish to use: " << "\n" ;
cin.getline(file1, 50);
cout << "\n";
openfile.open(file1);
string parameters; string line1;string line2;string line3;string line4;string line5;string line6;string line7;string line8; string line9; //define the lines from the files


while(!openfile.eof()){

getline (openfile, parameters); //store each line into file
getline (openfile, line1);
getline (openfile, line2);
getline (openfile, line3);
getline (openfile, line4);
getline (openfile, line5);
getline (openfile, line6);
getline (openfile, line7);
getline (openfile, line8);
getline (openfile, line9);
}

//char fpar == parameters.substr(0,2);
//const int MaxCol = atoi(fpar);

//char spar == parameters.substr(3,2);
//const int MaxCol = atoi(fpar);

//char tpar == parameters.substr(6,2);
//const int MaxCol = atoi(fpar);

//char frpar == parameters.substr(9,2);
//const int MaxCol = atoi(fpar);

const int MaxCol = stoi(parameters.substr(0,2));
const int MaxRow = stoi(parameters.substr(3,2));
const int startCol = stoi(parameters.substr(6,2));
const int startRow = stoi(parameters.substr(9,2));

char a[MaxCol+2][MaxRow+2], b[MaxCol+2][MaxRow+2]; // Defining initial game board with border

for(int i=0; i<MaxCol+2; i++)
for(int j=0; j<MaxRow+2; j++)
a[i][j]=' ', b[i][j]=' ';
//Clears gameboard


//Enter in board information from file

for(int i=0; i<line1.length(); i++) //entering first line
{
if(line1.substr(i,1)=="*"){
a[startCol+i][startRow] = '*';}
else{
a[startCol+i][startRow] = ' ';}

}
for(int i=0; i<line2.length(); i++) //now 2nd line
{
if(line2.substr(i,1)=="*"){
a[startCol+i][startRow+1] = '*';}
else{
a[startCol+i][startRow+1] = ' ';}

}
for(int i=0; i<line3.length(); i++) //3rd line...
{
if(line3.substr(i,1)=="*"){
a[startCol+i][startRow+2] = '*';}
else{
a[startCol+i][startRow+2] = ' ';}

}
for(int i=0; i<line4.length(); i++) //hey if it works it works
{
if(line4.substr(i,1)=="*"){
a[startCol+i][startRow+3] = '*';}
else{
a[startCol+i][startRow+3] = ' ';}

}
for(int i=0; i<line5.length(); i++)
{
if(line5.substr(i,1)=="*"){
a[startCol+i][startRow+4] = '*';}
else{
a[startCol+i][startRow+4] = ' ';}
}
for(int i=0; i<line6.length(); i++)
{
if(line6.substr(i,1)=="*"){
a[startCol+i][startRow+5] = '*';}
else{
a[startCol+i][startRow+5] = ' ';}
}
for(int i=0; i<line7.length(); i++)
{
if(line7.substr(i,1)=="*"){
a[startCol+i][startRow+6] = '*';}
else{
a[startCol+i][startRow+6] = ' ';}
}
for(int i=0; i<line8.length(); i++)
{
if(line8.substr(i,1)=="*"){
a[startCol+i][startRow+7] = '*';}
else{
a[startCol+i][startRow+7] = ' ';}
}
for(int i=0; i<line9.length(); i++)
{
if(line9.substr(i,1)=="*"){
a[startCol+i][startRow+8] = '*';}
else{
a[startCol+i][startRow+8] = ' ';}
}

//Do note: if a file has more than 10 lines, any lines after 10 will be omitted from the initial pattern, we could easily add more strings to accomidate more lines (rows) and fix the issue


int Gens_to_run;

cout << "Enter number of generatiions to run" << "\n" ;
cin >> Gens_to_run;
//asks user for number of generations to run

//game board is now set from file, now compute the nearest neighbors

int Gens_ran = 0; //counts generations that have been ran

int r = 0;

while (Gens_ran < Gens_to_run && r == 0)
{

for (int i = 1; i < MaxCol+1; i++) //starting at 1 and going to maxrow+1 to stay within borders
{
for (int j = 1; j < MaxRow+1; j++) //starting at 1 and going to maxrow+1 to stay within borders
{

// displays the current generation
for(int j=0; j<MaxRow+2; j++)
{
for(int i=0; i<MaxCol+2; i++)
cout << a[i][j];
cout << "\n";
}

int neighbors = 0;

if (a[i-1][j-1] == '*') neighbors += 1;
if (a[i-1][j] == '*') neighbors += 1;
if (a[i-1][j+1] == '*') neighbors += 1;
if (a[i][j-1] == '*') neighbors += 1;
if (a[i][j+1] == '*') neighbors += 1;
if (a[i+1][j-1] == '*') neighbors += 1;
if (a[i+1][j] == '*') neighbors += 1;
if (a[i+1][j+1] == '*') neighbors += 1;
//counts number of neighbors:
if (a[i][j] == '*' && neighbors < 2)
b[i][j] = ' ';
else if (a[i][j] == '*' && neighbors > 3)
b[i][j] = ' ';
else if (a[i][j] == '*' && (neighbors == 2 || neighbors == 3))
b[i][j] = '*';
else if (a[i][j] == ' ' && neighbors == 3)
b[i][j] = '*';
//store new generation in b array
}
}

Gens_ran++; //count the number of generation ran

cout << "Press the ENTER key to run next generation or anyother key to quit";
if (cin.get() == '\n')
{
cout << "\n";
for(int i=0; i<MaxCol+2; i++) //generation "b" becomes "a" generation
for(int j=0; j<MaxRow+2; j++)
a[i][j]=b[i][j];
}
else {
r = 1;
}
}
cout << "Your game of life is over" << "\n";
}
Since you are familiar with arrays, I'm very surprised to see the rather long-winded use of variables line1, line2, line3 etc.
You might instead use an array for that purpose too.

The code at present doesn't compile. It uses an undefined function stoi(). It's reasonable to assume that should be atoi(). But it still doesn't compile because atoi() requires a c-string and you are passing a c++ string as a parameter.
That's easily remedied with .c_str().

But still, as you asked, is there an easier way. Well, you could use normal c++ formatted input.
1
2
int a, b, c, d;
openfile >> a >> b >> c>> d;

You'll probably have to use openfile.ignore(20,'\n'); or something similar to ignore to the end of the line.

Further down, you use char a[MaxCol+2][MaxRow+2];
This is problematic in standard C++ as the size of the array needs to be a constant, known at compile time. Since you plan to read these values from the file, you are using a variable-length array. Some compilers offer a non-standard extension to allow this, but other compilers will reject it. You may instead have to use the operator new to allocate space.

Beyond that, I've not checked the code in detail. It seems to be going roughly in the right direction, but looks quite inefficient in the way the initial pattern from the file is stored in the array, and not just because of the use of individual line variables.
thank you that helped!

I have rewrote most of the code but I keep getting these warnings.

bradler2@CF162-10:~/Desktop$ g++ test2.cpp
test2.cpp: In function ‘int main()’:
test2.cpp:268:16: warning: name lookup of ‘j’ changed [enabled by default]
test2.cpp:255:14: warning: matches this ‘j’ under ISO standard rules [enabled by default]
test2.cpp:258:13: warning: matches this ‘j’ under old rules [enabled by default]

here is the new code.

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

int main()
{
string lifename;

ifstream life;

cout << "Please enter the file you wish to use to play the game of life: ";
getline (cin, lifename);
life.open(lifename.c_str());

cout << "\n";

if (life.fail())
{
cout << "Your life file failed" << "\n";
}
else
{
cout << "Your life file has opened" << "\n";
}

cout << "\n";

// The file to use should now be open
//-------------------------------------------------------------------------------

string parameters;
getline(life, parameters);

string parameter1 = parameters.substr(0,2);
string parameter2 = parameters.substr(3,2);
string parameter3 = parameters.substr(6,2);
string parameter4 = parameters.substr(9,2);

char * Parameter1;
Parameter1 = new char [parameter1.size()];
strcpy (Parameter1, parameter1.c_str());

char * Parameter2;
Parameter2 = new char [parameter2.size()];
strcpy (Parameter2, parameter2.c_str());

char * Parameter3;
Parameter3 = new char [parameter3.size()];
strcpy (Parameter3, parameter3.c_str());

char * Parameter4;
Parameter4 = new char [parameter4.size()];
strcpy (Parameter4, parameter4.c_str());

//cout << Parameters;

//stores first line of text file then converst each parameter to a character array to use as integers
//-------------------------------------------------------------------------------

const int MaxCol = atoi(Parameter1);
const int MaxRow = atoi(Parameter2);
const int startCol = atoi(Parameter3);
const int startRow = atoi(Parameter4);

cout << "Your borad parameters are:" << "\n" <<MaxCol << "\n" << MaxRow << "\n" << startCol << "\n" << startRow << "\n";

char a[MaxCol][MaxRow], b[MaxCol][MaxRow];

for(int i=0; i<MaxCol; i++)
for(int j=0; j<MaxRow; j++)
a[i][j]=' ', b[i][j]=' ';

//builds and clears gameboard
//--------------------------------------------------------------------------------

string line1;
string line2;
string line3;
string line4;
string line5;
string line6;
string line7;
string line8;
string line9;
string line10;
string line11;
string line12;
string line13;
string line14;
string line15;
string line16;
string line17;
string line18;
string line19;

while(!life.eof())
{
getline (life, line1);
getline (life, line2);
getline (life, line3);
getline (life, line4);
getline (life, line5);
getline (life, line6);
getline (life, line7);
getline (life, line8);
getline (life, line9);
getline (life, line10);
getline (life, line11);
getline (life, line12);
getline (life, line13);
getline (life, line14);
getline (life, line15);
getline (life, line16);
getline (life, line17);
getline (life, line18);
getline (life, line19);
}

// stores lines of life file as strings to be used in gameboard
//------------------------------------------------------------------------------------

for(int i=0; i<line1.length(); i++)
{
if(line1.substr(i,1)=="*")
{
a[startCol+i][startRow] = '*';
}
else
{
a[startCol+i][startRow] = ' ';
}}

for(int i=0; i<line2.length(); i++)
{
if(line2.substr(i,1)=="*")
{
a[startCol+i][startRow+1] = '*';
}
else
{
a[startCol+i][startRow+1] = ' ';
}}

for(int i=0; i<line3.length(); i++)
{
if(line3.substr(i,1)=="*")
{
a[startCol+i][startRow+2] = '*';
}
else
{
a[startCol+i][startRow+2] = ' ';
}}

for(int i=0; i<line4.length(); i++)
{
if(line4.substr(i,1)=="*")
{
a[startCol+i][startRow+3] = '*';
}
else
{
a[startCol+i][startRow+3] = ' ';
}}

for(int i=0; i<line5.length(); i++)
{
if(line5.substr(i,1)=="*")
{
a[startCol+i][startRow+4] = '*';
}
else
{
a[startCol+i][startRow+4] = ' ';
}}

for(int i=0; i<line6.length(); i++)
{
if(line6.substr(i,1)=="*")
{
a[startCol+i][startRow+5] = '*';
}
else
{
a[startCol+i][startRow+5] = ' ';
}}

for(int i=0; i<line7.length(); i++)
{
if(line7.substr(i,1)=="*")
{
a[startCol+i][startRow+6] = '*';
}
else
{
a[startCol+i][startRow+6] = ' ';
}}

for(int i=0; i<line8.length(); i++)
{
if(line8.substr(i,1)=="*")
{
a[startCol+i][startRow+7] = '*';
}
else
{
a[startCol+i][startRow+7] = ' ';
}}

for(int i=0; i<line9.length(); i++)
{
if(line9.substr(i,1)=="*")
{
a[startCol+i][startRow+8] = '*';
}
else
{
a[startCol+i][startRow+8] = ' ';
}}

// builds game board with initial patern
//---------------------------------------------------------------------------------

for(int j=0; j<=MaxRow; j++)
{
for(int i=0; i<=MaxCol; i++)
cout << a[i][j];
cout << endl;
}

// displays initial game board
//---------------------------------------------------------------------------------
int Gens_to_run;

cout << "Enter number of generatiions to run" << "\n" ;
cin >> Gens_to_run;

int Gens_ran = 0;

int r = 0;

while (Gens_ran < Gens_to_run && r == 0)
{
for (int i = 0; i <= MaxCol; i++)
{
for (int j = 0; j <= MaxRow; j++)
{

for(int j=0; j <= MaxRow; j++)
{
for(int i=0; i <= MaxCol; i++)
cout << a[i][j];
cout << "\n";
}
// displays the current generation

int neighbors = 0;

if (a[i-1][j-1] == '*') neighbors += 1;
if (a[i-1][j] == '*') neighbors += 1;
if (a[i-1][j+1] == '*') neighbors += 1;
if (a[i][j-1] == '*') neighbors += 1;
if (a[i][j+1] == '*') neighbors += 1;
if (a[i+1][j-1] == '*') neighbors += 1;
if (a[i+1][j] == '*') neighbors += 1;
if (a[i+1][j+1] == '*') neighbors += 1;
//counts number of neighbors:
if (a[i][j] == '*' && neighbors < 2)
b[i][j] = ' ';
else if (a[i][j] == '*' && neighbors > 3)
b[i][j] = ' ';
else if (a[i][j] == '*' && (neighbors == 2 || neighbors == 3))
b[i][j] = '*';
else if (a[i][j] == ' ' && neighbors == 3)
b[i][j] = '*';
//store new generation in b array
}}

Gens_ran++;

cout << "Press the ENTER key to run next generation or anyother key to quit";

if (cin.get() == '\n')
{
cout << "\n";
for(int i=0; i<=MaxCol; i++)
for(int j=0; j<=MaxRow; j++)
a[i][j]=b[i][j];
//generation "b" becomes "a" generation
}
else
{
r = 1;
}
}

cout << "Your game of life is over" << "\n";

return 0;
}
kekoa18222987 wrote:
thank you that helped!

I'd like to think so.

But looking at the code, it still seems just as long-winded and excessively complex as before. I don't understand why you are using substrings and atoi() when you could just use cin to get the integers you need.

If you did that, 22 lines of complex code would reduce to a single line.

And the variables line1 to line19 - just use an array string line[20]; and be done with it.
The associated code where each line is processed will then be correspondingly shorter and simpler. Your 300+ lines of code would be much more concise, easy to read and consequently more likely to be bug-free.

As for the compiler warning messages, notice each message gives the corresponding line number so you should be able to track them down.
Because you haven't used the code formatting tags [code]your code here[/code] its difficult to identify the line numbers here. Please use the <> formatting button on the right.
Topic archived. No new replies allowed.