Fix id clashes: Normalize all card positions
This commit is contained in:
parent
27a45561e7
commit
cdf8575283
2 changed files with 45 additions and 13 deletions
|
@ -182,8 +182,12 @@ namespace Hanabi
|
|||
boost::container::static_vector<boost::container::static_vector<player_t, max_card_duplicity>
|
||||
, 30> card_positions_draw;
|
||||
|
||||
|
||||
// List of all non-trash cards in hands of base state
|
||||
boost::container::static_vector<Card, num_players * hand_size> good_cards_hands;
|
||||
|
||||
// This will indicate whether cards that were in hands initially still are in hand
|
||||
// The first n bits are used and cards are assumed to have been marked with their indices in this bitset
|
||||
// The first n entries are used and cards are assumed to have been marked with their indices in this vector
|
||||
boost::container::static_vector<CardPosition, num_players * hand_size> card_positions_hands{};
|
||||
|
||||
// Note this is not the same as _good_cards_draw.size(), since this accounts for multiplicities
|
||||
|
|
|
@ -583,6 +583,7 @@ namespace Hanabi
|
|||
num_useful_cards_in_starting_hands++;
|
||||
|
||||
good_cards_in_hand.push_back(card);
|
||||
_relative_representation.good_cards_hands.push_back(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1118,6 +1119,26 @@ namespace Hanabi
|
|||
}
|
||||
}
|
||||
|
||||
// encode positions of cards that started in hands
|
||||
ASSERT(_relative_representation.card_positions_hands.size() == _relative_representation.good_cards_hands.size());
|
||||
for(size_t i = 0; i < _relative_representation.card_positions_hands.size(); i++)
|
||||
{
|
||||
id *= 3;
|
||||
// we have to normalize here again and pretend that cards already played are all discarded.
|
||||
// Note that implicitly, this means that when we lose the last copy of a good card, this encoding pretends that
|
||||
// the card has been played already.
|
||||
// However, since we only ever consider actions that do not lose the last copy of a card, this is not a problem
|
||||
// (unless our base state was already lacking cards, in which case the card is never considered played in any state)
|
||||
if(is_trash(_relative_representation.good_cards_hands[i]))
|
||||
{
|
||||
id += static_cast<std::underlying_type_t<typename RelativeRepresentationData::CardPosition>>(RelativeRepresentationData::CardPosition::discarded);
|
||||
}
|
||||
else
|
||||
{
|
||||
id += static_cast<std::underlying_type_t<typename RelativeRepresentationData::CardPosition>>(_relative_representation.card_positions_hands[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// encode number of clues
|
||||
clue_t const scaled_clues = clue_t(2) * _num_clues;
|
||||
assert(scaled_clues.denominator() == 1);
|
||||
|
@ -1139,12 +1160,6 @@ namespace Hanabi
|
|||
id *= _relative_representation.initial_draw_pile_size + num_players;
|
||||
id += draw_pile_size_and_extra_turns;
|
||||
|
||||
// encode positions of cards that started in hands
|
||||
for (typename RelativeRepresentationData::CardPosition const & position: _relative_representation.card_positions_hands)
|
||||
{
|
||||
id *= 3;
|
||||
id += static_cast<std::underlying_type_t<typename RelativeRepresentationData::CardPosition>>(position);
|
||||
}
|
||||
|
||||
id *= num_players;
|
||||
id += _turn;
|
||||
|
@ -1185,6 +1200,25 @@ namespace Hanabi
|
|||
}
|
||||
}
|
||||
|
||||
// encode positions of cards that started in hands
|
||||
ASSERT(_relative_representation.card_positions_hands.size() == _relative_representation.good_cards_hands.size());
|
||||
for(size_t i = 0; i < _relative_representation.card_positions_hands.size(); i++)
|
||||
{
|
||||
// we have to normalize here again and pretend that cards already played are all discarded.
|
||||
// Note that implicitly, this means that when we lose the last copy of a good card, this encoding pretends that
|
||||
// the card has been played already.
|
||||
// However, since we only ever consider actions that do not lose the last copy of a card, this is not a problem
|
||||
// (unless our base state was already lacking cards, in which case the card is never considered played in any state)
|
||||
if(is_trash(_relative_representation.good_cards_hands[i]))
|
||||
{
|
||||
ret.push_back(static_cast<std::underlying_type_t<typename RelativeRepresentationData::CardPosition>>(RelativeRepresentationData::CardPosition::discarded));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.push_back(static_cast<std::underlying_type_t<typename RelativeRepresentationData::CardPosition>>(_relative_representation.card_positions_hands[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// encode number of clues
|
||||
clue_t const scaled_clues = clue_t(2) * _num_clues;
|
||||
assert(scaled_clues.denominator() == 1);
|
||||
|
@ -1204,12 +1238,6 @@ namespace Hanabi
|
|||
|
||||
ret.push_back(draw_pile_size_and_extra_turns);
|
||||
|
||||
// encode positions of cards that started in hands
|
||||
for (typename RelativeRepresentationData::CardPosition const & position: _relative_representation.card_positions_hands)
|
||||
{
|
||||
ret.push_back(static_cast<std::underlying_type_t<typename RelativeRepresentationData::CardPosition>>(position));
|
||||
}
|
||||
|
||||
ret.push_back(_turn);
|
||||
|
||||
// The id is unique now, since for all relevant cards, we know their position (including if they are played),
|
||||
|
|
Loading…
Reference in a new issue