add 8 clue state to backtrack action

This commit is contained in:
Maximilian Keßler 2023-08-10 12:44:09 +02:00
parent a4ee7ace1d
commit b1963967a7
Signed by: max
GPG key ID: BCC5A619923C0BA5
2 changed files with 22 additions and 12 deletions

View file

@ -146,13 +146,22 @@ enum class ActionType {
};
struct BacktrackAction {
BacktrackAction(ActionType action_type, Card discarded_or_played, hand_index_t index);
explicit BacktrackAction(
ActionType action_type,
Card discarded_or_played = unknown_card,
hand_index_t index = 0,
bool was_on_8_clues = false
);
ActionType action_type{};
// The card that was discarded or played
Card discarded{};
// Index of card in hand that was discarded or played
hand_index_t index{};
// Indicates whether before the action was taken, we had 8 clues.
// This is important so that we know if we go back to 7 or 8 clues when we revert playing a 5
bool was_on_8_clues {false};
};
/** Would like to have 2 versions:
@ -201,7 +210,7 @@ public:
void discard(hand_index_t index) final;
void revert_clue();
void revert_play(bool was_on_8_clues);
void revert_play();
void revert_discard();
[[nodiscard]] hand_index_t find_card_in_hand(const Card& card) const final;

View file

@ -62,11 +62,13 @@ namespace Hanabi {
};
BacktrackAction::BacktrackAction(
Hanabi::ActionType action_type, Hanabi::Card discarded_or_played, Hanabi::hand_index_t index
Hanabi::ActionType action_type, Hanabi::Card discarded_or_played, Hanabi::hand_index_t index,
bool was_on_8_clues
):
action_type(action_type),
discarded(discarded_or_played),
index(index) {
index(index),
was_on_8_clues(was_on_8_clues) {
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
@ -156,6 +158,8 @@ namespace Hanabi {
const Card played_card = _hands[_turn][index];
ASSERT(is_playable(played_card));
_actions_log.emplace(ActionType::play, played_card, index, _num_clues == 8);
--_stacks[played_card.suit];
_score++;
@ -165,7 +169,6 @@ namespace Hanabi {
}
unsigned long multiplicity = draw<update_card_positions>(index);
_actions_log.emplace(ActionType::play, played_card, index);
incr_turn();
return multiplicity;
@ -388,14 +391,14 @@ namespace Hanabi {
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
void
HanabiState<num_suits, num_players, hand_size>::revert_play(bool was_on_8_clues) {
HanabiState<num_suits, num_players, hand_size>::revert_play() {
const BacktrackAction last_action = _actions_log.top();
_actions_log.pop();
ASSERT(last_action.action_type == ActionType::play);
ASSERT(!was_on_8_clues or _num_clues == 8);
ASSERT(!last_action.was_on_8_clues or _num_clues == 8);
decr_turn();
if (last_action.discarded.rank == 0 and not was_on_8_clues) {
if (last_action.discarded.rank == 0 and not last_action.was_on_8_clues) {
_num_clues--;
}
revert_draw(last_action.index, last_action.discarded);
@ -471,20 +474,18 @@ namespace Hanabi {
for(std::uint8_t index = 0; index < hand_size; index++) {
if(is_playable(hand[index])) {
if (_draw_pile.empty()) {
bool on_8_clues = _num_clues == 8;
play_and_potentially_update<true>(index);
const probability_t probability_for_this_play = backtrack(depth + 1);
revert_play(on_8_clues);
revert_play();
UPDATE_PROBABILITY(probability_for_this_play);
} else {
probability_t sum_of_probabilities = 0;
uint8_t sum_of_mults = 0;
for (size_t i = 0; i < _draw_pile.size(); i++) {
bool on_8_clues = _num_clues == 8;
const unsigned long multiplicity = play_and_potentially_update<true>(index);
sum_of_probabilities += backtrack(depth + 1) * multiplicity;
sum_of_mults += multiplicity;
revert_play(on_8_clues);
revert_play();
ASSERT(sum_of_mults <= _weighted_draw_pile_size);
}
ASSERT(sum_of_mults == _weighted_draw_pile_size);