void encode_board_state()

in dipcc/dipcc/cc/encoding.cc [106:232]


void encode_board_state(GameState &state, float *r) {
  memset(r, 0, 81 * BOARD_STATE_ENC_WIDTH * sizeof(float));

  //////////////////////////////////////
  // unit type, unit power, removable //
  //////////////////////////////////////

  std::vector<bool> filled(81, false);

  for (auto p : state.get_units()) {
    OwnedUnit unit = p.second;
    JCHECK(unit.type != UnitType::NONE, "UnitType::NONE");
    JCHECK(unit.loc != Loc::NONE, "Loc::NONE");
    JCHECK(unit.power != Power::NONE, "Power::NONE");

    bool removable =
        state.get_phase().season == 'W' && state.get_n_builds(unit.power) < 0;

    size_t loc_i = static_cast<int>(unit.loc) - 1;
    P_BOARD_STATE(r, loc_i, unit.type == UnitType::ARMY ? S_ARMY : S_FLEET) = 1;
    P_BOARD_STATE(r, loc_i, S_AUS + static_cast<int>(unit.power) - 1) = 1;
    P_BOARD_STATE(r, loc_i, S_REMOVABLE) = static_cast<float>(removable);
    filled[loc_i] = true;

    // Mark parent if it's a coast
    Loc rloc = root_loc(unit.loc);
    if (unit.loc != rloc) {
      size_t rloc_i = static_cast<int>(rloc) - 1;
      P_BOARD_STATE(r, rloc_i, unit.type == UnitType::ARMY ? S_ARMY : S_FLEET) =
          1;
      P_BOARD_STATE(r, rloc_i, S_AUS + static_cast<int>(unit.power) - 1) = 1;
      P_BOARD_STATE(r, rloc_i, S_REMOVABLE) = static_cast<float>(removable);
      filled[rloc_i] = true;
    }
  }

  // Set locs with no units
  for (int i = 0; i < 81; ++i) {
    if (!filled[i]) {
      P_BOARD_STATE(r, i, S_UNIT_NONE) = 1;
      P_BOARD_STATE(r, i, S_POW_NONE) = 1;
    }
  }

  ///////////////
  // buildable //
  ///////////////

  if (state.get_phase().phase_type == 'A') {
    for (auto &p : state.get_all_possible_orders()) {
      auto order = p.second.begin();
      if (order->get_type() == OrderType::B) {
        Loc loc = order->get_unit().loc;
        size_t loc_i = static_cast<int>(loc) - 1;
        P_BOARD_STATE(r, loc_i, S_BUILDABLE) = 1;
      }
    }
  }

  /////////////////////
  // dislodged units //
  /////////////////////

  std::fill(filled.begin(), filled.end(), false);
  for (OwnedUnit unit : state.get_dislodged_units()) {
    size_t loc_i = static_cast<int>(unit.loc) - 1;
    P_BOARD_STATE(r, loc_i,
                  unit.type == UnitType::ARMY ? S_DIS_ARMY : S_DIS_FLEET) = 1;
    P_BOARD_STATE(r, loc_i, S_DIS_AUS + static_cast<int>(unit.power) - 1) = 1;
    filled[loc_i] = true;

    // Mark parent if it's a coast
    Loc rloc = root_loc(unit.loc);
    if (unit.loc != rloc) {
      size_t rloc_i = static_cast<int>(rloc) - 1;
      P_BOARD_STATE(r, rloc_i,
                    unit.type == UnitType::ARMY ? S_DIS_ARMY : S_DIS_FLEET) = 1;
      P_BOARD_STATE(r, rloc_i, S_DIS_AUS + static_cast<int>(unit.power) - 1) =
          1;
      filled[rloc_i] = true;
    }
  }

  // Set locs with no dislodged units
  for (int i = 0; i < 81; ++i) {
    if (!filled[i]) {
      P_BOARD_STATE(r, i, S_DIS_UNIT_NONE) = 1;
      P_BOARD_STATE(r, i, S_DIS_POW_NONE) = 1;
    }
  }

  ///////////////
  // Area type //
  ///////////////

  for (int i = 0; i < 81; ++i) {
    Loc loc = LOCS[i];
    if (is_water(loc)) {
      P_BOARD_STATE(r, i, S_WATER) = 1;
    } else if (is_coast(loc)) {
      P_BOARD_STATE(r, i, S_COAST) = 1;
    } else {
      P_BOARD_STATE(r, i, S_LAND) = 1;
    }
  }

  ///////////////////
  // supply center //
  ///////////////////

  auto centers = state.get_centers();
  for (int i = 0; i < 81; ++i) {
    Loc loc = LOCS[i];
    if (!is_center(loc) || loc != root_loc(loc)) {
      continue;
    }

    auto it = centers.find(loc);
    Power power = it == centers.end() ? Power::NONE : it->second;
    int off = power == Power::NONE ? 7 : static_cast<int>(power) - 1;

    for (Loc cloc : expand_coasts(loc)) {
      int cloc_i = static_cast<int>(cloc) - 1;
      P_BOARD_STATE(r, cloc_i, S_SC_AUS + off) = 1;
    }
  }
} // encode_board_state