better output in case of too short replays

This commit is contained in:
Maximilian Keßler 2023-11-12 18:32:19 +01:00
parent 32af52ae9e
commit d3328725c7
Signed by: max
GPG key ID: BCC5A619923C0BA5
4 changed files with 24 additions and 2 deletions

View file

@ -226,6 +226,7 @@ public:
[[nodiscard]] virtual player_t turn() const = 0; [[nodiscard]] virtual player_t turn() const = 0;
[[nodiscard]] virtual clue_t num_clues() const = 0; [[nodiscard]] virtual clue_t num_clues() const = 0;
[[nodiscard]] virtual unsigned score() const = 0;
[[nodiscard]] virtual std::vector<std::vector<Card>> hands() const = 0; [[nodiscard]] virtual std::vector<std::vector<Card>> hands() const = 0;
[[nodiscard]] virtual std::vector<Card> cur_hand() const = 0; [[nodiscard]] virtual std::vector<Card> cur_hand() const = 0;
[[nodiscard]] virtual size_t draw_pile_size() const = 0; [[nodiscard]] virtual size_t draw_pile_size() const = 0;
@ -260,6 +261,9 @@ protected:
// history by making and reverting the stored actions. // history by making and reverting the stored actions.
struct Game { struct Game {
Game(std::unique_ptr<HanabiStateIF> state, std::vector<Action> actions, std::vector<Card> deck); Game(std::unique_ptr<HanabiStateIF> state, std::vector<Action> actions, std::vector<Card> deck);
unsigned cur_turn() const;
void make_turn(); void make_turn();
void revert_turn(); void revert_turn();
@ -296,6 +300,7 @@ public:
[[nodiscard]] player_t turn() const final; [[nodiscard]] player_t turn() const final;
[[nodiscard]] clue_t num_clues() const final; [[nodiscard]] clue_t num_clues() const final;
[[nodiscard]] unsigned score() const final;
[[nodiscard]] std::vector<std::vector<Card>> hands() const final; [[nodiscard]] std::vector<std::vector<Card>> hands() const final;
[[nodiscard]] std::vector<Card> cur_hand() const final; [[nodiscard]] std::vector<Card> cur_hand() const final;
[[nodiscard]] size_t draw_pile_size() const final; [[nodiscard]] size_t draw_pile_size() const final;

View file

@ -589,7 +589,12 @@ namespace Hanabi {
template<suit_t num_suits, player_t num_players, hand_index_t hand_size> template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
clue_t HanabiState<num_suits, num_players, hand_size>::num_clues() const { clue_t HanabiState<num_suits, num_players, hand_size>::num_clues() const {
return _num_clues; return _num_clues;
}; }
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
unsigned HanabiState<num_suits, num_players, hand_size>::score() const {
return _score;
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size> template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
std::vector<std::vector<Card>> HanabiState<num_suits, num_players, hand_size>::hands() const { std::vector<std::vector<Card>> HanabiState<num_suits, num_players, hand_size>::hands() const {

View file

@ -96,6 +96,7 @@ namespace Hanabi {
throw std::logic_error("Invalid game state specification type encountered"); throw std::logic_error("Invalid game state specification type encountered");
} }
std::cout << parms.game_state_spec << " cannot be reached with specified replay." << std::endl; std::cout << parms.game_state_spec << " cannot be reached with specified replay." << std::endl;
std::cout << "Replay ends at turn " << game.cur_turn() << " with score of " << game.state->score() << "." << std::endl;
return state_unreachable; return state_unreachable;
} }
@ -117,10 +118,16 @@ namespace Hanabi {
// This already evaluates all intermediate game states as well, because stalling is an option // This already evaluates all intermediate game states as well, because stalling is an option
// (except for rare cases, where there is a forced win that does not need stalling). // (except for rare cases, where there is a forced win that does not need stalling).
size_t const max_draw_pile_size = game.state->draw_pile_size(); size_t const max_draw_pile_size = game.state->draw_pile_size();
bool printed_replay_end_msg = false;
for(size_t remaining_cards = 1; remaining_cards <= max_draw_pile_size; remaining_cards++) { for(size_t remaining_cards = 1; remaining_cards <= max_draw_pile_size; remaining_cards++) {
if (!game.goto_draw_pile_size(remaining_cards)) if (!game.goto_draw_pile_size(remaining_cards))
{ {
std::cout << "The given draw pile size (" << remaining_cards << ") cannot be obtained with the specified replay." << std::endl; if (not printed_replay_end_msg)
{
std::cout << "Draw pile size of " << game.state->draw_pile_size() -1 << " or lower cannot be obtained with the specified replay:" << std::endl;
std::cout << "Replay ends at turn " << game.cur_turn() << " with score of " << game.state->score() << "." << std::endl;
printed_replay_end_msg = true;
}
continue; continue;
}; };
if (std::holds_alternative<std::monostate>(parms.clue_spec)) if (std::holds_alternative<std::monostate>(parms.clue_spec))

View file

@ -21,6 +21,11 @@ namespace Hanabi {
} }
} }
unsigned Game::cur_turn() const
{
return next_action + 1;
}
void Game::make_turn() void Game::make_turn()
{ {
ASSERT(next_action < actions.size()); ASSERT(next_action < actions.size());