implement criticality of cards
This commit is contained in:
parent
8b42819704
commit
4ba61b0450
3 changed files with 40 additions and 0 deletions
|
@ -57,6 +57,9 @@ namespace Hanabi
|
||||||
|
|
||||||
[[nodiscard]] virtual bool is_trash(const Card & card) const = 0;
|
[[nodiscard]] virtual bool is_trash(const Card & card) const = 0;
|
||||||
|
|
||||||
|
/** Returns whether the card is critical, assuming it is not trash already */
|
||||||
|
[[nodiscard]] virtual bool is_critical(const Card & card) const = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual bool is_playable(const Card & card) const = 0;
|
[[nodiscard]] virtual bool is_playable(const Card & card) const = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual bool is_relative_state_initialized() const = 0;
|
[[nodiscard]] virtual bool is_relative_state_initialized() const = 0;
|
||||||
|
|
|
@ -106,6 +106,9 @@ namespace Hanabi
|
||||||
|
|
||||||
[[nodiscard]] bool is_trash(const Card & card) const final;
|
[[nodiscard]] bool is_trash(const Card & card) const final;
|
||||||
|
|
||||||
|
/** Returns whether the card is critical, assuming that it is non-trash */
|
||||||
|
[[nodiscard]] bool is_critical(const Card & card) const final;
|
||||||
|
|
||||||
[[nodiscard]] bool is_playable(const Card & card) const final;
|
[[nodiscard]] bool is_playable(const Card & card) const final;
|
||||||
|
|
||||||
[[nodiscard]] bool is_relative_state_initialized() const final;
|
[[nodiscard]] bool is_relative_state_initialized() const final;
|
||||||
|
@ -230,6 +233,11 @@ namespace Hanabi
|
||||||
std::list<CardMultiplicity> _draw_pile{};
|
std::list<CardMultiplicity> _draw_pile{};
|
||||||
std::uint8_t _endgame_turns_left{};
|
std::uint8_t _endgame_turns_left{};
|
||||||
|
|
||||||
|
// This will actually not always be updated exactly, but only for those cards that are not
|
||||||
|
// trash yet, since for trash, this is simply not interesting.
|
||||||
|
// Thus, we only need to update this on discards or misplays.
|
||||||
|
CardArray<num_suits, int8_t> _num_copies_left {0};
|
||||||
|
|
||||||
// further values of game state that are technically determined, but we update them anyway
|
// further values of game state that are technically determined, but we update them anyway
|
||||||
int8_t _pace{};
|
int8_t _pace{};
|
||||||
uint8_t _score{};
|
uint8_t _score{};
|
||||||
|
|
|
@ -86,6 +86,17 @@ namespace Hanabi
|
||||||
incr_turn();
|
incr_turn();
|
||||||
}
|
}
|
||||||
ASSERT(_turn == 0);
|
ASSERT(_turn == 0);
|
||||||
|
|
||||||
|
// Prepare card counting
|
||||||
|
CardArray<num_suits, unsigned> card_multiplicities (0);
|
||||||
|
for (auto const hand: _hands) {
|
||||||
|
for (Card const card: hand) {
|
||||||
|
_num_copies_left[card] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (CardMultiplicity const card_mult : _draw_pile) {
|
||||||
|
_num_copies_left[card_mult.card] += card_mult.multiplicity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
||||||
|
@ -147,6 +158,12 @@ namespace Hanabi
|
||||||
return card.rank == _stacks[card.suit] - 1;
|
return card.rank == _stacks[card.suit] - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||||
|
bool HanabiState<num_suits, num_players, hand_size>::is_critical(Card const & card) const
|
||||||
|
{
|
||||||
|
return _num_copies_left[card] == 1;
|
||||||
|
}
|
||||||
|
|
||||||
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::uint64_t HanabiState<num_suits, num_players, hand_size>::enumerated_states() const
|
std::uint64_t HanabiState<num_suits, num_players, hand_size>::enumerated_states() const
|
||||||
{
|
{
|
||||||
|
@ -186,6 +203,8 @@ namespace Hanabi
|
||||||
// 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 += _clues_gained_on_discard_or_stack_finished;
|
_num_clues += _clues_gained_on_discard_or_stack_finished;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
_num_copies_left[played_card]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned long multiplicity = draw(index, cycle, !strike);
|
const unsigned long multiplicity = draw(index, cycle, !strike);
|
||||||
|
@ -213,6 +232,8 @@ namespace Hanabi
|
||||||
_num_clues += _clues_gained_on_discard_or_stack_finished;
|
_num_clues += _clues_gained_on_discard_or_stack_finished;
|
||||||
_pace--;
|
_pace--;
|
||||||
|
|
||||||
|
_num_copies_left[discarded_card]--;
|
||||||
|
|
||||||
unsigned long multiplicity = draw(index, cycle, false);
|
unsigned long multiplicity = draw(index, cycle, false);
|
||||||
_actions_log.emplace(ActionType::discard, discarded_card, index);
|
_actions_log.emplace(ActionType::discard, discarded_card, index);
|
||||||
|
|
||||||
|
@ -274,6 +295,9 @@ namespace Hanabi
|
||||||
for (hand_index_t index = 0; index < hand.size(); index++)
|
for (hand_index_t index = 0; index < hand.size(); index++)
|
||||||
{
|
{
|
||||||
os << hand[index];
|
os << hand[index];
|
||||||
|
if (is_critical(hand[index])) {
|
||||||
|
os << "!";
|
||||||
|
}
|
||||||
if (index < hand.size() - 1)
|
if (index < hand.size() - 1)
|
||||||
{
|
{
|
||||||
os << " ";
|
os << " ";
|
||||||
|
@ -577,6 +601,9 @@ namespace Hanabi
|
||||||
{
|
{
|
||||||
_stacks[last_action.discarded.suit]++;
|
_stacks[last_action.discarded.suit]++;
|
||||||
_score--;
|
_score--;
|
||||||
|
} else {
|
||||||
|
// If we misplayed, then we lost the card and have to regain it now
|
||||||
|
_num_copies_left[last_action.discarded]++;
|
||||||
}
|
}
|
||||||
check_draw_pile_integrity();
|
check_draw_pile_integrity();
|
||||||
}
|
}
|
||||||
|
@ -597,6 +624,8 @@ namespace Hanabi
|
||||||
|
|
||||||
_pace++;
|
_pace++;
|
||||||
|
|
||||||
|
_num_copies_left[last_action.discarded]++;
|
||||||
|
|
||||||
revert_draw(last_action.index, last_action.discarded, cycle, false);
|
revert_draw(last_action.index, last_action.discarded, cycle, false);
|
||||||
check_draw_pile_integrity();
|
check_draw_pile_integrity();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue