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