#include #include #include #include #include #include "game_engine.hpp" #include const auto ERROR = fmt::emphasis::bold | fg(fmt::color::red); using namespace fmt; using namespace std; GameEngine::GameEngine(int hp) : starting_hp(hp) { hit_points = starting_hp; }; int GameEngine::determine_damage(string &type) { try { return damage_types.at(type); } catch(std::out_of_range &err) { print(ERROR, "BAD DAMAGE TYPE {}\n", type); return 0; } } void GameEngine::reset() { streak = 0; hit_points = starting_hp; } bool GameEngine::hit(string &type) { int damage = determine_damage(type); hit_points -= damage; ++hits_taken; return is_dead(); } void GameEngine::heal() { hit_points = hit_points * 1.10; if(hit_points > 100) hit_points = 100; } bool GameEngine::is_dead() { return hit_points <= 0; } void GameEngine::start(GameEvent ev) { state(GameState::IDLE); idle(ev); } void GameEngine::idle(GameEvent ev) { if(ev == GameEvent::BUILD_START) { hits_taken = 0; state(GameState::IN_ROUND); } else { state(GameState::IDLE); } } void GameEngine::in_round(GameEvent ev, string &hit_type) { switch(ev) { case GameEvent::HIT: hit(hit_type); if(is_dead()) { state(GameState::DEAD); } else { state(GameState::IN_ROUND); } break; case GameEvent::BUILD_SUCCESS: state(GameState::SUCCESS); break; case GameEvent::BUILD_FAILED: state(GameState::FAILURE); break; default: state(GameState::IN_ROUND); } } void GameEngine::dead(GameEvent ev) { if(ev == GameEvent::BUILD_DONE) { reset(); state(GameState::FAILURE); failure(ev); } else if(ev == GameEvent::HIT) { ++hits_taken; } else { state(GameState::DEAD); } } void GameEngine::success(GameEvent ev) { assert(ev == GameEvent::BUILD_DONE && "success state expected BUILD_DONE"); ++rounds; ++streak; heal(); state(GameState::IDLE); } void GameEngine::failure(GameEvent ev) { assert(ev == GameEvent::BUILD_DONE && "failure state expected BUILD_DONE"); ++rounds; streak = 0; state(GameState::IDLE); }