std::vector encodeLastAction()

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;
  }