store bits for starting hand cards in central bitse
This commit is contained in:
parent
8001483ddd
commit
9cc852a96d
2 changed files with 22 additions and 18 deletions
|
@ -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<uint8_t>::max();
|
||||
|
||||
constexpr std::array<std::string, 6> 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<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::array<std::bitset<hand_size>, 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<boost::container::static_vector<Card, hand_size>, num_players> _good_cards_in_initial_draw_pile;
|
||||
// This will indicate whether cards that were in hands initially still are in hands
|
||||
std::bitset<num_players * hand_size> _card_positions_hands;
|
||||
|
||||
// further statistics that we might want to keep track of
|
||||
uint8_t _pace{};
|
||||
|
|
|
@ -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<Card, hand_size> 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<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||
|
|
Loading…
Reference in a new issue