#include #include #include class GameState { public: virtual ~GameState() = default; virtual void print() const = 0; virtual GameState* handle(std::string const& input) = 0; }; class GuessTheWord : public GameState { public: GuessTheWord(std::string const& answer) : GameState{}, answer{answer}, n{3} {} void print() const { std::cout << "Guess the word, attempt " << n << ": " << std::endl; } GameState* handle(std::string const& input) { if (input == answer) { std::cout << "Great input, you win!" << std::endl; return nullptr; } if (--n <= 0) { std::cout << "End of attempts, you loose!" << std::endl; return nullptr; } std::cout << "Keep trying!" << std::endl; return this; } private: std::string answer; int n; }; class Menu : public GameState { public: Menu(std::string const& name) : GameState{}, name{name} {} void print() const { std::cout << "Welcome to " << name << ", please select:\n" << "1 Play\n" << "2 Quit\n" << std::endl; } GameState* handle(std::string const& input) { if (input == "1") return new GuessTheWord{"Klas"}; else if (input == "2") return nullptr; else std::cerr << "Bad input, Please enter 1 or 2." << std::endl; return this; } private: std::string name; }; int main() { // Keep the current state at the top of a stack std::stack state_stack; // A menu should be active when we enter the game state_stack.push(new Menu{"The Game"}); // Keep runnig the game until all states are completed while ( ! state_stack.empty() ) { // Fetch the current active state GameState* active_state = state_stack.top(); // Let the active state instruct the user active_state->print(); std::string input{}; std::cin >> input; // Let the active state handle user input GameState* next{ active_state->handle(input) }; if (next == nullptr) { // If handle returns nullptr the active_state is completed and should cease it's existance, pop it delete active_state; state_stack.pop(); } else if (next != active_state) { // If handle returns a new state wh should complete that before this one, push it to the stack state_stack.push(next); } else if (next == active_state) { // If handle returns pointer to its own state object, keep running that state, do nothing } } return 0; }