diff --git a/game_state.h b/game_state.h index 7d7b424..3544438 100644 --- a/game_state.h +++ b/game_state.h @@ -37,13 +37,14 @@ 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::max(); constexpr std::array suit_initials{"r", "y", "g", "b", "p", "t"}; struct Card { suit_t suit; rank_t rank; - bool was_in_initial_hand; + uint8_t local_index_among_good_starting_hand_cards; bool initial_trash; Card &operator++(); @@ -211,11 +212,9 @@ private: // This will save the card positions of all cards that are in the draw pile when we start backtracking CardArray> _card_positions_draw; - // This will indicate whether cards that were in hands initially still are in hands - std::array, num_players> _card_positions_hands; - // A list of cards (set up once upon initialization) of all good cards that were in starting hands - std::array, num_players> _good_cards_in_initial_draw_pile; + // This will indicate whether cards that were in hands initially still are in hands + std::bitset _card_positions_hands; // further statistics that we might want to keep track of uint8_t _pace{}; diff --git a/game_state.hpp b/game_state.hpp index c8e7080..e040f01 100644 --- a/game_state.hpp +++ b/game_state.hpp @@ -218,9 +218,9 @@ namespace Hanabi { if constexpr(update_card_positions) { const Card discarded = _hands[_turn][index]; if (!discarded.initial_trash) { - if (discarded.was_in_initial_hand) { - ASSERT(_card_positions_hands[_turn][index] == true); - _card_positions_hands[_turn][index] = false; + if (discarded.local_index_among_good_starting_hand_cards != not_in_starting_hand) { + ASSERT(_card_positions_hands[discarded.local_index_among_good_starting_hand_cards] == true); + _card_positions_hands[discarded.local_index_among_good_starting_hand_cards] = false; } else { auto replaced_card_it = std::ranges::find(_card_positions_draw[discarded], _turn); ASSERT(replaced_card_it != _card_positions_draw[discarded].end()); @@ -290,9 +290,9 @@ namespace Hanabi { } if (!discarded_card.initial_trash) { - if (discarded_card.was_in_initial_hand) { - ASSERT(_card_positions_hands[_turn][index] == false); - _card_positions_hands[_turn][index] = true; + if (discarded_card.local_index_among_good_starting_hand_cards != not_in_starting_hand) { + ASSERT(_card_positions_hands[discarded_card.local_index_among_good_starting_hand_cards] == false); + _card_positions_hands[discarded_card.local_index_among_good_starting_hand_cards] = true; } else { auto hand_card_it = std::ranges::find(_card_positions_draw[discarded_card], trash_or_play_stack); ASSERT(hand_card_it != _card_positions_draw[discarded_card].end()); @@ -309,7 +309,7 @@ namespace Hanabi { const Card trash = [this]() -> Card { for(suit_t suit = 0; suit < num_suits; suit++) { if(_stacks[suit] < starting_card_rank) { - return {suit, starting_card_rank - 1, false, true}; + return {suit, starting_card_rank - 1, not_in_starting_hand, true}; } } return {0,0}; @@ -328,7 +328,7 @@ namespace Hanabi { _draw_pile.clear(); for(suit_t suit = 0; suit < num_suits; suit++) { for(rank_t rank = 0; rank < starting_card_rank; rank++) { - Card card {suit, rank, false, is_trash(card)}; + Card card {suit, rank, not_in_starting_hand, is_trash(card)}; _card_positions_draw[card].clear(); if (nums_in_draw_pile[card] > 0) { _draw_pile.push_back({card, nums_in_draw_pile[card]}); @@ -340,22 +340,27 @@ 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.was_in_initial_hand = true; card.initial_trash = is_trash(card); + // Needed to check for dupes in same hand + boost::container::static_vector good_cards_in_hand; if(!is_trash(card)) { - if(std::count(_good_cards_in_initial_draw_pile[player].begin(), _good_cards_in_initial_draw_pile[player].end(), card) > 0) { + if(std::count(good_cards_in_hand.begin(), good_cards_in_hand.end(), card) > 0) { // This card is already in hand, so just replace the second copy by some trash card = trash; } else { - _good_cards_in_initial_draw_pile[player].push_back(card); + card.local_index_among_good_starting_hand_cards = local_index_among_good_starting_hand_cards; + local_index_among_good_starting_hand_cards++; + + good_cards_in_hand.push_back(card); } } } - _card_positions_hands[player].reset(); - _card_positions_hands[player].flip(); } + _card_positions_hands.reset(); + _card_positions_hands.flip(); } template