/*
Forum: https://forum.arduino.cc/t/rpg-game-buttons-not-working-progressing-through-story/1199123
Wokwi: https://wokwi.com/projects/383817981120307201
*/
#include <LiquidCrystal.h>
// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
constexpr byte button1Pin = 8; // Button 1 pin
constexpr byte button2Pin = 9; // Button 2 pin
constexpr byte button3Pin = 10; // Button 3 pin
int state = 0; // Track the story progress
struct buttonType {
byte pin;
byte state = HIGH;
byte lastState = HIGH;
unsigned long lastChange = 0;
void init(byte aPin) {
pin = aPin;
pinMode(pin, INPUT_PULLUP);
}
boolean released() {
byte actState = digitalRead(pin);
if (actState != lastState) {
lastChange = millis();
lastState = actState;
}
if (state != actState && millis() - lastChange >= 50) {
state = actState;
return state;
}
return false;
}
};
buttonType button1, button2, button3;
void setup() {
Serial.begin(9600);
button1.init(button1Pin);
button2.init(button2Pin);
button3.init(button3Pin);
lcd.begin(16, 2); // set up the LCD's number of columns and rows:
showStory("Lost Treasure of", "Eldorado. Begin?");
}
void loop() {
if (button1.released()) {
progressStoryNew(1);
}
if (button2.released()) {
progressStoryNew(2);
}
if (button3.released()) {
progressStoryNew(3);
}
}
void progressStoryNew(int choice) {
switch (state) {
case 0 :
onChoiceDo(choice, 1,"You're in a jungle", "Which path?", 1);
break;
case 1 :
onChoiceDo(choice, 1,"Path leads to cave", "Find a map!", 2);
onChoiceDo(choice, 2,"Climb a tree and", "spot a village", 3);
onStateNotChanged(1,"Cross a river", "Discover a clue",4);
break;
case 2 :
onChoiceDo(choice, 1,"Map shows a path", "to hidden city", 5);
break;
case 3 :
onChoiceDo(choice, 1,"Village elder gives", "a golden key", 5);
break;
case 4 :
onChoiceDo(choice, 1,"Clue leads to a", "mysterious cave", 5);
break;
case 5 :
onChoiceDo(choice, 1,"You find Eldorado", "Treasure is yours!", 6);
onChoiceDo(choice, 2,"You decide to explore", "the hidden city further", 7);
onStateNotChanged(5,"You follow another clue", "What do you find?",10);
case 6 :
onChoiceDo(choice, 1,"Adventure ends", "Play again?", 0);
break;
case 7 :
onChoiceDo(choice, 1,"You discover a", "secret chamber", 8);
onChoiceDo(choice, 2,"You encounter a", "mysterious figure", 9);
break;
case 8 :
onChoiceDo(choice, 1,"Inside the chamber,", "you find ancient artifacts", 9);
onStateNotChanged(8,"You leave the chamber", "What's your next move?",10);
break;
case 9 :
onChoiceDo(choice, 1,"The figure reveals", "a hidden power", 10);
onStateNotChanged(9,"You try to escape", "but the figure blocks your way",11);
break;
case 10 :
onChoiceDo(choice, 1,"Congratulations!", "You are a legendary explorer!",11);
break;
case 11:
onChoiceDo(choice, 1,"The mysterious figure", "becomes your ally",12);
break;
case 12 :
onChoiceDo(choice, 1,"Together, you uncover", "even greater mysteries",13);
break;
case 13 :
onChoiceDo(choice, 1,"Your legend grows,", "and your adventures continue!",14);
break;
case 14 :
onChoiceDo(choice, 1,"Thanks for playing!", "Would you like to play again?",0);
break;
}
}
/*
This function checks whether "actChoice" is equal to the accepted choice (1,2 or 3) and
- if yes - displays the text and changes the state to newState
*/
void onChoiceDo(int actChoice, int acceptedChoice,char * upperLine, char * lowerLine, int newState){
if (actChoice == acceptedChoice) {
showStory(upperLine, lowerLine);
state = newState;
}
}
/*
This function is used after all possible choices have been handled:
thisState should have the value of the current state. If a choice has already changed
the value of "state" it will not influence the program flow. If state is still the same
as entered in "thisState" the if condition will become true ...
*/
void onStateNotChanged(int thisState,char * upperLine, char * lowerLine, int newState){
if (state == thisState) {
showStory(upperLine, lowerLine);
state = newState;
}
}
void showStory(char * line1, char * line2) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line1);
lcd.setCursor(0, 1);
lcd.print(line2);
}