store number of useful cards in starting hands
This commit is contained in:
parent
9cc852a96d
commit
0100e8c987
2 changed files with 23 additions and 9 deletions
11
game_state.h
11
game_state.h
|
@ -34,8 +34,6 @@ using state_t = std::uint32_t;
|
||||||
constexpr rank_t starting_card_rank = 5;
|
constexpr rank_t starting_card_rank = 5;
|
||||||
constexpr suit_t max_suit_index = 5;
|
constexpr suit_t max_suit_index = 5;
|
||||||
constexpr size_t max_card_duplicity = 3;
|
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 clue_t max_num_clues = 8;
|
||||||
constexpr uint8_t not_in_starting_hand = std::numeric_limits<uint8_t>::max();
|
constexpr uint8_t not_in_starting_hand = std::numeric_limits<uint8_t>::max();
|
||||||
|
|
||||||
|
@ -200,6 +198,12 @@ private:
|
||||||
void incr_turn();
|
void incr_turn();
|
||||||
void decr_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{};
|
player_t _turn{};
|
||||||
clue_t _num_clues{};
|
clue_t _num_clues{};
|
||||||
std::uint8_t _weighted_draw_pile_size{};
|
std::uint8_t _weighted_draw_pile_size{};
|
||||||
|
@ -208,13 +212,12 @@ private:
|
||||||
std::list<CardMultiplicity> _draw_pile{};
|
std::list<CardMultiplicity> _draw_pile{};
|
||||||
std::uint8_t _endgame_turns_left{};
|
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
|
// 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;
|
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
|
// This will indicate whether cards that were in hands initially still are in hands
|
||||||
std::bitset<num_players * hand_size> _card_positions_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
|
// further statistics that we might want to keep track of
|
||||||
uint8_t _pace{};
|
uint8_t _pace{};
|
||||||
|
|
|
@ -69,8 +69,12 @@ namespace Hanabi {
|
||||||
_hands(),
|
_hands(),
|
||||||
_draw_pile(),
|
_draw_pile(),
|
||||||
_endgame_turns_left(no_endgame),
|
_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)),
|
_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);
|
std::ranges::fill(_stacks, starting_card_rank);
|
||||||
for(const Card& card: deck) {
|
for(const Card& card: deck) {
|
||||||
_draw_pile.push_back({card, 1});
|
_draw_pile.push_back({card, 1});
|
||||||
|
@ -340,7 +344,6 @@ namespace Hanabi {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare cards in hands
|
// Prepare cards in hands
|
||||||
uint8_t local_index_among_good_starting_hand_cards = 0;
|
|
||||||
for(player_t player = 0; player < num_players; player++) {
|
for(player_t player = 0; player < num_players; player++) {
|
||||||
for(Card& card : _hands[player]) {
|
for(Card& card : _hands[player]) {
|
||||||
card.initial_trash = is_trash(card);
|
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
|
// This card is already in hand, so just replace the second copy by some trash
|
||||||
card = trash;
|
card = trash;
|
||||||
} else {
|
} else {
|
||||||
card.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;
|
||||||
local_index_among_good_starting_hand_cards++;
|
_num_useful_cards_in_starting_hands++;
|
||||||
|
|
||||||
good_cards_in_hand.push_back(card);
|
good_cards_in_hand.push_back(card);
|
||||||
}
|
}
|
||||||
|
@ -360,7 +363,9 @@ namespace Hanabi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_card_positions_hands.reset();
|
_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>
|
template<suit_t num_suits, player_t num_players, hand_index_t hand_size>
|
||||||
|
@ -480,4 +485,10 @@ namespace Hanabi {
|
||||||
return best_probability;
|
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
|
} // namespace Hanabi
|
Loading…
Reference in a new issue