Some more c++ stuff, add possible lr grammar (glr?)

This commit is contained in:
2022-01-01 19:00:55 -06:00
parent 6aba0d0227
commit c3b7cc58f0
3 changed files with 98 additions and 7 deletions

View File

@@ -8,7 +8,29 @@ Storybook::Storybook(FILE* fin) {
pages = CyoaParse(fin);
}
void Storybook::Find(const char* id) {
void Storybook::UpdateStat(const char *key, int rel) {
auto it = stats.find(key);
if (it == stats.end()) {
// Key not present
stats[key] = 0;
} else {
// Key present, add the rel
stats[key] = it->second + rel;
}
}
int Storybook::LookupStat(const char *key) {
auto it = stats.find(key);
if (it == stats.end()){
stats[key] = 0;
return 0;
} else {
return it->second;
}
return 0;
}
void Storybook::Find(const char *id) {
for (Page* page : pages) {
if (strcmp(page->id, id) == 0) {
current = page;
@@ -19,6 +41,41 @@ void Storybook::Find(const char* id) {
current = NULL;
}
void Storybook::Advance() {
// TODO throw an exception if the ending type is choices
switch(current->footer.type) {
case FooterType::End:
IsEnded = true;
current = NULL;
return;
case FooterType::Goto:
Find(current->footer.link);
return;
}
}
void Storybook::Advance(int choice_key) {
// TODO throw an exception if the ending type is not choices.
Choice* choice = (*current->footer.choices)[choice_key];
if (!choice) {
// TODO throw exception?
}
if (auto ck = choice->statcheck) {
int val = LookupStat(ck->stat);
if (ck->rel == STATCHECK_GT && val < ck->value ||
ck->rel == STATCHECK_LT && val > ck->value) {
// TODO throw different exception?
}
}
if (auto cg = choice->statchange) {
UpdateStat(cg->stat, cg->addend);
}
Find(choice->id);
}
void print_choice(Choice* c) {
printf("%d) %s", c->option, c->flavor);
if (c->statcheck) {
@@ -32,14 +89,15 @@ void print_choice(Choice* c) {
void Storybook::Play() {
printf(current->body);
Choice *choice;
switch (current->footer.type) {
case FooterType::End:
printf("The End.");
IsEnded = true;
Advance();
break;
case FooterType::Goto:
Find(current->footer.link);
Advance();
printf("Press ENTER to continue...");
std::cin.get();
break;
@@ -48,9 +106,9 @@ void Storybook::Play() {
print_choice(c.second);
}
printf("Make a selection: ");
int choice;
std::cin >> choice;
Find((*current->footer.choices)[choice]->id);
int choice_option;
std::cin >> choice_option;
Advance(choice_option);
break;
default:
IsEnded = true; // TODO

View File

@@ -2,18 +2,32 @@
#define STORYBOOK_H
#include <vector>
#include <unordered_map>
#include <string>
#include <cstdio>
#include "cyoa.h"
class Storybook {
private:
std::vector<Page*> pages;
std::unordered_map<const char*, int> stats;
Page *current;
public:
Storybook(FILE* fin);
// Functions for looking up and printing stats
void UpdateStat(const char*, int);
int LookupStat(const char*);
std::vector<std::string> GetDefinedStats();
// Functions to change the game state
void Find(const char*);
void Play();
void Advance(); // For Goto and End cases
void Advance(int); // For Choices
bool IsEnded = false;
// This will probably be moved to the cli driver
void Play();
};
#endif /* STORYBOOK_H */