diff --git a/include/game_state.h b/include/game_state.h index c1c5564..446adde 100644 --- a/include/game_state.h +++ b/include/game_state.h @@ -21,7 +21,7 @@ namespace Hanabi { using rank_t = std::uint8_t; using suit_t = std::uint8_t; - using clue_t = std::uint8_t; + using clue_t = std::int8_t; using player_t = std::uint8_t; using hand_index_t = std::uint8_t; @@ -220,6 +220,8 @@ public: virtual void rotate_next_draw(const Card& card) = 0; virtual void revert() = 0; + virtual void modify_clues(clue_t change) = 0; + [[nodiscard]] virtual player_t turn() const = 0; [[nodiscard]] virtual clue_t num_clues() const = 0; [[nodiscard]] virtual std::vector> hands() const = 0; @@ -258,6 +260,7 @@ struct Game { void make_turn(); void revert_turn(); void forward_until(size_t turn = 100, size_t draw_pile_break = 0); + void revert_until(size_t draw_pile_break); std::unique_ptr state; @@ -282,6 +285,8 @@ public: void revert() final; + void modify_clues(clue_t change) final; + [[nodiscard]] player_t turn() const final; [[nodiscard]] clue_t num_clues() const final; [[nodiscard]] std::vector> hands() const final; diff --git a/include/game_state.hpp b/include/game_state.hpp index 0ebb8cd..11b4d2e 100644 --- a/include/game_state.hpp +++ b/include/game_state.hpp @@ -511,6 +511,19 @@ namespace Hanabi { } } + + template + void HanabiState::modify_clues(Hanabi::clue_t change) + { + _num_clues += change; + if (_num_clues > 8) { + _num_clues = 8; + } + if (_num_clues < 0) { + _num_clues = 0; + } + } + template player_t HanabiState::turn() const { return _turn; diff --git a/src/main.cpp b/src/main.cpp index 97f5a4d..2ca672a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,7 +12,7 @@ namespace Hanabi { void analyze_game_and_start_cli(std::variant game_id, int turn, int draw_pile_size, std::optional score_goal, - bool start_cli, bool print_remaining_states, bool quiet) { + bool start_cli, bool print_remaining_states, bool quiet, clue_t clue_modifier) { auto game = Download::get_game(game_id, score_goal); if (game.state == nullptr) { if(game_id.index() == 0) { @@ -24,6 +24,7 @@ namespace Hanabi { } game.forward_until(turn, draw_pile_size); + game.state->modify_clues(clue_modifier); if (not quiet) { std::cout << "Analysing state: " << std::endl << std::endl << *game.state << std::endl; @@ -37,8 +38,8 @@ namespace Hanabi { std::cout.precision(10); if (not (quiet and print_remaining_states)) { std::cout << "Probability with optimal play: "; + print_probability(std::cout, res) << std::endl; } - print_probability(std::cout, res) << std::endl; if (not quiet) { std::cout << "Took " << std::chrono::duration_cast(end - start) << "." << std::endl; std::cout << "Visited " << game.state->enumerated_states() << " states." << std::endl; @@ -72,6 +73,7 @@ int main(int argc, char *argv[]) { int draw_pile_size = 0; std::optional score; bool interactive_shell; + int clue_modifier = 0; boost::program_options::options_description desc("Allowed options"); desc.add_options() @@ -83,6 +85,7 @@ int main(int argc, char *argv[]) { ("score,s", boost::program_options::value(), "Score that counts as a win, i.e. is optimized for achieving.") ("interactive,i", boost::program_options::value(&interactive_shell)->default_value(true), "Drop into interactive shell to explore game") ("remaining-states,r", "Print probabilities for all further sizes of draw pile.") + ("clue-modifier,c", boost::program_options::value(&clue_modifier)->default_value(0), "Modification to the number of clues applied to selected game state.") ("quiet,q", "Deactivate all non-essential prints") ; boost::program_options::variables_map vm; @@ -111,9 +114,9 @@ int main(int argc, char *argv[]) { } if (vm.count("file")) { - Hanabi::analyze_game_and_start_cli(vm["file"].as().c_str(), turn, draw_pile_size, score, interactive_shell, vm.count("remaining-states"), vm.count("quiet")); + Hanabi::analyze_game_and_start_cli(vm["file"].as().c_str(), turn, draw_pile_size, score, interactive_shell, vm.count("remaining-states"), vm.count("quiet"), clue_modifier); } else { - Hanabi::analyze_game_and_start_cli(vm["id"].as(), turn, draw_pile_size, score, interactive_shell, vm.count("remaining-states"), vm.count("quiet")); + Hanabi::analyze_game_and_start_cli(vm["id"].as(), turn, draw_pile_size, score, interactive_shell, vm.count("remaining-states"), vm.count("quiet"), clue_modifier); } return EXIT_SUCCESS; }