diff --git a/include/game_state.h b/include/game_state.h index bb27ca3..33f3ce6 100644 --- a/include/game_state.h +++ b/include/game_state.h @@ -219,6 +219,8 @@ namespace Hanabi void check_draw_pile_integrity() const; + probability_t check_play_or_discard(hand_index_t index, bool play); + static constexpr uint8_t no_endgame = std::numeric_limits::max(); // Usual game state diff --git a/include/game_state.hpp b/include/game_state.hpp index b289a6c..b8e3a09 100644 --- a/include/game_state.hpp +++ b/include/game_state.hpp @@ -940,14 +940,7 @@ namespace Hanabi { if (is_playable(hand[index])) { - probability_t sum_of_probabilities = 0; - - do_for_each_potential_draw(index, true, [this, &sum_of_probabilities](const unsigned long multiplicity) { - sum_of_probabilities += evaluate_state() * multiplicity; - }); - - const unsigned long total_weight = std::max(static_cast(_weighted_draw_pile_size), 1ul); - const probability_t probability_play = sum_of_probabilities / total_weight; + probability_t const probability_play = check_play_or_discard(index, true); best_probability = std::max(best_probability, probability_play); if (best_probability == 1) @@ -994,15 +987,7 @@ namespace Hanabi // Discard if we found trash now if (discard_index != invalid_index) { - probability_t sum_of_probabilities = 0; - - do_for_each_potential_draw(discard_index, false, [this, &sum_of_probabilities](const unsigned long multiplicity) { - sum_of_probabilities += evaluate_state() * multiplicity; - }); - - const unsigned long total_weight = std::max(static_cast(_weighted_draw_pile_size), 1ul); - const probability_t probability_discard = sum_of_probabilities / total_weight; - best_probability = std::max(best_probability, probability_discard); + probability_t const probability_discard = check_play_or_discard(discard_index, false); best_probability = std::max(best_probability, probability_discard); if (best_probability == 1) @@ -1015,18 +1000,9 @@ namespace Hanabi // sacrifice cards in hand for(hand_index_t index = 0; index < hand_size; ++index) { if(!is_critical(hand[index])) { - // consider discarding this - probability_t sum_of_probabilities = 0; + probability_t const probability_sacrifice = check_play_or_discard(index, false); - do_for_each_potential_draw(index, false, [this, &sum_of_probabilities](const unsigned long multiplicity) { - sum_of_probabilities += evaluate_state() * multiplicity; - }); - - const unsigned long total_weight = std::max(static_cast(_weighted_draw_pile_size), 1ul); - const probability_t probability_discard = sum_of_probabilities / total_weight; - best_probability = std::max(best_probability, probability_discard); - - best_probability = std::max(best_probability, probability_discard); + best_probability = std::max(best_probability, probability_sacrifice); if (best_probability == 1) { update_tablebase(id_of_state, best_probability); @@ -1055,6 +1031,18 @@ namespace Hanabi return best_probability; } + template + probability_t HanabiState::check_play_or_discard(hand_index_t index, bool play) { + probability_t sum_of_probabilities = 0; + + do_for_each_potential_draw(index, play, [this, &sum_of_probabilities](const unsigned long multiplicity) { + sum_of_probabilities += evaluate_state() * multiplicity; + }); + + const unsigned long total_weight = std::max(static_cast(_weighted_draw_pile_size), 1ul); + return sum_of_probabilities / total_weight; + } + template template void