#include <iostream>
#include <vector>
#include <stdlib.h>
#include <string>
#include <fstream>
#define EE <<endl<<
using namespace std;
/*******************************************************************************
.txtquest file format:
First Menu Title
First Menu Question
First Menu Option1
First Menu Destination1
First Menu Option2
First Menu Destination2
...
~~~~...~~~~ (however many you want, as long as the line starts w/ a ~ it works)
Next Menu Title
Next Menu Question
Next Menu Option1
Next Menu Destination1
...
...
~~~~...~~~~
Last Menu Title
Last Menu Question
Last Menu Option1
Last Menu Destination1
...
----...---- (same as with ~)
*******************************************************************************/
void help()
{
cout<<"GTBA [file name].txtquest\n\tRuns a txtquest!"<<endl;
cout<<
"First Menu Title"EE
"First Menu Question"EE
"First Menu Option1"EE
"First Menu Destination1"EE
"First Menu Option2"EE
"First Menu Destination2"EE
"..."EE
"~... (Any line starting with a ~)"EE
"Next Menu Title"EE
"Next Menu Question"EE
"Next Menu Option1"EE
"Next Menu Destination1"EE
"..."EE
"~..."EE
"Last Menu Title (Not displayed)"EE
"-... (Any line starting with a -)";
}
struct q
{
string title;
string question;
vector<string> answers;
vector<string> locations;
};
class GameMap
{
private:
vector<q> qs;
string final;
string init;
vector<q> mergesort(vector<q> s)
{
if (s.size()<=1)
return s;
vector<q> left;
vector<q> right;
int mid=s.size()/2;
for (int i=0; i<s.size(); ++i)
{
if (i<mid)
left.push_back(s[i]);
else
right.push_back(s[i]);
}
left=mergesort(left);
right=mergesort(right);
return merge(left,right);
}
vector<q> merge(vector<q> a, vector<q> b)
{
vector<q> ret;
while (a.size()>0||b.size()>0)
{
if (a.size()>0&&b.size()>0)
{
if (a.front().title<=b.front().title)
{
ret.push_back(a.front());
a.erase(a.begin());
}
else
{
ret.push_back(b.front());
b.erase(b.begin());
}
}
else if (a.size()>0)
{
ret.push_back(a.front());
a.erase(a.begin());
}
else if (b.size()>0)
{
ret.push_back(b.front());
b.erase(b.begin());
}
}
return ret;
}
q BinarySearchQS(string str)
{
int max=qs.size();
int min=0;
while (min<max)
{
int mid=(max+min)/2;
if (qs[mid].title<str)
{
min=mid+1;
}
else if (qs[mid].title>str)
{
max=mid-1;
}
else
{
return qs[mid];
}
}
return qs[min];
}
public:
GameMap(string fname)
{
fstream file(fname.c_str());
if (!file.is_open())
{
cout<<"Unable to open file..."<<endl;
exit(1);
}
cout<<".";
qs=vector<q>();
string tmps;
q tmpq;
bool good=true;
init="";
cout<<"...";
while (good)
{
getline(file,tmps);
tmpq.title=tmps;
if (init=="")
init=tmps;
getline(file,tmps);
tmpq.question=tmps;
while (true)
{
getline(file,tmps);
if (tmps[0]=='~')
{
break;
}
else if (tmps[0]=='-')
{
good=false;
final=tmpq.title;
break;
}
tmpq.answers.push_back(tmps);
getline(file,tmps);
tmpq.locations.push_back(tmps);
}
qs.push_back(tmpq);
tmpq.answers.clear();
tmpq.locations.clear();
}
cout<<"..";
qs=mergesort(qs);
cout<<"..."<<endl<<endl;
}
void playGame()
{
q current=BinarySearchQS(init);
while (current.title!=final)
{
cout<<current.question<<endl;
for (int i=0; i<current.answers.size(); ++i)
cout<<i+1<<") "<<current.answers[i]<<endl;
int sel;
do{
cin>>sel;
}while(sel<1||sel>current.answers.size());
string tmp;
tmp=current.locations[sel-1];
current=BinarySearchQS(tmp);
}
}
};
int main(int argc, char *argv[])
{
if (argc!=2)
{
help();
return 1;
}
GameMap gm(argv[1]);
gm.playGame();
return 0;
}