Some more c++ stuff, add possible lr grammar (glr?)
This commit is contained in:
parent
6aba0d0227
commit
c3b7cc58f0
19
spec.txt
19
spec.txt
@ -38,6 +38,18 @@ BlankLine <- Spacing Newline
|
|||||||
Spacing <- (' ' / '\t')*
|
Spacing <- (' ' / '\t')*
|
||||||
Newline <- '\r\n' / '\r' / '\n'
|
Newline <- '\r\n' / '\r' / '\n'
|
||||||
|
|
||||||
|
Story language CFG:
|
||||||
|
|
||||||
|
story : pages <<EOF>>
|
||||||
|
pages : pages page | <<EPSILON>>
|
||||||
|
page : ID FREETEXT footer
|
||||||
|
footer : "THE END" | "GOTO" ID | choices
|
||||||
|
choices : choices choice | choice
|
||||||
|
choice : INT ')' FREETEXT maybe-skillcheck redirect maybe-skillchange
|
||||||
|
redirect : '[' ID ']'
|
||||||
|
maybe-skillcheck : '<' SKILL INT op '>' | <<EPSILON>>
|
||||||
|
maybe-skillchange: '(' op INT SKILL ') | <<EPSILON>>
|
||||||
|
|
||||||
Work log:
|
Work log:
|
||||||
|
|
||||||
12/13/21
|
12/13/21
|
||||||
@ -77,3 +89,10 @@ of a bust. The project was very deep, very academic and hard to pick up, especia
|
|||||||
I'll just keep chugging with what I've got.
|
I'll just keep chugging with what I've got.
|
||||||
|
|
||||||
Next up is integrating with Godot for real this time. For real. This time...
|
Next up is integrating with Godot for real this time. For real. This time...
|
||||||
|
|
||||||
|
1/1/22
|
||||||
|
|
||||||
|
I'm getting pretty frustrated with what I perceive to be bugs in the peg/leg parser. The project seems abandoned and
|
||||||
|
I don't really feel like maintaining it. And GNU Bison is like right there. If I can write a cfg for my little language
|
||||||
|
here I'll switch. I also can't shake the feeling that this is over-engineered, and I really don't need a parser for all this, but
|
||||||
|
oh well. I could probably do it all with just lex actually. Maybe I need to spend some time rethinking this.
|
||||||
|
@ -8,7 +8,29 @@ Storybook::Storybook(FILE* fin) {
|
|||||||
pages = CyoaParse(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) {
|
for (Page* page : pages) {
|
||||||
if (strcmp(page->id, id) == 0) {
|
if (strcmp(page->id, id) == 0) {
|
||||||
current = page;
|
current = page;
|
||||||
@ -19,6 +41,41 @@ void Storybook::Find(const char* id) {
|
|||||||
current = NULL;
|
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) {
|
void print_choice(Choice* c) {
|
||||||
printf("%d) %s", c->option, c->flavor);
|
printf("%d) %s", c->option, c->flavor);
|
||||||
if (c->statcheck) {
|
if (c->statcheck) {
|
||||||
@ -32,14 +89,15 @@ void print_choice(Choice* c) {
|
|||||||
|
|
||||||
void Storybook::Play() {
|
void Storybook::Play() {
|
||||||
printf(current->body);
|
printf(current->body);
|
||||||
|
Choice *choice;
|
||||||
|
|
||||||
switch (current->footer.type) {
|
switch (current->footer.type) {
|
||||||
case FooterType::End:
|
case FooterType::End:
|
||||||
printf("The End.");
|
printf("The End.");
|
||||||
IsEnded = true;
|
Advance();
|
||||||
break;
|
break;
|
||||||
case FooterType::Goto:
|
case FooterType::Goto:
|
||||||
Find(current->footer.link);
|
Advance();
|
||||||
printf("Press ENTER to continue...");
|
printf("Press ENTER to continue...");
|
||||||
std::cin.get();
|
std::cin.get();
|
||||||
break;
|
break;
|
||||||
@ -48,9 +106,9 @@ void Storybook::Play() {
|
|||||||
print_choice(c.second);
|
print_choice(c.second);
|
||||||
}
|
}
|
||||||
printf("Make a selection: ");
|
printf("Make a selection: ");
|
||||||
int choice;
|
int choice_option;
|
||||||
std::cin >> choice;
|
std::cin >> choice_option;
|
||||||
Find((*current->footer.choices)[choice]->id);
|
Advance(choice_option);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
IsEnded = true; // TODO
|
IsEnded = true; // TODO
|
||||||
|
@ -2,18 +2,32 @@
|
|||||||
#define STORYBOOK_H
|
#define STORYBOOK_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "cyoa.h"
|
#include "cyoa.h"
|
||||||
|
|
||||||
class Storybook {
|
class Storybook {
|
||||||
private:
|
private:
|
||||||
std::vector<Page*> pages;
|
std::vector<Page*> pages;
|
||||||
|
std::unordered_map<const char*, int> stats;
|
||||||
Page *current;
|
Page *current;
|
||||||
public:
|
public:
|
||||||
Storybook(FILE* fin);
|
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 Find(const char*);
|
||||||
void Play();
|
void Advance(); // For Goto and End cases
|
||||||
|
void Advance(int); // For Choices
|
||||||
bool IsEnded = false;
|
bool IsEnded = false;
|
||||||
|
|
||||||
|
// This will probably be moved to the cli driver
|
||||||
|
void Play();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* STORYBOOK_H */
|
#endif /* STORYBOOK_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user