in hanabi-learning-environment/hanabi_lib/canonical_encoders.cc [70:142]
int EncodeHands(const HanabiGame& game,
const HanabiObservation& obs,
int start_offset,
bool show_own_cards,
const std::vector<int>& order,
bool shuffle_color,
const std::vector<int>& color_permute,
std::vector<float>* encoding) {
int bits_per_card = BitsPerCard(game);
int num_ranks = game.NumRanks();
int num_players = game.NumPlayers();
int hand_size = game.HandSize();
int offset = start_offset;
const std::vector<HanabiHand>& hands = obs.Hands();
assert(hands.size() == num_players);
for (int player = 0; player < num_players; ++player) {
const std::vector<HanabiCard>& cards = hands[player].Cards();
int num_cards = 0;
// for (const HanabiCard& card : cards) {
for (int i = 0; i < cards.size(); ++i) {
int card_i = i;
if (player != 0 && order.size() > 0) {
card_i = order[i];
}
const auto& card = cards[card_i];
// Only a player's own cards can be invalid/unobserved.
// assert(card.IsValid());
assert(card.Color() < game.NumColors());
assert(card.Rank() < num_ranks);
if (player == 0) {
if (show_own_cards) {
assert(card.IsValid());
// std::cout << offset << CardIndex(card.Color(), card.Rank(), num_ranks) << std::endl;
// std::cout << card.Color() << ", " << card.Rank() << ", " << num_ranks << std::endl;
auto card_idx = CardIndex(
card.Color(), card.Rank(), num_ranks, shuffle_color, color_permute);
(*encoding).at(offset + card_idx) = 1;
} else {
assert(!card.IsValid());
// (*encoding).at(offset + CardIndex(card.Color(), card.Rank(), num_ranks)) = 0;
}
} else {
assert(card.IsValid());
auto card_idx = CardIndex(
card.Color(), card.Rank(), num_ranks, shuffle_color, color_permute);
(*encoding).at(offset + card_idx) = 1;
}
++num_cards;
offset += bits_per_card;
}
// A player's hand can have fewer cards than the initial hand size.
// Leave the bits for the absent cards empty (adjust the offset to skip
// bits for the missing cards).
if (num_cards < hand_size) {
offset += (hand_size - num_cards) * bits_per_card;
}
}
// For each player, set a bit if their hand is missing a card.
for (int player = 0; player < num_players; ++player) {
if (hands[player].Cards().size() < game.HandSize()) {
(*encoding)[offset + player] = 1;
}
}
offset += num_players;
assert(offset - start_offset == HandsSectionLength(game));
return offset - start_offset;
}