void encode_prev_orders()

in dipcc/dipcc/cc/encoding.cc [234:368]


void encode_prev_orders(PhaseData &phase_data, float *r) {
  JCHECK(phase_data.get_state().get_phase().phase_type == 'M',
         "encode_prev_orders called on non-movement phase");

  memset(r, 0, 81 * PREV_ORDERS_ENC_WIDTH * sizeof(float));

  // Store owner of each loc: unit owner if there is a unit, otherwise SC
  // owner, otherwise none (7)
  std::vector<int> loc_owner(81, 7);

  ////////////////////
  // supply centers //
  ////////////////////

  std::vector<bool> filled(81, false);
  for (auto &p : phase_data.get_state().get_centers()) {
    Loc loc = p.first;
    Power power = p.second;
    int power_i = static_cast<int>(power) - 1;
    for (Loc cloc : expand_coasts(loc)) {
      int cloc_i = static_cast<int>(cloc) - 1;

      loc_owner[cloc_i] = power_i;
      P_PREV_ORDERS(r, cloc_i, O_SC_AUS + power_i) = 1;
      filled[cloc_i] = true;
    }
  }

  // Set unowned SC
  for (int i = 0; i < 81; ++i) {
    Loc loc = LOCS[i];
    if (!filled[i] && is_center(root_loc(loc))) {
      P_PREV_ORDERS(r, i, O_SC_NONE) = 1;
    }
  }

  // set owner: units
  for (auto &p : phase_data.get_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");

    int power_i = static_cast<int>(unit.power) - 1;

    for (Loc cloc : expand_coasts(unit.loc)) {
      int cloc_i = static_cast<int>(cloc) - 1;
      loc_owner[cloc_i] = power_i;
    }
  }

  ////////////
  // orders //
  ////////////

  std::fill(filled.begin(), filled.end(), false);
  for (auto &it : phase_data.get_orders()) {
    Power power = it.first;
    for (auto &order : it.second) {
      Unit unit = order.get_unit();
      int loc_i = static_cast<int>(unit.loc) - 1;
      int rloc_i = static_cast<int>(root_loc(unit.loc)) - 1;

      if (phase_data.get_state().get_unit(unit.loc) != unit.owned_by(power)) {
        // ignore bad order
        continue;
      }

      // Unit type, power
      P_PREV_ORDERS(r, loc_i, unit.type == UnitType::ARMY ? O_ARMY : O_FLEET) =
          1;
      P_PREV_ORDERS(r, rloc_i, unit.type == UnitType::ARMY ? O_ARMY : O_FLEET) =
          1;
      P_PREV_ORDERS(r, loc_i, O_AUS + static_cast<int>(power) - 1) = 1;
      P_PREV_ORDERS(r, rloc_i, O_AUS + static_cast<int>(power) - 1) = 1;

      // Order Type
      OrderType order_type = order.get_type();
      int order_type_idx;
      if (order_type == OrderType::H) {
        order_type_idx = O_HOLD;
      } else if (order_type == OrderType::M) {
        order_type_idx = O_MOVE;
      } else if (order_type == OrderType::C) {
        order_type_idx = O_CONVOY;
      } else if (order_type == OrderType::SM || order_type == OrderType::SH) {
        order_type_idx = O_SUPPORT;
      } else {
        JFAIL("Unexpected order type");
      }
      P_PREV_ORDERS(r, loc_i, order_type_idx) = 1;
      P_PREV_ORDERS(r, rloc_i, order_type_idx) = 1;

      // Src power
      if (order_type == OrderType::SH || order_type == OrderType::SM ||
          order_type == OrderType::C) {
        int src_idx =
            O_SRC_AUS + loc_owner[static_cast<int>(order.get_target().loc) - 1];
        P_PREV_ORDERS(r, loc_i, src_idx) = 1;
        P_PREV_ORDERS(r, rloc_i, src_idx) = 1;
      } else {
        P_PREV_ORDERS(r, loc_i, O_SRC_NONE) = 1;
        P_PREV_ORDERS(r, rloc_i, O_SRC_NONE) = 1;
      }

      // Dest power
      if (order_type == OrderType::M || order_type == OrderType::SM ||
          order_type == OrderType::C) {
        int dest_idx =
            O_DEST_AUS + loc_owner[static_cast<int>(order.get_dest()) - 1];
        P_PREV_ORDERS(r, loc_i, dest_idx) = 1;
        P_PREV_ORDERS(r, rloc_i, dest_idx) = 1;
      } else {
        P_PREV_ORDERS(r, loc_i, O_DEST_NONE) = 1;
        P_PREV_ORDERS(r, rloc_i, O_DEST_NONE) = 1;
      }

      filled[loc_i] = true;
      filled[rloc_i] = true;
    } // for (order : orders)
  }   // for (power : powers)

  // Fill locations with no orders
  for (int i = 0; i < 81; ++i) {
    if (filled[i]) {
      continue;
    }

    P_PREV_ORDERS(r, i, O_UNIT_NONE) = 1;
    P_PREV_ORDERS(r, i, O_POW_NONE) = 1;
    P_PREV_ORDERS(r, i, O_ORDER_NONE) = 1;
    P_PREV_ORDERS(r, i, O_SRC_NONE) = 1;
    P_PREV_ORDERS(r, i, O_DEST_NONE) = 1;
  }
} // encode_prev_orders