From 8da12f5360c9e87d6ad4ba88ea1ec78a0578bb5f Mon Sep 17 00:00:00 2001 From: Peisong Xiao Date: Sat, 13 Jul 2024 17:13:10 -0400 Subject: [PATCH] New attack function for single character in characters.h, need implementation (example in shade.h) --- src/characters.cc | 11 +++++++ src/characters.h | 6 ++++ src/constants.h | 6 ++-- src/game.cc | 76 +++++++++++++++++++++++++++++++++++++++++++++++ src/game.h | 23 ++++++++++++-- src/shade.cc | 9 ++++++ src/shade.h | 1 + 7 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 src/game.cc diff --git a/src/characters.cc b/src/characters.cc index af80e33..c6ec287 100644 --- a/src/characters.cc +++ b/src/characters.cc @@ -202,6 +202,17 @@ result character::move_or_attack(const direction dir, return this->attack(dir, chlist); } +result character::move_or_attack(const direction dir, + const position_list &available_positions, + character *ch) { + auto res = this->move(dir, available_positions); + + if (res != result::fine) + return res; + + return this->attack(dir, ch); +} + int calc_dmg(const int ATK, const int DEF) { return ceil((100 / (100 + DEF)) * ATK); diff --git a/src/characters.h b/src/characters.h index db75525..70e75e6 100644 --- a/src/characters.h +++ b/src/characters.h @@ -34,6 +34,12 @@ public: virtual result move_or_attack(const direction dir, const position_list &available_positions, character_list &chlist); + + virtual result attack(const direction dir, character *ch) = 0; + virtual result move_or_attack(const direction dir, + const position_list &available_positions, + character *ch); + virtual void apply(direction &dir, potion_list &potions); virtual result get_hit(const enum race &race, const int atk, diff --git a/src/constants.h b/src/constants.h index 2e696bd..42682dd 100644 --- a/src/constants.h +++ b/src/constants.h @@ -9,9 +9,11 @@ const int INF = 0x3F3F3F3F; enum error {none}; // TODO: update result to include subject -enum result {fine, died, go_down, hit, moved, miss}; +enum result {fine, died, go_down, go_up, hit, moved, miss}; -enum game_status {terminated, main_menu, in_game, options}; +enum game_status {terminated, main_menu, in_game, options, + dead, won, escaped, restart + }; enum game_command {game_command_terminate = 0, move_north, move_south, move_east, move_west, diff --git a/src/game.cc b/src/game.cc new file mode 100644 index 0000000..dc7df97 --- /dev/null +++ b/src/game.cc @@ -0,0 +1,76 @@ +#include "game.h" + +#include "races.h" + +game::game(const enum race starting_race, + const feature enabled_features, + input *new_in, + display *new_out, + logger *new_log, + RNG *new_rng): + enabled_features{enabled_features}, + in{new_in}, out{new_out}, log{new_log}, rng{new_rng} { + const position nil{0, 0}; + the_world = false; + + // TODO: add the other races + switch (starting_race) { + case race::rshade: + player = std::make_unique(rng, nil); + break; + } + + if (enabled_features & FEATURE_EXTRA_LEVELS) + max_level = rng->rand_between(MIN_LEVEL_CNT, MAX_LEVEL_CNT + 1); + else + max_level = DEFAULT_MAX_LEVEL; + + levels.reserve(max_level); + curr_level = 0; + + new_level(); +} + +void game::new_level() { + if (enabled_features & FEATURE_RAND_MAP) + levels.push_back(std::make_unique(player.get(), + rng, enabled_features)); + else + levels.push_back(std::make_unique(default_map, player.get(), + rng, enabled_features)); +} + +game_status game::run() { + auto res = player_moves(in->get_command()); + + switch (res) { + case result::died: + return game_status::dead; + + case result::go_down: { + if (curr_level == max_level - 1) + return game_status::won; + + player->discard_level_effects(); + ++curr_level; + new_level(); + break; + } + + case result::go_up: { + if (curr_level == 0) + return game_status::escaped; + + --curr_level; + player->set_position(levels[curr_level]->get_down_stairs()); + break; + } + + default: + break; + } + + + + return game_status::in_game; +} diff --git a/src/game.h b/src/game.h index fd83ece..6221749 100644 --- a/src/game.h +++ b/src/game.h @@ -7,26 +7,43 @@ #include "input.h" #include "rng.h" #include "characters.h" -#include "map.h" +#include "level.h" #include "log.h" class game final { private: - feature features; + static const size_t MAX_LEVEL_CNT = 50; + static const size_t MIN_LEVEL_CNT = 30; + static const size_t DEFAULT_MAX_LEVEL = 5; + + const feature enabled_features; + input *in; display *out; logger *log; RNG *rng; std::unique_ptr player; + std::vector> levels; + + size_t max_level; + size_t curr_level; + + bool the_world; public: - game(const feature enabled_features, + game(const enum race starting_race, + const feature enabled_features, input *new_in, display *new_out, logger *new_log, RNG *new_rng); game_status run(); + size_t get_curr_level() const; + const character *get_player() const; private: + result player_moves(game_command cmd); + void new_level(); + void move_enemies(); }; #endif diff --git a/src/shade.cc b/src/shade.cc index 9fcac64..b89ca90 100644 --- a/src/shade.cc +++ b/src/shade.cc @@ -20,6 +20,15 @@ result shade::attack(const direction dir, character_list &chlist) { return result::fine; } +result shade::attack(const direction dir, character *ch) { + position tmp{pos + MOVE[dir]}; + + if (tmp == ch->get_position()) + return ch->get_hit(race, ATK, base_hit_rate); + + return result::fine; +} + result shade::get_hit(const enum race &race, const int atk, const fraction hitrate) { if (rng->trial(hitrate)) // This is a hit! diff --git a/src/shade.h b/src/shade.h index 59a748c..93c9ab4 100644 --- a/src/shade.h +++ b/src/shade.h @@ -10,6 +10,7 @@ public: character_list &chlist) override; virtual result get_hit(const enum race &race, const int atk, const fraction hit_rate) override; + virtual result attack(const direction dir, character *ch) override; }; #endif