The game engine now has two bonuses for long build streaks. +10% max hp or 1 free death. I'll be adding more but that's enough to work on the real UI.

master
Zed A. Shaw 3 weeks ago
parent 07553400f5
commit 0a9fa59365
  1. 43
      game_engine.cpp
  2. 8
      game_engine.hpp
  3. 39
      tests/game_engine.cpp

@ -12,7 +12,7 @@ using namespace fmt;
using namespace std; using namespace std;
GameEngine::GameEngine(int hp) : starting_hp(hp) { GameEngine::GameEngine(int hp) : starting_hp(hp) {
hit_points = starting_hp; hit_points = max_hp();
}; };
int GameEngine::determine_damage(string &type) { int GameEngine::determine_damage(string &type) {
@ -25,8 +25,17 @@ int GameEngine::determine_damage(string &type) {
} }
void GameEngine::reset() { void GameEngine::reset() {
streak = 0; println("!!!!!!! RESET hit_points={}, max={}", hit_points, max_hp());
hit_points = starting_hp; if(free_death) {
hit_points = max_hp() * 0.5f;
} else {
streak = 0;
hit_points = max_hp();
}
println("!!!!!!!! AFTER RESET hit_points={}, max={}", hit_points, max_hp());
free_death = false;
} }
bool GameEngine::hit(string &type) { bool GameEngine::hit(string &type) {
@ -37,12 +46,12 @@ bool GameEngine::hit(string &type) {
} }
void GameEngine::heal() { void GameEngine::heal() {
hit_points = hit_points * 1.10; hit_points = hit_points * 1.10f;
if(hit_points > 100) hit_points = 100; if(hit_points > max_hp()) hit_points = max_hp();
} }
bool GameEngine::is_dead() { bool GameEngine::is_dead() {
return hit_points <= 0; return free_death ? false : hit_points <= 0;
} }
void GameEngine::start(GameEvent ev) { void GameEngine::start(GameEvent ev) {
@ -63,7 +72,9 @@ void GameEngine::in_round(GameEvent ev, string &hit_type) {
switch(ev) { switch(ev) {
case GameEvent::HIT: case GameEvent::HIT:
hit(hit_type); hit(hit_type);
if(is_dead()) {
// NOTE: don't use is_dead to avoid free_death
if(hit_points <= 0) {
state(GameState::DEAD); state(GameState::DEAD);
} else { } else {
state(GameState::IN_ROUND); state(GameState::IN_ROUND);
@ -103,6 +114,22 @@ void GameEngine::success(GameEvent ev) {
void GameEngine::failure(GameEvent ev) { void GameEngine::failure(GameEvent ev) {
assert(ev == GameEvent::BUILD_DONE && "failure state expected BUILD_DONE"); assert(ev == GameEvent::BUILD_DONE && "failure state expected BUILD_DONE");
++rounds; ++rounds;
streak = 0; // streak is handled by reset()
state(GameState::IDLE); state(GameState::IDLE);
} }
int GameEngine::max_hp() {
return starting_hp * hp_bonus;
}
void GameEngine::add_bonus(GameBonus bonus) {
switch(bonus) {
case GameBonus::MORE_HP:
hp_bonus += 0.10f;
hit_points = max_hp();
break;
case GameBonus::FREE_DEATH:
free_death = true;
break;
}
}

@ -19,6 +19,10 @@ enum class GameEvent {
BUILD_DONE, BUILD_FAILED, HIT BUILD_DONE, BUILD_FAILED, HIT
}; };
enum class GameBonus {
MORE_HP, FREE_DEATH
};
class GameEngine : DeadSimpleFSM<GameState, GameEvent> { class GameEngine : DeadSimpleFSM<GameState, GameEvent> {
std::map<string, int> damage_types{ std::map<string, int> damage_types{
@ -33,6 +37,8 @@ class GameEngine : DeadSimpleFSM<GameState, GameEvent> {
int hits_taken = 0; int hits_taken = 0;
int rounds = 0; int rounds = 0;
int streak = 0; int streak = 0;
float hp_bonus = 1.0f;
bool free_death = false;
GameEngine(int hp); GameEngine(int hp);
@ -82,4 +88,6 @@ class GameEngine : DeadSimpleFSM<GameState, GameEvent> {
void heal(); void heal();
bool hit(string &type); bool hit(string &type);
void reset(); void reset();
void add_bonus(GameBonus bonus);
int max_hp();
}; };

@ -36,7 +36,44 @@ TEST_CASE("game engine death cycle", "[game_engine]") {
} }
TEST_CASE("game can do success build", "[game_engine]") { TEST_CASE("game can do success build", "[game_engine]") {
GameEngine game{10};
// test fails on purpose right now // test fails on purpose right now
GameEngine game{100}; for(int i = 0; i < 10; i++) {
game.event(GameEvent::BUILD_START);
game.event(GameEvent::BUILD_SUCCESS);
REQUIRE(game.hits_taken == 0);
REQUIRE(game.hit_points == game.starting_hp);
// confirm streaks, hit_taken, rounds are maintained
REQUIRE(game.streak == i);
REQUIRE(game.rounds == i);
REQUIRE(game.is_dead() == false);
game.event(GameEvent::BUILD_DONE);
}
// if you hit a streak of 10 then you get one of two bonuses
// 1. 10% more hp
// 2. 1 free death
game.add_bonus(GameBonus::MORE_HP);
REQUIRE(game.max_hp() > game.starting_hp);
REQUIRE(game.hit_points == game.starting_hp * game.hp_bonus);
REQUIRE(game.hit_points == game.max_hp());
game.add_bonus(GameBonus::FREE_DEATH);
REQUIRE(game.free_death == true);
game.event(GameEvent::BUILD_START);
game.event(GameEvent::HIT, "error");
game.event(GameEvent::HIT, "error");
game.event(GameEvent::HIT, "error");
REQUIRE(game.is_dead() == false); REQUIRE(game.is_dead() == false);
REQUIRE(game.streak == 10);
game.event(GameEvent::BUILD_FAILED);
game.event(GameEvent::BUILD_DONE);
REQUIRE(game.streak == 10);
REQUIRE(game.free_death == false);
REQUIRE(game.hit_points == int(game.max_hp() * 0.5f));
} }

Loading…
Cancel
Save