store number of useful cards in starting hands

This commit is contained in:
Maximilian Keßler 2023-08-07 11:48:39 +02:00
parent 9cc852a96d
commit 0100e8c987
Signed by: max
GPG Key ID: BCC5A619923C0BA5
2 changed files with 23 additions and 9 deletions

View File

@ -34,8 +34,6 @@ using state_t = std::uint32_t;
constexpr rank_t starting_card_rank = 5;
constexpr suit_t max_suit_index = 5;
constexpr size_t max_card_duplicity = 3;
constexpr player_t draw_pile = -1;
constexpr player_t trash_or_play_stack = -2;
constexpr clue_t max_num_clues = 8;
constexpr uint8_t not_in_starting_hand = std::numeric_limits<uint8_t>::max();
@ -200,6 +198,12 @@ private:
void incr_turn();
void decr_turn();
static constexpr uint8_t no_endgame = std::numeric_limits<uint8_t>::max();
static constexpr player_t draw_pile = num_players;
static constexpr player_t trash_or_play_stack = num_players + 1;
std::uint64_t unique_id() const;
player_t _turn{};
clue_t _num_clues{};
std::uint8_t _weighted_draw_pile_size{};
@ -208,13 +212,12 @@ private:
std::list<CardMultiplicity> _draw_pile{};
std::uint8_t _endgame_turns_left{};
static constexpr uint8_t no_endgame = std::numeric_limits<uint8_t>::max();
// This will save the card positions of all cards that are in the draw pile when we start backtracking
CardArray<num_suits, boost::container::static_vector<player_t, max_card_duplicity>> _card_positions_draw;
// This will indicate whether cards that were in hands initially still are in hands
std::bitset<num_players * hand_size> _card_positions_hands;
size_t _num_useful_cards_in_starting_hands;
// further statistics that we might want to keep track of
uint8_t _pace{};

View File

@ -69,8 +69,12 @@ namespace Hanabi {
_hands(),
_draw_pile(),
_endgame_turns_left(no_endgame),
_card_positions_draw(),
_card_positions_hands(),
_num_useful_cards_in_starting_hands(0),
_pace(deck.size() - 5 * num_suits - num_players * (hand_size - 1)),
_score(0) {
_score(0),
_enumerated_states(0) {
std::ranges::fill(_stacks, starting_card_rank);
for(const Card& card: deck) {
_draw_pile.push_back({card, 1});
@ -340,7 +344,6 @@ namespace Hanabi {
}
// Prepare cards in hands
uint8_t local_index_among_good_starting_hand_cards = 0;
for(player_t player = 0; player < num_players; player++) {
for(Card& card : _hands[player]) {
card.initial_trash = is_trash(card);
@ -351,8 +354,8 @@ namespace Hanabi {
// This card is already in hand, so just replace the second copy by some trash
card = trash;
} else {
card.local_index_among_good_starting_hand_cards = local_index_among_good_starting_hand_cards;
local_index_among_good_starting_hand_cards++;
card.local_index_among_good_starting_hand_cards = _num_useful_cards_in_starting_hands;
_num_useful_cards_in_starting_hands++;
good_cards_in_hand.push_back(card);
}
@ -360,7 +363,9 @@ namespace Hanabi {
}
}
_card_positions_hands.reset();
_card_positions_hands.flip();
for(size_t i = 0; i < _num_useful_cards_in_starting_hands; i++) {
_card_positions_hands[i] = true;
}
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
@ -480,4 +485,10 @@ namespace Hanabi {
return best_probability;
}
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
std::uint64_t HanabiState<num_suits, num_players, hand_size>::unique_id() const {
unsigned long id = _card_positions_hands.to_ulong();
return id;
}
} // namespace Hanabi