in csrc/HleUtils.h [231:319]
std::vector<float> encodeLastAction(
const Hanabi::Server &server,
Move lastMove,
Hanabi::Card lastCard, // for play/discard
Hanabi::CardIndices lastMoveIndices, // for hint color/rank
int prevScore,
int prevNumHint) {
std::vector<float> lastAction(lastActionSectionLen_, 0);
// first step, no prev action
if (lastMove.type == INVALID_MOVE) {
return lastAction;
}
int me = server.whoAmI();
int offset = 0;
int lastActivePlayer = (server.activePlayer() + numPlayers_ - 1) % numPlayers_;
assert(lastActivePlayer < numPlayers_);
int relativeIdx = (numPlayers_ + lastActivePlayer - me) % numPlayers_;
lastAction[relativeIdx] = 1;
offset += numPlayers_;
// move type
int typeIdx = (int)lastMove.type;
assert(typeIdx >= 0 && typeIdx < numMoveTypes_);
lastAction[offset + typeIdx] = 1;
offset += numMoveTypes_;
// target player idx
// std::cout << "lastMove.to " << lastMove.to << std::endl;
if (lastMove.type == HINT_COLOR || lastMove.type == HINT_VALUE) {
// std::cout << "@@@hint" << std::endl;
assert(lastMove.to >= 0 && lastMove.to < numPlayers_);
int targetPlayer = (lastMove.to + numPlayers_ - me) % numPlayers_;
// if (targetPlayer == 1) {
// std::cout << "@@@" << lastMove.to << ", " << lastActivePlayer << ", " << me << std::endl;
// }
lastAction[offset + targetPlayer] = 1;
}
offset += numPlayers_;
// color revealed
if (lastMove.type == HINT_COLOR) {
lastAction[offset + lastMove.value] = 1;
}
offset += numColors_;
// value revealed
if (lastMove.type == HINT_VALUE) {
lastAction[offset + lastMove.value - 1] = 1;
}
offset += numRanks_;
// reveal outcome
if (lastMove.type == HINT_VALUE || lastMove.type == HINT_COLOR) {
for (int i = 0; i < handSize_; ++i) {
if (lastMoveIndices.contains(i)) {
lastAction[offset + i] = 1;
}
}
}
offset += handSize_;
// position played/discarded
if (lastMove.type == PLAY_CARD || lastMove.type == DISCARD_CARD) {
// std::cout << "last move index: " << lastMoveIndex << std::endl;
lastAction[offset + lastMove.value] = 1;
}
offset += handSize_;
// card played/discarded
if (lastMove.type == PLAY_CARD || lastMove.type == DISCARD_CARD) {
lastAction[offset + cardToIndex(lastCard)] = 1;
}
offset += bitsPerCard_;
// std::cout << offset << ", " << LAST_ACTION_SIZE << std::endl;
// whether success play
if (lastMove.type == PLAY_CARD) {
if (server.currentScore() > prevScore) {
lastAction[offset] = 1;
}
if (server.hintStonesRemaining() > prevNumHint) {
lastAction[offset + 1] = 1;
}
}
offset += 2;
assert(offset == lastActionSectionLen_);
return lastAction;
}