I am working on creating a Game of Life in C++ for my Data Structures course. I've been stuck on this for a few days and am officially stumped. I am having trouble with passing the values of my height and width variables between classes. In the FileParser class, the values print correctly (5,7), but when I pass and print those same values, they are both 0. Then when they are passed into main, they print (8,0). I’ve attempted multiple solutions but I am stumped. From looking at my code and around the internet there should not be a problem there? Also, if I uncomment line 41, I get a Segmentation fault after the first iteration of the for loop.
I apologize for the lengthy code it is just because the retrieval and passing of the values require multiple classes and functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
// MAIN
#include "UserIO.h"
#include "FileParser.h"
#include "ClassicMode.h"
#include <iostream>
using namespace std;
int main (int argc, char** argv)
{
// initialize new class instances
UserIO user;
user.Config();
cout << "test main 1" << endl; // delete later
ClassicMode cm;
int boundMode = user.BoundMode();
cout << "test main 2" << endl; // delete later
int height = user.h;
cout << "test main 3" << endl; // delete later
int width = user.w;
cout << height << " main height" << endl; // delete later
cout << width << " main width" << endl; // delete later
cout << "test main 4" << endl; // delete later
// Classic Mode
if (boundMode == 1)
{
// I can finish this function once this problem is resolved
cout<< "test main 5" <<endl; // delete later
// iterate through grid for r and c
for (int r = 0; r < height; r++)
{
for (int c = 0; c <= width; c++)
{
cout<<"test main 6" << " r: " << r << " c: " << c <<endl; // delete later
// cm.classicNeighbors(r, c, height, width);
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
// FILEPARSER CLASS
#include "FileParser.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
using namespace std;
// opens file from a pre-defined file path
// and checks if that file exists, if not it prompts user for a new file
void FileParser::openFile(string filePath)
{
inFile.open(filePath);
while (!inFile.is_open())
{
cout<<"File cannot be found, name a new file."<<endl;
string newPath;
cin>>newPath;
inFile.open(newPath);
}
}
// get an int from the file line
int FileParser::fpGetInt(string line)
{
int lineInt;
while (true)
{
try
{
lineInt = stoi(line);
break;
}
catch(invalid_argument& e)
{
cout<<"This input is invalid. Please enter an integer. fp1"<<endl;
}
break;
}
return lineInt;
}
// get the dimensions from the map file
void FileParser::findHW(string fileName)
{
inFile.open(fileName);
while (!inFile.is_open())
{
cout<<"File cannot be found, name a new file."<<endl;
string newPath;
cin>>newPath;
inFile.open(newPath);
}
string line;
cout<<"test fp 1"<<endl; // delete later
getline(inFile, line);
int rowInt = fpGetInt(line);
cout<<rowInt<<" rowInt fp "<<endl; // delete later
getline(inFile, line);
int colInt = fpGetInt(line);
cout<<colInt<<" colInt fp "<<endl; // delete later
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// USERIO CLASS
#include "UserIO.h"
#include "FileParser.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
using namespace std;
int UserIO::GetInt()
{
int xInt;
string x;
cin>>x;
if (cin.fail())
{
cin.clear();
cin.ignore(1000,'\n');
cout<<"This input is invalid. Please enter an integer. userIO 1"<<endl;
cin>>x;
}
while (true)
{
try
{
xInt = stoi(x);
break;
}
catch(invalid_argument& e)
{
cout<<"This input is invalid. Please enter an integer. userIO 2"<<endl;
}
break;
}
return xInt;
}
double UserIO::GetDouble()
{
double y;
cin>>y;
if (cin.fail())
{
cin.clear();
cin.ignore(1000,'\n');
cout<<"This input is invalid. Please enter a decimal value between 0 and 1."<<endl;
cin>>y;
}
return y;
}
void UserIO::Config()
{
while (true) // loops until a viable input is given
{
FileParser fp;
cout<<"Would you like to provide a file or use a random configuration?"<<endl;
cout<<"Enter '1' to enter a file path or '2' to use random configuration."<<endl;
int configChoice = GetInt();
double startPop;
if (configChoice == 1)
{
cout<<"Enter the path of the map file you would like to use: "<<endl;
string filePath;
cin>>filePath;
fp.findHW(filePath);
int h = fp.rowInt;
cout << h << " user IO height "<< endl; // delete later
int w = fp.colInt;
cout << h << " user IO width "<< endl; // delete later
break;
}
else if (configChoice == 2)
{
cout<<"What is the height (number of rows) of your world?"<<endl;
int h = GetInt();
cout << h << endl;
cout<<"What is the width (number of columns) of your world?"<<endl;
int w = GetInt();
cout << w << endl;
cout<<"Enter a decimal value between 0 and 1 for the initial population density of your world: "<<endl;
startPop = GetDouble();
while (true) // loops until viable input is given
{
if (startPop >0 && startPop<1)
{
cout<<"test userIO 1"<<endl; // delete later
break;
}
else
{
cout<<"This input is invalid."<<endl;
cout<<"Enter a decimal value between 0 and 1 for the initial population density of your world: "<<endl;
startPop = GetDouble();
}
}
break;
}
else
{
cout<<"This input is invalid."<<endl;
}
}
}
int UserIO::BoundMode()
{
int modeInt;
while(true)
{
cout<<"What boundary mode would you like to use?"<<endl;
cout<<"Enter '1' for Classic Mode, '2' for Doughnut Mode, or '3' for Mirror Mode."<<endl;
modeInt = GetInt();
// Check if input is valid
if (modeInt != 1 && modeInt != 2 && modeInt != 3)
{
cout<<"Invalid entry."<<endl;
}
else
{
cout<<modeInt<<endl;
break;
}
}
return modeInt;
}
|
The output is this:
Would you like to provide a file or use a random configuration?
Enter '1' to enter a file path or '2' to use random configuration.
1
Enter the path of the map file you would like to use:
mapfile.txt
test fp 1
5 rowInt fp
7 colInt fp
0 user IO height
0 user IO width
test main 1
What boundary mode would you like to use?
Enter '1' for Classic Mode, '2' for Doughnut Mode, or '3' for Mirror Mode.
1
1
test main 2
test main 3
9 main height
0 main width
test main 4
test main 5
test main 6 r: 0 c: 0
test main 6 r: 1 c: 0
test main 6 r: 2 c: 0
test main 6 r: 3 c: 0
test main 6 r: 4 c: 0
test main 6 r: 5 c: 0
test main 6 r: 6 c: 0
test main 6 r: 7 c: 0
test main 6 r: 8 c: 0
Any help would be appreciated!