void AIBase::save_structured_state()

in rts/game_CF/ai.cc [13:82]


void AIBase::save_structured_state(const GameEnv &env, Data *data) const {
    GameState *game = &data->newest();
    game->tick = _receiver->GetTick();
    game->winner = env.GetWinnerId();
    game->terminal = env.GetTermination() ? 1 : 0;
    game->game_counter = env.GetGameCounter();
    game->player_id = _player_id;

    const int n_type = env.GetGameDef().GetNumUnitType();
    const int n_additional = 3;
    const int resource_grid = 1;
    const int res_pt = NUM_RES_SLOT;
    const int total_channel = n_type + n_additional + res_pt;

    const auto &m = env.GetMap();

    // [Channel, width, height]
    const int sz = total_channel * m.GetXSize() * m.GetYSize();
    game->s.resize(sz);
    std::fill(game->s.begin(), game->s.end(), 0.0);

    int players = env.GetNumOfPlayers();
    game->res.resize(players * res_pt);
    std::fill(game->res.begin(), game->res.end(), 0.0);

#define _OFFSET(_c, _x, _y) (((_c) * m.GetYSize() + (_y)) * m.GetXSize() + (_x))
#define _F(_c, _x, _y) game->s[_OFFSET(_c, _x, _y)]

    // Extra data.
    game->ai_start_tick = 0;
    auto unit_iter = env.GetUnitIterator(_player_id);
    std::vector<int> quantized_r(players, 0);

    while (! unit_iter.end()) {
        const Unit &u = *unit_iter;
        int x = int(u.GetPointF().x);
        int y = int(u.GetPointF().y);
        float hp_level = u.GetProperty()._hp / (u.GetProperty()._max_hp + 1e-6);
        UnitType t = u.GetUnitType();

        _F(t, x, y) = 1.0;
        _F(n_type, x, y) = u.GetPlayerId() + 1;
        _F(n_type + 1, x, y) = hp_level;
        _F(n_type + 2, x, y) = u.HasFlag();
        if (u.HasFlag()) game->flag_x = x;
        ++ unit_iter;
    }

    for (int i = 0; i < players; ++i) {
        if (_player_id != INVALID && _player_id != i) continue;
        const auto &player = env.GetPlayer(i);
        quantized_r[i] = min(int(player.GetResource() / resource_grid), res_pt - 1);
        game->res[i * res_pt + quantized_r[i]] = 1.0;
    }

    if (_player_id != INVALID) {
        const int c = _OFFSET(n_type + n_additional + quantized_r[_player_id], 0, 0);
        std::fill(game->s.begin() + c, game->s.begin() + c + m.GetXSize() * m.GetYSize(), 1.0);
    }

    game->last_r = 0.0;
    game->r0 = quantized_r[0];
    game->r1 = quantized_r[1];
    int winner = env.GetWinnerId();

    if (winner != INVALID) {
        if (winner == _player_id) game->last_r = 1.0;
        else game->last_r = -1.0;
    }
}