Skip to main content
Code Review

Return to Answer

Commonmark migration
Source Link

###Data file

Data file

###Code

Code

###Data file

###Code

Data file

Code

struct Choice {
 std::string text;
 std::string target;
}
struct Encounter {
 std::string tag;
 std::string message;
 std::vector<Choice> choices;
}
std::string ReadFile(const std::string& filename) {
 /** check online resources */
}
Encounter ParseEncounter(const std::string& text) { ... }
std::map<std::string,Encounter> ParseEncounters(const std::string& text) {
 std::map<std::string,Encounter> encounters;
 size_t pos = 0;
 while(true) {
 // find next [
 size_t next = text.find("[");
 if(next == std::string::npos) break;
 // get the encounter text
 std::string enc_str = text.substr(pos,next);
 // parse encounter
 Encounter enc = ParseEncounter(enc_str);
 // store encounter
 encounters[enc.tag] = enc;
 // next 
 pos = next;
 }
 return encounters;
}
std::string RunEncounter(const std::map<std::string,Encounter>& encounters, const std::string& tag) {
 system("cls");
 // get encounter
 Encounter node = encounters[tag];
 // print message and choices
 std::cout << node.message << std::endl;
 for(size_t i=0; i<node.choices.size(); i++) {
 std::cout << i << ". " << node.choices[i].text << std::endl;
 }
 // get correct choice from user
 int choice = -1;
 while(!(0 <= choice && choice < node.choices.size())) {
 std::cin >> choice;
 }
 cin.ignore();
 // return choice tag
 return node.choices[choice].target;
}
int main() {
 std::string str = ParseFileReadFile("adventure.txt");
 std::map<std::string,Encounter> encounters = ParseEncounters(str);
 std::string tag = "road";
 while(tag != "endofgame") {
 tag = RunEncounter(tag);
 }
}
struct Choice {
 std::string text;
 std::string target;
}
struct Encounter {
 std::string tag;
 std::string message;
 std::vector<Choice> choices;
}
std::string ReadFile(const std::string& filename) {
 /** check online resources */
}
Encounter ParseEncounter(const std::string& text) { ... }
std::map<std::string,Encounter> ParseEncounters(const std::string& text) {
 std::map<std::string,Encounter> encounters;
 size_t pos = 0;
 while(true) {
 // find next [
 size_t next = text.find("[");
 if(next == std::string::npos) break;
 // get the encounter text
 std::string enc_str = text.substr(pos,next);
 // parse encounter
 Encounter enc = ParseEncounter(enc_str);
 // store encounter
 encounters[enc.tag] = enc;
 // next 
 pos = next;
 }
 return encounters;
}
std::string RunEncounter(const std::map<std::string,Encounter>& encounters, const std::string& tag) {
 system("cls");
 // get encounter
 Encounter node = encounters[tag];
 // print message and choices
 std::cout << node.message << std::endl;
 for(size_t i=0; i<node.choices.size(); i++) {
 std::cout << i << ". " << node.choices[i].text << std::endl;
 }
 // get correct choice from user
 int choice = -1;
 while(!(0 <= choice && choice < node.choices.size())) {
 std::cin >> choice;
 }
 cin.ignore();
 // return choice tag
 return node.choices[choice].target;
}
int main() {
 std::string str = ParseFile("adventure.txt");
 std::map<std::string,Encounter> encounters = ParseEncounters(str);
 std::string tag = "road";
 while(tag != "endofgame") {
 tag = RunEncounter(tag);
 }
}
struct Choice {
 std::string text;
 std::string target;
}
struct Encounter {
 std::string tag;
 std::string message;
 std::vector<Choice> choices;
}
std::string ReadFile(const std::string& filename) {
 /** check online resources */
}
Encounter ParseEncounter(const std::string& text) { ... }
std::map<std::string,Encounter> ParseEncounters(const std::string& text) {
 std::map<std::string,Encounter> encounters;
 size_t pos = 0;
 while(true) {
 // find next [
 size_t next = text.find("[");
 if(next == std::string::npos) break;
 // get the encounter text
 std::string enc_str = text.substr(pos,next);
 // parse encounter
 Encounter enc = ParseEncounter(enc_str);
 // store encounter
 encounters[enc.tag] = enc;
 // next 
 pos = next;
 }
 return encounters;
}
std::string RunEncounter(const std::map<std::string,Encounter>& encounters, const std::string& tag) {
 system("cls");
 // get encounter
 Encounter node = encounters[tag];
 // print message and choices
 std::cout << node.message << std::endl;
 for(size_t i=0; i<node.choices.size(); i++) {
 std::cout << i << ". " << node.choices[i].text << std::endl;
 }
 // get correct choice from user
 int choice = -1;
 while(!(0 <= choice && choice < node.choices.size())) {
 std::cin >> choice;
 }
 cin.ignore();
 // return choice tag
 return node.choices[choice].target;
}
int main() {
 std::string str = ReadFile("adventure.txt");
 std::map<std::string,Encounter> encounters = ParseEncounters(str);
 std::string tag = "road";
 while(tag != "endofgame") {
 tag = RunEncounter(tag);
 }
}
Post Merged (destination) from codereview.stackexchange.com/questions/49846/…
Post Migrated Here from stackoverflow.com (revisions)
Source Link
Danvil
Danvil

Your code does a very poor job in separating code from data. I would suggest you split your projects into two parts: a data file to define your adventure and code which parses the data file and lets you play the game.

The following is a suggestion how it might work. You can come up with your own more sophisticated "grammar" for the data file. There are also tools around to do the parsing for your, but as this project is for learning, I would suggest your write your own parsing code.

If you want some custom code to run, like doing a fight or rolling a random choice, you can also add that to your grammar and link tags to functions you want to execute (for example using if statements to select the correct piece of code).

Have fun!


###Data file

A normal text file, e.g. "the_dragon_tale.txt", which has all your text messages and the possible choices. The text file is annotated to indicate the program flow.

Example:

[road]
You are on a road that heads west and east of your position.
Which way will you go?
#west Go West
#east Go East
#roadwait Wait for something to happen
[west]
A spider!!
#fightspider
[east]
A dragon!
#endofgame
[roadwait]
Very boring.
#road

###Code

Your program now looks completely different. First write a function which reads and parses your adventure text file. For each [tag] section it creates an instances of a class and links and the possible choices marked by the # sections.

Example:

struct Choice {
 std::string text;
 std::string target;
}
struct Encounter {
 std::string tag;
 std::string message;
 std::vector<Choice> choices;
}
std::string ReadFile(const std::string& filename) {
 /** check online resources */
}
Encounter ParseEncounter(const std::string& text) { ... }
std::map<std::string,Encounter> ParseEncounters(const std::string& text) {
 std::map<std::string,Encounter> encounters;
 size_t pos = 0;
 while(true) {
 // find next [
 size_t next = text.find("[");
 if(next == std::string::npos) break;
 // get the encounter text
 std::string enc_str = text.substr(pos,next);
 // parse encounter
 Encounter enc = ParseEncounter(enc_str);
 // store encounter
 encounters[enc.tag] = enc;
 // next 
 pos = next;
 }
 return encounters;
}
std::string RunEncounter(const std::map<std::string,Encounter>& encounters, const std::string& tag) {
 system("cls");
 // get encounter
 Encounter node = encounters[tag];
 // print message and choices
 std::cout << node.message << std::endl;
 for(size_t i=0; i<node.choices.size(); i++) {
 std::cout << i << ". " << node.choices[i].text << std::endl;
 }
 // get correct choice from user
 int choice = -1;
 while(!(0 <= choice && choice < node.choices.size())) {
 std::cin >> choice;
 }
 cin.ignore();
 // return choice tag
 return node.choices[choice].target;
}
int main() {
 std::string str = ParseFile("adventure.txt");
 std::map<std::string,Encounter> encounters = ParseEncounters(str);
 std::string tag = "road";
 while(tag != "endofgame") {
 tag = RunEncounter(tag);
 }
}
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /