Fix: Correctly handle bombing of cards and reverting thereof

This commit is contained in:
Maximilian Keßler 2023-11-11 22:52:28 +01:00
parent 5308eeaf6e
commit a615733350
Signed by: max
GPG key ID: BCC5A619923C0BA5
3 changed files with 23 additions and 22 deletions

View file

@ -327,7 +327,8 @@ private:
ActionType action_type, ActionType action_type,
Card discarded_or_played = Cards::unknown, Card discarded_or_played = Cards::unknown,
hand_index_t index = 0, hand_index_t index = 0,
bool was_on_8_clues = false bool was_on_8_clues = false,
bool strike = false
); );
ActionType action_type{}; ActionType action_type{};
@ -339,6 +340,11 @@ private:
// Indicates whether before the action was taken, we had 8 clues. // 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 // 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}; bool was_on_8_clues {false};
// Indicates whether playing this card triggered a bomb.
// This cannot be deduced just from the stacks since we cannot differentiate between a card
// having been played correctly or the top card of the draw pile being bombed.
bool strike {false};
}; };
// This keeps track of the representation of the gamestate relative to some starting state // This keeps track of the representation of the gamestate relative to some starting state

View file

@ -103,12 +103,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>
HanabiState<num_suits, num_players, hand_size>::BacktrackAction::BacktrackAction( HanabiState<num_suits, num_players, hand_size>::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 bool was_on_8_clues, bool strike
): ):
action_type(action_type), action_type(action_type),
discarded(discarded_or_played), discarded(discarded_or_played),
index(index), index(index),
was_on_8_clues(was_on_8_clues) { was_on_8_clues(was_on_8_clues), strike(strike) {
} }
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>
@ -210,22 +210,18 @@ namespace Hanabi {
check_draw_pile_integrity(); check_draw_pile_integrity();
ASSERT(index < _hands[_turn].size()); ASSERT(index < _hands[_turn].size());
const Card played_card = _hands[_turn][index]; const Card played_card = _hands[_turn][index];
if (!is_playable(played_card)) {
const unsigned long multiplicity = draw(index, cycle);
incr_turn();
return multiplicity;
}
ASSERT(is_playable(played_card));
_actions_log.emplace(ActionType::play, played_card, index, _num_clues == 8); _actions_log.emplace(ActionType::play, played_card, index, _num_clues == 8, !is_playable(played_card));
if(is_playable(played_card))
{
--_stacks[played_card.suit]; --_stacks[played_card.suit];
_score++; _score++;
if (played_card.rank == 0 and _num_clues < max_num_clues) { if (played_card.rank == 0 and _num_clues < max_num_clues) {
// update clues if we played the last played_card of a stack // update clues if we played the last played_card of a stack
_num_clues++; _num_clues++;
} }
}
const unsigned long multiplicity = draw(index, cycle); const unsigned long multiplicity = draw(index, cycle);
@ -505,14 +501,14 @@ namespace Hanabi {
ASSERT(!last_action.was_on_8_clues or _num_clues == 8); ASSERT(!last_action.was_on_8_clues or _num_clues == 8);
decr_turn(); decr_turn();
if (last_action.discarded.rank == 0 and not last_action.was_on_8_clues) { if (last_action.discarded.rank == 0 and not last_action.was_on_8_clues and not last_action.strike) {
_num_clues--; _num_clues--;
} }
revert_draw(last_action.index, last_action.discarded, cycle); revert_draw(last_action.index, last_action.discarded, cycle);
if(_stacks[last_action.discarded.suit] == last_action.discarded.rank) { if(not last_action.strike) {
_stacks[last_action.discarded.suit]++; _stacks[last_action.discarded.suit]++;
}
_score--; _score--;
}
check_draw_pile_integrity(); check_draw_pile_integrity();
} }

View file

@ -80,7 +80,6 @@ namespace Hanabi {
while(state->draw_pile_size() < draw_pile_break or (state->draw_pile_size() == draw_pile_break and state->last_action_type() == ActionType::clue)) { while(state->draw_pile_size() < draw_pile_break or (state->draw_pile_size() == draw_pile_break and state->last_action_type() == ActionType::clue)) {
revert_turn(); revert_turn();
} }
std::cout << "Moved to turn " << next_action + 1 << " with draw pile size " << state->draw_pile_size() << ".\n";
return state->draw_pile_size() == draw_pile_break; return state->draw_pile_size() == draw_pile_break;
} }