It does get a bit difficult at times. The important thing is to break it up into plenty of functions, I use Dev Bloodshed C++ as my compiler, and it (like I suspect most if not all compilers) has an option to show classes, functions, and global variables. This feature I mostly use for functions, since with a single double click on the function name, it takes me where ever in the code I want to go. Also, liberal use of comments is always a plus, even if the code's function is completely obvious.
Oh, and a fun little tidbit in case you didn't know: in addition to system("pause"); you can use the other system commands available to the command prompt. system("color 0c"); is one I find particularly useful for warning the player if something bad is happening/about to happen (system("color"); will reset it to default). For other color combinations, type "help color" into your command prompt.
Here's my WIP sci-fi game... although at the moment its more of a generic text RPG game engine. I am fairly sure most of my includes are un-needed, but oh well... The apmatrix.h is hooked up to 3 other files I DLed, apmatrix.cpp apvector.cpp apvector.h, all 4 of which have been slightly modified (so I could add in a couple extra functions to apmatrix, namely an eraseRow and eraseCol function. The itemvector header file contains my itemvector class, which is essentially a class based version of the parallel vectors (and matricies) used for the area system. Both the itemvector and the area data stuff do more or less the same things, just different methodologies due to items needing to be rearanged, added, and deleted frequently.
//includes
#include <iostream>
#include <vector>
#include <string>
#include "apmatrix.h"
#include <fstream>
#include <iomanip>
#include "itemclass.h"
//namespace
using namespace std;
void redAlert(); //function declarations
void loggin();
int playerInput();
void loadProfile();
void loadDef();
void move();
void directionInput(char dInput);
void statusInfo();
void areaData();
void saveProfile();
void displayInventory();
int p_new_location; //player variables
vector<int> p_a_contents;
vector<int> p_a_connections;
vector<char> p_a_directions;
int p_a_location;
string p_a_description;
int p_health;
string p_name;
vector<int> a_locations; //world variables
vector<string> a_descriptions;
apmatrix<int> a_contents(5,5,0);
apmatrix<int> a_connections(5,5,0);
apmatrix<char> a_directions(5,5,0);
itemvector p_inventory;
itemvector WorldItemList;
//main function
int main()
{
areaData(); //load in world area data
WorldItemList.loadFromFile();
loggin(); //load/create character
//game loop
while(true)
{
statusInfo(); //displays vital info after every loop
playerInput(); //input
}
return 0;
}
//Red Alert function
void redAlert()
{
cout<<"ENTERING RED ALERT STATUS, ALL PERSONNEL REPORT TO STATIONS"<<endl;
system("color 0c");
}
//login function, retrieves data from previous games
void loggin()
{
bool tf=true;
while (tf)
{
cout<<"Please enter username, type 'new' if you do not have a character: "<<endl;
cin>>p_name;
if(p_name!="new")
{
ifstream fin(("profiles\\"+p_name+".txt").c_str());
if (fin.good())
{
fin.close();
loadProfile(); //load from txt file
tf=false;
}
else
{
cout<<"Username not found."<<endl;
}
}
if (p_name=="new")
{
loadDef(); //use default values
tf=false;
}
}
}
//input handling function
int playerInput()
{
string input;
cin>>input;
if (input=="w"||input=="e"||input=="n"||input=="s"||input=="east"||input=="west"||input=="north"||input=="south")
{
char dInput;
if (input=="w"||input=="west")
{
dInput='w';
}
if (input=="e"||input=="east")
{
dInput='e';
}
if (input=="n"||input=="north")
{
dInput='n';
}
if (input=="s"||input=="south")
{
dInput='s';
}
directionInput(dInput);
}
if (input=="inventory")
{
displayInventory();
}
}
//load profile from default (starting) values
void loadDef()
{
cout<<"Welcome, new player, please enter a name. Note: entering the same name as a pre-existing profile will erase that profile!"<<endl;
cin>>p_name;
cout<<"Welcome, "<<p_name<<endl;
p_health=100;
p_new_location=1;
move();
saveProfile();
}
//deals with player movement
void move()
{
int x = 0;
while (a_locations[x]!= p_new_location) //find x position of new location in world structure
{
x++;
}
p_a_contents.clear(); //clear old player area variables
p_a_connections.clear();
p_a_directions.clear();
p_a_location=p_new_location; //assign new location variable
p_a_description = a_descriptions[x]; //assign new area description
int y = 0;
while (a_contents[x][y]) //assign new contents
{
p_a_contents.push_back(a_contents[x][y]);
y++;
}
y=0;
while(a_connections[x][y] != 0) //assign new connections
{
p_a_connections.push_back(a_connections[x][y]);
y++;
}
y=0;
while(a_directions[x][y] != '0') //asign new directions
{
p_a_directions.push_back(a_directions[x][y]);
y++;
}
cout<<p_a_description<<endl; //show area description
return;
}
//process direction input to ensure valid movement
void directionInput(char dInput)
{
int size= p_a_directions.size();
int i = 0;
while (i<size && dInput != p_a_directions[i])
{
i++;
if (i==size)
{
cout<<"Invalid movement"<<endl; //failsafe to prevent invalid movement entry from causing vector problems
return;
}
}
p_new_location=p_a_connections[i];
move();
return;
}
//displays information about player and area after every game loop
void statusInfo()
{
string exits=""; //display possible movements
int i=0;
cout<<"exits: ";
while (i < p_a_directions.size())
{
exits=p_a_directions[i];
i++;
cout<<exits;
if (i < p_a_directions.size())
{
cout<<", ";
}
}
cout<<". health:"<<p_health<<". Input: "; //display health and prompt for input
return;
}
//saves player profiles
//will need updating as more variables come into play, specifically inventories and ship data
void saveProfile()
{
ofstream fout(("profiles\\"+p_name+".txt").c_str());
fout<<p_name<<endl;
fout<<p_a_location<<endl;
fout<<p_health<<endl;
fout.close();
}
//loads preexisting profiles from text files in profile fold in directory
void loadProfile()
{
ifstream fin(("profiles\\"+p_name+".txt").c_str());
fin>>p_name;
fin>>p_new_location;
fin>>p_health;
move();
}
//display items in player's inventory
void displayInventory()
{
int iter=0;
while(p_inventory.vectorSize()>iter)
{
cout<<p_inventory.itemName(iter)<<endl;
iter++;
}
}
//transfer item from world list to other itemvector
void itemvector::createItem(string itemName)
{
int iter=0;
bool solution=false;
while (WorldItemList.name.size()>iter+1)
{
if(WorldItemList.name[iter]==itemName)
{
solution=true;
break;
}
iter++;
}
if(solution==false)
{
cout<<"Error: Item not found!"<<endl;
}
else
{
name.push_back(itemName);
id.push_back(WorldItemList.id[iter]);
type.push_back(WorldItemList.type[iter]);
description.push_back(WorldItemList.description[iter]);
int rows=use.numrows();
int cols=use.numcols();
use.resize(rows+1,cols);
if(WorldItemList.use.numcols()>use.numcols())
{
use.resize(rows+1,WorldItemList.use.numcols());
}
int y=0;
while(y<WorldItemList.use.numcols())
{
use[name.size()-1][y]=WorldItemList.use[iter][y];
y++;
}
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//----------------------Area data--------------------------------------------
//---------------------------------------------------------------------------
//-------------Feeds data into world variables-------------------------------
//---------------------------------------------------------------------------
//-a_locations--a_descriptions--a_contents--a_connections--a_directions------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void areaData()
{
int locationId=0; //variable declarations
string description;
int count=0;
int contentId;
int endone=0;
int xSize=10;
int ySize=5;
int zSize=5;
int xPosition=0;
int iter=0;
a_connections.resize(xSize, ySize); //initial sizing of matrices
a_directions.resize(xSize, ySize);
a_contents.resize(xSize, zSize);
ifstream fin("area.txt"); //initialize file input
if(fin.good() != 1)
{
cout<<"Error opening world data."<<endl;
return;
}
while (fin.eof()==false)
{
fin>>locationId;
fin.ignore();
getline(fin, description);
fin>>count;
if((ySize-2) < count)
{
ySize += 5; //ensure matrices are large enough, essentially the same as push_back
a_connections.resize(xSize,ySize);
a_directions.resize(xSize,ySize);
}
iter = 0;
while(iter<count)
{
fin>>a_connections[xPosition][iter]; //store connectionIDs
iter++;
}
iter = 0;
while(iter<count)
{
fin>>a_directions[xPosition][iter]; //store movements possible
iter++;
}
a_directions[xPosition][iter]='0';
fin>>count;
if (zSize-2<count)
{
zSize += 4;
a_contents.resize(xSize, zSize); //ensure matrix is large enough
}
iter=0;
while(iter<count)
{
fin>>a_contents[xPosition][iter]; //store things in area
iter++;
}
a_contents[xPosition][iter]=0;
if(xSize-2 < xPosition)
{
xSize = 5 + xSize;
a_connections.resize(xSize,ySize);
a_directions.resize(xSize,ySize);
}
a_locations.push_back(locationId);
a_descriptions.push_back(description);
xPosition++;
fin.ignore();
}
a_locations.push_back(0);
return;
}