LCOV - code coverage report
Current view: top level - envpool/minigrid/impl - minigrid_tasks.cc (source / functions) Coverage Total Hit
Test: EnvPool coverage report Lines: 99.0 % 390 386
Test Date: 2026-04-07 08:10:29 Functions: 100.0 % 34 34
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 62.9 % 475 299

             Branch data     Line data    Source code
       1                 :             : // Copyright 2026 Garena Online Private Limited
       2                 :             : //
       3                 :             : // Licensed under the Apache License, Version 2.0 (the "License");
       4                 :             : // you may not use this file except in compliance with the License.
       5                 :             : // You may obtain a copy of the License at
       6                 :             : //
       7                 :             : //      http://www.apache.org/licenses/LICENSE-2.0
       8                 :             : //
       9                 :             : // Unless required by applicable law or agreed to in writing, software
      10                 :             : // distributed under the License is distributed on an "AS IS" BASIS,
      11                 :             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12                 :             : // See the License for the specific language governing permissions and
      13                 :             : // limitations under the License.
      14                 :             : 
      15                 :             : #include <algorithm>
      16                 :             : #include <cmath>
      17                 :             : #include <string>
      18                 :             : #include <utility>
      19                 :             : #include <vector>
      20                 :             : 
      21                 :             : #include "envpool/minigrid/impl/minigrid_env.h"
      22                 :             : #include "envpool/minigrid/impl/minigrid_task_utils.h"
      23                 :             : 
      24                 :             : namespace minigrid {
      25                 :             : 
      26                 :          86 : EmptyTask::EmptyTask(int size, Pos agent_start_pos, int agent_start_dir,
      27                 :          86 :                      int max_steps, int agent_view_size)
      28                 :             :     : MiniGridTask("empty", max_steps, agent_view_size, true, 6),
      29                 :          86 :       size_(size),
      30                 :          86 :       agent_start_pos_(std::move(agent_start_pos)),
      31         [ +  - ]:          86 :       agent_start_dir_(agent_start_dir) {
      32                 :          86 : }  // NOLINT(whitespace/indent_namespace)
      33                 :             : 
      34                 :          99 : void EmptyTask::GenGrid() {
      35                 :          99 :   ClearGrid(size_, size_);
      36                 :          99 :   WallRect(0, 0, size_, size_);
      37         [ +  - ]:          99 :   PutObj(WorldObj(kGoal, kGreen), size_ - 2, size_ - 2);
      38         [ +  + ]:          99 :   goal_pos_ = {size_ - 2, size_ - 2};
      39         [ +  + ]:          99 :   if (agent_start_pos_.first >= 0) {
      40                 :             :     agent_pos_ = agent_start_pos_;
      41                 :          60 :     agent_dir_ = agent_start_dir_;
      42                 :             :   } else {
      43                 :          39 :     PlaceAgent(1, 1, size_ - 2, size_ - 2, true);
      44                 :             :   }
      45                 :          99 :   SetMission("get to the green goal square", 0);
      46                 :          99 : }
      47                 :             : 
      48                 :          64 : DoorKeyTask::DoorKeyTask(int size, int max_steps)
      49         [ +  - ]:         128 :     : MiniGridTask("doorkey", max_steps, 7, false, 6), size_(size) {}
      50                 :             : 
      51                 :          64 : void DoorKeyTask::GenGrid() {
      52                 :          64 :   ClearGrid(size_, size_);
      53                 :          64 :   WallRect(0, 0, size_, size_);
      54         [ +  - ]:          64 :   PutObj(WorldObj(kGoal, kGreen), size_ - 2, size_ - 2);
      55                 :          64 :   goal_pos_ = {size_ - 2, size_ - 2};
      56                 :          64 :   int split_idx = RandInt(2, size_ - 2);
      57                 :          64 :   VertWall(split_idx, 0);
      58                 :          64 :   PlaceAgent(0, 0, split_idx, size_, true);
      59                 :          64 :   int door_idx = RandInt(1, size_ - 2);
      60   [ +  -  +  - ]:         128 :   PutObj(MakeDoor(kYellow, true, false), split_idx, door_idx);
      61   [ +  -  -  +  :         128 :   PlaceObj(WorldObj(kKey, kYellow), 0, 0, split_idx, size_);
                   -  - ]
      62                 :          64 :   SetMission("use the key to open the door and then get to the goal", 0);
      63                 :          64 : }
      64                 :             : 
      65                 :          26 : DistShiftTask::DistShiftTask(int width, int height, Pos agent_start_pos,
      66                 :          26 :                              int agent_start_dir, int strip2_row, int max_steps)
      67                 :             :     : MiniGridTask("distshift", max_steps, 7, true, 6),
      68                 :          26 :       agent_start_pos_(std::move(agent_start_pos)),
      69                 :          26 :       agent_start_dir_(agent_start_dir),
      70         [ +  - ]:          26 :       strip2_row_(strip2_row) {
      71                 :          26 :   width_ = width;
      72                 :          26 :   height_ = height;
      73                 :          26 : }
      74                 :             : 
      75                 :          40 : void DistShiftTask::GenGrid() {
      76                 :          40 :   ClearGrid(width_, height_);
      77                 :          40 :   WallRect(0, 0, width_, height_);
      78         [ +  - ]:          40 :   PutObj(WorldObj(kGoal, kGreen), width_ - 2, 1);
      79                 :          40 :   goal_pos_ = {width_ - 2, 1};
      80         [ +  + ]:         160 :   for (int i = 0; i < width_ - 6; ++i) {
      81         [ +  - ]:         120 :     PutObj(WorldObj(kLava), 3 + i, 1);
      82         [ +  - ]:         240 :     PutObj(WorldObj(kLava), 3 + i, strip2_row_);
      83                 :             :   }
      84         [ +  - ]:          40 :   if (agent_start_pos_.first >= 0) {
      85                 :             :     agent_pos_ = agent_start_pos_;
      86                 :          40 :     agent_dir_ = agent_start_dir_;
      87                 :             :   } else {
      88                 :           0 :     PlaceAgent();
      89                 :             :   }
      90                 :          40 :   SetMission("get to the green goal square", 0);
      91                 :          40 : }
      92                 :             : 
      93                 :          39 : LavaGapTask::LavaGapTask(int size, Type obstacle_type, int max_steps)
      94                 :             :     : MiniGridTask("lavgap", max_steps, 7, false, 6),
      95                 :          39 :       size_(size),
      96         [ +  - ]:          78 :       obstacle_type_(obstacle_type) {}  // NOLINT(whitespace/indent_namespace)
      97                 :             : 
      98                 :          59 : void LavaGapTask::GenGrid() {
      99                 :          59 :   ClearGrid(size_, size_);
     100                 :          59 :   WallRect(0, 0, size_, size_);
     101                 :             :   agent_pos_ = {1, 1};
     102                 :          59 :   agent_dir_ = 0;
     103         [ +  - ]:          59 :   goal_pos_ = {size_ - 2, size_ - 2};
     104         [ +  - ]:          59 :   PutObj(WorldObj(kGoal, kGreen), goal_pos_.first, goal_pos_.second);
     105                 :          59 :   Pos gap_pos{RandInt(2, size_ - 2), RandInt(1, size_ - 1)};
     106                 :          59 :   VertWall(gap_pos.first, 1, size_ - 2, obstacle_type_,
     107                 :          59 :            DefaultColor(obstacle_type_));
     108                 :          59 :   SetEmpty(gap_pos.first, gap_pos.second);
     109         [ -  + ]:          59 :   SetMission(obstacle_type_ == kLava
     110                 :             :                  ? "avoid the lava and get to the green goal square"
     111                 :             :                  : "find the opening and get to the green goal square",
     112                 :             :              0);
     113                 :          59 : }
     114                 :             : 
     115                 :         104 : CrossingTask::CrossingTask(int size, int num_crossings, Type obstacle_type,
     116                 :         104 :                            int max_steps)
     117                 :             :     : MiniGridTask("crossing", max_steps, 7, false, 6),
     118                 :         104 :       size_(size),
     119                 :         104 :       num_crossings_(num_crossings),
     120         [ +  - ]:         208 :       obstacle_type_(obstacle_type) {}  // NOLINT(whitespace/indent_namespace)
     121                 :             : 
     122                 :         150 : void CrossingTask::GenGrid() {
     123   [ -  +  -  - ]:         150 :   CHECK_EQ(size_ % 2, 1);
     124                 :         150 :   ClearGrid(size_, size_);
     125                 :         150 :   WallRect(0, 0, size_, size_);
     126                 :             :   agent_pos_ = {1, 1};
     127                 :         150 :   agent_dir_ = 0;
     128         [ +  - ]:         150 :   goal_pos_ = {size_ - 2, size_ - 2};
     129         [ +  - ]:         300 :   PutObj(WorldObj(kGoal, kGreen), goal_pos_.first, goal_pos_.second);
     130                 :             : 
     131                 :         150 :   std::vector<std::pair<bool, int>> rivers;
     132         [ +  + ]:         643 :   for (int i = 2; i < size_ - 2; i += 2) {
     133         [ +  - ]:         493 :     rivers.emplace_back(true, i);
     134         [ +  - ]:         493 :     rivers.emplace_back(false, i);
     135                 :             :   }
     136                 :         150 :   std::shuffle(rivers.begin(), rivers.end(), *gen_ref_);
     137         [ +  - ]:         150 :   rivers.resize(num_crossings_);
     138                 :         150 :   std::vector<int> rivers_v;
     139                 :         150 :   std::vector<int> rivers_h;
     140         [ +  + ]:         580 :   for (const auto& river : rivers) {
     141         [ +  + ]:         430 :     if (river.first) {
     142         [ +  - ]:         187 :       rivers_v.push_back(river.second);
     143                 :             :     } else {
     144         [ +  - ]:         243 :       rivers_h.push_back(river.second);
     145                 :             :     }
     146                 :             :   }
     147                 :         150 :   std::sort(rivers_v.begin(), rivers_v.end());
     148                 :         150 :   std::sort(rivers_h.begin(), rivers_h.end());
     149         [ +  + ]:         393 :   for (int y : rivers_h) {
     150         [ +  + ]:        2186 :     for (int x = 1; x < size_ - 1; ++x) {
     151   [ +  -  +  - ]:        3886 :       PutObj(WorldObj(obstacle_type_), x, y);
     152                 :             :     }
     153                 :             :   }
     154         [ +  + ]:         338 :   for (int x : rivers_v) {
     155         [ +  + ]:        1683 :     for (int y = 1; y < size_ - 1; ++y) {
     156   [ +  -  +  - ]:        2990 :       PutObj(WorldObj(obstacle_type_), x, y);
     157                 :             :     }
     158                 :             :   }
     159                 :             : 
     160                 :             :   std::vector<bool> path;
     161         [ +  - ]:         150 :   path.insert(path.end(), rivers_v.size(), true);
     162         [ +  - ]:         149 :   path.insert(path.end(), rivers_h.size(), false);
     163                 :         150 :   std::shuffle(path.begin(), path.end(), *gen_ref_);
     164                 :             : 
     165   [ +  -  +  - ]:         300 :   std::vector<int> limits_v = {0};
     166                 :         150 :   limits_v.insert(limits_v.end(), rivers_v.begin(), rivers_v.end());
     167         [ +  - ]:         150 :   limits_v.push_back(size_ - 1);
     168   [ +  -  +  - ]:         150 :   std::vector<int> limits_h = {0};
     169                 :         150 :   limits_h.insert(limits_h.end(), rivers_h.begin(), rivers_h.end());
     170         [ +  - ]:         150 :   limits_h.push_back(size_ - 1);
     171                 :             :   int room_i = 0;
     172                 :             :   int room_j = 0;
     173                 :         150 :   for (bool is_horizontal_move : path) {
     174                 :             :     int x = 0;
     175                 :             :     int y = 0;
     176         [ +  + ]:         431 :     if (is_horizontal_move) {
     177         [ +  - ]:         188 :       x = limits_v[room_i + 1];
     178         [ +  - ]:         188 :       y = RandInt(limits_h[room_j] + 1, limits_h[room_j + 1]);
     179                 :             :       room_i += 1;
     180                 :             :     } else {
     181         [ +  - ]:         243 :       x = RandInt(limits_v[room_i] + 1, limits_v[room_i + 1]);
     182                 :         242 :       y = limits_h[room_j + 1];
     183                 :             :       room_j += 1;
     184                 :             :     }
     185         [ +  - ]:         430 :     SetEmpty(x, y);
     186                 :             :   }
     187   [ +  +  +  - ]:         352 :   SetMission(obstacle_type_ == kLava
     188                 :             :                  ? "avoid the lava and get to the green goal square"
     189                 :             :                  : "find the opening and get to the green goal square",
     190                 :             :              0);
     191                 :         150 : }
     192                 :             : 
     193                 :          86 : DynamicObstaclesTask::DynamicObstaclesTask(int size, Pos agent_start_pos,
     194                 :             :                                            int agent_start_dir, int n_obstacles,
     195                 :          86 :                                            int max_steps)
     196                 :             :     : MiniGridTask("dynamic_obstacles", max_steps, 7, true, 2),
     197                 :          86 :       size_(size),
     198                 :          86 :       agent_start_pos_(std::move(agent_start_pos)),
     199                 :          86 :       agent_start_dir_(agent_start_dir),
     200   [ +  -  -  + ]:         172 :       n_obstacles_(n_obstacles <= size / 2 + 1 ? n_obstacles : size / 2) {
     201                 :          86 : }  // NOLINT(whitespace/indent_namespace)
     202                 :             : 
     203                 :         614 : void DynamicObstaclesTask::GenGrid() {
     204                 :         614 :   ClearGrid(size_, size_);
     205                 :         614 :   WallRect(0, 0, size_, size_);
     206         [ +  - ]:         614 :   PutObj(WorldObj(kGoal, kGreen), size_ - 2, size_ - 2);
     207         [ +  + ]:         614 :   goal_pos_ = {size_ - 2, size_ - 2};
     208         [ +  + ]:         614 :   if (agent_start_pos_.first >= 0) {
     209                 :             :     agent_pos_ = agent_start_pos_;
     210                 :         371 :     agent_dir_ = agent_start_dir_;
     211                 :             :   } else {
     212                 :         243 :     PlaceAgent();
     213                 :             :   }
     214                 :             :   obstacle_pos_.clear();
     215         [ +  + ]:        2611 :   for (int i = 0; i < n_obstacles_; ++i) {
     216   [ +  -  -  +  :        3994 :     obstacle_pos_.push_back(PlaceObj(WorldObj(kBall, kBlue), 0, 0, width_,
                   -  - ]
     217                 :        1997 :                                      height_, RejectFn(), 100));
     218                 :             :   }
     219                 :         614 :   SetMission("get to the green goal square", 0);
     220                 :         614 : }
     221                 :             : 
     222                 :        3163 : void DynamicObstaclesTask::BeforeStep(Act act, const WorldObj& pre_fwd) {
     223   [ +  +  +  +  :        3163 :   pre_front_blocked_ = act == kForward && pre_fwd.GetType() != kGoal &&
                   +  + ]
     224                 :             :                        pre_fwd.GetType() != kEmpty;
     225                 :        3163 :   std::vector<Pos> new_pos = obstacle_pos_;
     226         [ +  + ]:       14960 :   for (std::size_t i = 0; i < obstacle_pos_.size(); ++i) {
     227                 :       11800 :     Pos old_pos = obstacle_pos_[i];
     228         [ -  + ]:       11800 :     int top_x = std::max(old_pos.first - 1, 0);
     229         [ -  + ]:       11800 :     int top_y = std::max(old_pos.second - 1, 0);
     230         [ -  + ]:       11800 :     int end_x = std::min(old_pos.first + 2, width_);
     231         [ -  + ]:       11800 :     int end_y = std::min(old_pos.second + 2, height_);
     232         [ +  - ]:       23379 :     for (int attempt = 0; attempt < 100; ++attempt) {
     233         [ +  - ]:       23379 :       int x = RandInt(top_x, end_x);
     234         [ +  - ]:       23401 :       int y = RandInt(top_y, end_y);
     235                 :             :       Pos pos{x, y};
     236   [ +  -  +  +  :       46784 :       if (GetCell(x, y).GetType() != kEmpty || pos == agent_pos_) {
                   +  + ]
     237                 :             :         continue;
     238                 :             :       }
     239         [ +  - ]:       11821 :       PutObj(WorldObj(kBall, kBlue), x, y);
     240         [ +  - ]:       11814 :       SetEmpty(old_pos.first, old_pos.second);
     241                 :             :       new_pos[i] = pos;
     242                 :             :       break;
     243                 :             :     }
     244                 :             :   }
     245         [ +  - ]:        3160 :   obstacle_pos_ = new_pos;
     246                 :        3155 : }
     247                 :             : 
     248                 :        3160 : void DynamicObstaclesTask::AfterStep(Act act, const WorldObj& pre_fwd,
     249                 :             :                                      const Pos& fwd_pos,
     250                 :             :                                      const WorldObj& pre_carrying,
     251                 :             :                                      float* reward, bool* terminated) {
     252   [ +  +  +  + ]:        3160 :   if (act == kForward && pre_front_blocked_) {
     253                 :         513 :     *reward = -1.0f;
     254                 :         513 :     *terminated = true;
     255                 :             :   }
     256                 :        3160 : }
     257                 :             : 
     258                 :        1224 : MiniGridDebugState DynamicObstaclesTask::DebugState() const {
     259                 :        1224 :   MiniGridDebugState state = MiniGridTask::DebugState();
     260         [ +  - ]:        1224 :   state.obstacle_positions.reserve(obstacle_pos_.size() * 2);
     261         [ +  + ]:        5712 :   for (const Pos& pos : obstacle_pos_) {
     262         [ +  - ]:        4488 :     state.obstacle_positions.push_back(pos.first);
     263         [ +  - ]:        4488 :     state.obstacle_positions.push_back(pos.second);
     264                 :             :   }
     265                 :        1224 :   return state;
     266                 :           0 : }
     267                 :             : 
     268                 :          47 : FetchTask::FetchTask(int size, int num_objs, int max_steps)
     269                 :             :     : MiniGridTask("fetch", max_steps, 7, true, 6),
     270                 :          47 :       size_(size),
     271         [ +  - ]:          94 :       num_objs_(num_objs) {}  // NOLINT(whitespace/indent_namespace)
     272                 :             : 
     273                 :          65 : void FetchTask::GenGrid() {
     274                 :          65 :   ClearGrid(size_, size_);
     275                 :          65 :   HorzWall(0, 0);
     276                 :          65 :   HorzWall(0, size_ - 1);
     277                 :          65 :   VertWall(0, 0);
     278                 :          65 :   VertWall(size_ - 1, 0);
     279                 :             :   std::vector<std::pair<Type, Color>> objs;
     280         [ +  + ]:         217 :   while (static_cast<int>(objs.size()) < num_objs_) {
     281   [ +  -  +  - ]:         152 :     Type type = RandElem(std::vector<Type>{kKey, kBall});
     282   [ +  -  -  + ]:         152 :     Color color = RandColor();
     283   [ +  -  -  +  :         304 :     PlaceObj(WorldObj(type, color));
                   -  - ]
     284         [ +  - ]:         152 :     objs.emplace_back(type, color);
     285                 :             :   }
     286         [ +  - ]:          65 :   PlaceAgent();
     287         [ +  - ]:          65 :   int target_idx = RandInt(0, static_cast<int>(objs.size()));
     288         [ +  - ]:          65 :   target_type_ = objs[target_idx].first;
     289                 :          65 :   target_color_ = objs[target_idx].second;
     290         [ +  - ]:          65 :   int syntax_idx = RandInt(0, 5);
     291         [ +  - ]:          65 :   SetMission(MissionFetch(syntax_idx, target_color_, target_type_),
     292                 :          65 :              syntax_idx * 12 + static_cast<int>(target_color_) * 2 +
     293         [ +  + ]:          65 :                  (target_type_ == kBall ? 1 : 0));
     294                 :          65 : }
     295                 :             : 
     296         [ +  + ]:        1832 : void FetchTask::AfterStep(Act act, const WorldObj& pre_fwd, const Pos& fwd_pos,
     297                 :             :                           const WorldObj& pre_carrying, float* reward,
     298                 :             :                           bool* terminated) {
     299         [ +  + ]:        1832 :   if (carrying_.GetType() == kEmpty) {
     300                 :             :     return;
     301                 :             :   }
     302                 :          18 :   *terminated = true;
     303         [ +  + ]:          18 :   if (carrying_.GetType() == target_type_ &&
     304         [ +  + ]:          16 :       carrying_.GetColor() == target_color_) {
     305                 :          14 :     *reward = SuccessReward();
     306                 :             :   } else {
     307                 :           4 :     *reward = 0.0f;
     308                 :             :   }
     309                 :             : }
     310                 :             : 
     311                 :          39 : GoToDoorTask::GoToDoorTask(int size, int max_steps)
     312         [ +  - ]:          78 :     : MiniGridTask("goto_door", max_steps, 7, true, 6), size_(size) {}
     313                 :             : 
     314                 :         480 : void GoToDoorTask::GenGrid() {
     315                 :         480 :   ClearGrid(size_, size_);
     316                 :         481 :   int active_width = RandInt(5, size_ + 1);
     317                 :         481 :   int active_height = RandInt(5, size_ + 1);
     318                 :         481 :   WallRect(0, 0, active_width, active_height);
     319                 :             :   std::vector<Pos> door_pos = {
     320                 :         481 :       {RandInt(2, active_width - 2), 0},
     321                 :         481 :       {RandInt(2, active_width - 2), active_height - 1},
     322                 :         481 :       {0, RandInt(2, active_height - 2)},
     323                 :         481 :       {active_width - 1, RandInt(2, active_height - 2)},
     324                 :         481 :   };
     325                 :             :   std::vector<Color> door_colors;
     326         [ +  + ]:        3132 :   while (static_cast<int>(door_colors.size()) <
     327                 :             :          static_cast<int>(door_pos.size())) {
     328   [ +  -  +  + ]:        2651 :     Color color = RandColor();
     329         [ +  + ]:        2654 :     if (std::find(door_colors.begin(), door_colors.end(), color) !=
     330                 :             :         door_colors.end()) {
     331                 :         732 :       continue;
     332                 :             :     }
     333         [ +  - ]:        1922 :     door_colors.push_back(color);
     334                 :             :   }
     335         [ +  + ]:        2404 :   for (std::size_t i = 0; i < door_pos.size(); ++i) {
     336   [ -  +  +  - ]:        3846 :     PutObj(MakeDoor(door_colors[i], false, false), door_pos[i].first,
     337                 :             :            door_pos[i].second);
     338                 :             :   }
     339         [ +  - ]:         481 :   PlaceAgent(0, 0, active_width, active_height, true);
     340         [ +  - ]:         481 :   int door_idx = RandInt(0, static_cast<int>(door_pos.size()));
     341         [ +  - ]:         481 :   target_pos_ = door_pos[door_idx];
     342                 :         481 :   target_type_ = kDoor;
     343                 :         481 :   target_color_ = door_colors[door_idx];
     344         [ +  - ]:         481 :   SetMission(MissionGoToDoor(target_color_), static_cast<int>(target_color_));
     345                 :         480 : }
     346                 :             : 
     347                 :        1397 : void GoToDoorTask::AfterStep(Act act, const WorldObj& pre_fwd,
     348                 :             :                              const Pos& fwd_pos, const WorldObj& pre_carrying,
     349                 :             :                              float* reward, bool* terminated) {
     350         [ +  + ]:        1397 :   if (act == kToggle) {
     351                 :         232 :     *terminated = true;
     352                 :         232 :     return;
     353                 :             :   }
     354         [ +  + ]:        1165 :   if (act == kDone) {
     355                 :             :     if (IsAdjacent(agent_pos_, target_pos_)) {
     356                 :          31 :       *reward = SuccessReward();
     357                 :             :     }
     358                 :         211 :     *terminated = true;
     359                 :             :   }
     360                 :             : }
     361                 :             : 
     362                 :          26 : GoToObjectTask::GoToObjectTask(int size, int num_objs, int max_steps)
     363                 :             :     : MiniGridTask("goto_object", max_steps, 7, true, 6),
     364                 :          26 :       size_(size),
     365         [ +  - ]:          52 :       num_objs_(num_objs) {}  // NOLINT(whitespace/indent_namespace)
     366                 :             : 
     367                 :         320 : void GoToObjectTask::GenGrid() {
     368                 :         320 :   ClearGrid(size_, size_);
     369                 :         320 :   WallRect(0, 0, size_, size_);
     370                 :             :   std::vector<std::pair<Type, Color>> objs;
     371                 :             :   std::vector<Pos> positions;
     372         [ +  + ]:         972 :   while (static_cast<int>(objs.size()) < num_objs_) {
     373                 :             :     Type type =
     374   [ +  -  +  - ]:         652 :         RandElem(std::vector<Type>(kObjectTypes.begin(), kObjectTypes.end()));
     375   [ +  -  +  + ]:         651 :     Color color = RandColor();
     376         [ +  + ]:         651 :     if (std::find(objs.begin(), objs.end(),
     377         [ +  + ]:         651 :                   std::pair<Type, Color>{type, color}) != objs.end()) {
     378                 :          12 :       continue;
     379                 :             :     }
     380   [ +  -  -  +  :        1279 :     positions.push_back(PlaceObj(WorldObj(type, color)));
                   -  - ]
     381         [ +  - ]:         640 :     objs.emplace_back(type, color);
     382                 :             :   }
     383         [ +  - ]:         320 :   PlaceAgent();
     384         [ +  - ]:         320 :   int idx = RandInt(0, static_cast<int>(objs.size()));
     385      [ +  +  + ]:         320 :   target_pos_ = positions[idx];
     386                 :         320 :   target_type_ = objs[idx].first;
     387                 :         320 :   target_color_ = objs[idx].second;
     388                 :         320 :   SetMission(
     389         [ +  - ]:         320 :       MissionGoToObject(target_color_, target_type_),
     390      [ +  +  + ]:         320 :       static_cast<int>(target_color_) * 3 + MissionObjectIndex(target_type_));
     391                 :         320 : }
     392                 :             : 
     393                 :         934 : void GoToObjectTask::AfterStep(Act act, const WorldObj& pre_fwd,
     394                 :             :                                const Pos& fwd_pos, const WorldObj& pre_carrying,
     395                 :             :                                float* reward, bool* terminated) {
     396         [ +  + ]:         934 :   if (act == kToggle) {
     397                 :         154 :     *terminated = true;
     398                 :         154 :     return;
     399                 :             :   }
     400         [ +  + ]:         780 :   if (act == kDone) {
     401                 :             :     if (IsAdjacent(agent_pos_, target_pos_)) {
     402                 :          19 :       *reward = SuccessReward();
     403                 :             :     }
     404                 :         140 :     *terminated = true;
     405                 :             :   }
     406                 :             : }
     407                 :             : 
     408                 :          34 : PutNearTask::PutNearTask(int size, int num_objs, int max_steps)
     409                 :             :     : MiniGridTask("put_near", max_steps, 7, true, 6),
     410                 :          34 :       size_(size),
     411         [ +  - ]:          68 :       num_objs_(num_objs) {}  // NOLINT(whitespace/indent_namespace)
     412                 :             : 
     413                 :          70 : void PutNearTask::GenGrid() {
     414                 :          70 :   ClearGrid(size_, size_);
     415                 :          69 :   HorzWall(0, 0);
     416                 :          69 :   HorzWall(0, size_ - 1);
     417                 :          69 :   VertWall(0, 0);
     418                 :          70 :   VertWall(size_ - 1, 0);
     419                 :             :   std::vector<std::pair<Type, Color>> objs;
     420                 :             :   std::vector<Pos> positions;
     421                 :         227 :   auto near_existing = [&](const Pos& candidate) {
     422                 :         227 :     return std::any_of(positions.begin(), positions.end(), [&](const Pos& pos) {
     423   [ -  -  -  -  :         200 :       return std::abs(pos.first - candidate.first) <= 1 &&
          -  -  -  -  -  
             -  +  +  +  
                      + ]
     424   [ -  -  -  -  :         107 :              std::abs(pos.second - candidate.second) <= 1;
          -  -  -  -  -  
             -  +  +  +  
                      + ]
     425                 :         227 :     });
     426                 :             :   };
     427         [ +  + ]:         256 :   while (static_cast<int>(objs.size()) < num_objs_) {
     428                 :             :     Type type =
     429   [ +  -  +  - ]:         186 :         RandElem(std::vector<Type>(kObjectTypes.begin(), kObjectTypes.end()));
     430   [ +  -  +  + ]:         186 :     Color color = RandColor();
     431         [ +  + ]:         186 :     if (std::find(objs.begin(), objs.end(),
     432         [ +  + ]:         186 :                   std::pair<Type, Color>{type, color}) != objs.end()) {
     433                 :          10 :       continue;
     434                 :             :     }
     435                 :             :     positions.push_back(
     436   [ -  +  +  -  :         351 :         PlaceObj(WorldObj(type, color), 0, 0, width_, height_, near_existing));
             +  -  -  - ]
     437         [ +  - ]:         176 :     objs.emplace_back(type, color);
     438                 :             :   }
     439         [ +  - ]:          70 :   PlaceAgent();
     440         [ +  - ]:          70 :   int move_idx = RandInt(0, static_cast<int>(objs.size()));
     441                 :          70 :   move_pos_ = positions[move_idx];
     442                 :          70 :   move_type_ = objs[move_idx].first;
     443                 :          70 :   move_color_ = objs[move_idx].second;
     444                 :             :   int target_idx = move_idx;
     445         [ +  + ]:         212 :   while (target_idx == move_idx) {
     446         [ +  - ]:         142 :     target_idx = RandInt(0, static_cast<int>(objs.size()));
     447                 :             :   }
     448      [ +  +  + ]:          70 :   target_pos_ = positions[target_idx];
     449                 :          70 :   target_type_ = objs[target_idx].first;
     450                 :          70 :   target_color_ = objs[target_idx].second;
     451                 :          70 :   SetMission(
     452         [ +  - ]:          70 :       MissionPutNear(move_color_, move_type_, target_color_, target_type_),
     453      [ +  +  + ]:          70 :       ((static_cast<int>(move_color_) * 3 + MissionObjectIndex(move_type_)) *
     454                 :          70 :        18) +
     455      [ +  +  + ]:          70 :           (static_cast<int>(target_color_) * 3) +
     456                 :             :           MissionObjectIndex(target_type_));
     457                 :          69 : }
     458                 :             : 
     459                 :        1198 : void PutNearTask::AfterStep(Act act, const WorldObj& pre_fwd,
     460                 :             :                             const Pos& fwd_pos, const WorldObj& pre_carrying,
     461                 :             :                             float* reward, bool* terminated) {
     462   [ +  +  +  + ]:        1198 :   if (act == kPickup && carrying_.GetType() != kEmpty &&
     463         [ +  + ]:          25 :       (carrying_.GetType() != move_type_ ||
     464         [ +  + ]:          22 :        carrying_.GetColor() != move_color_)) {
     465                 :           7 :     *terminated = true;
     466                 :           7 :     return;
     467                 :             :   }
     468   [ +  +  +  + ]:        1191 :   if (act == kDrop && pre_carrying.GetType() != kEmpty) {
     469         [ +  + ]:          16 :     if (GetCell(fwd_pos.first, fwd_pos.second) == pre_carrying &&
     470         [ +  + ]:           8 :         std::abs(fwd_pos.first - target_pos_.first) <= 1 &&
     471         [ +  + ]:           7 :         std::abs(fwd_pos.second - target_pos_.second) <= 1) {
     472                 :           4 :       *reward = SuccessReward();
     473                 :             :     }
     474                 :           8 :     *terminated = true;
     475                 :             :   }
     476                 :             : }
     477                 :             : 
     478                 :          26 : RedBlueDoorTask::RedBlueDoorTask(int size, int max_steps)
     479         [ +  - ]:          52 :     : MiniGridTask("red_blue_door", max_steps, 7, false, 6), size_(size) {}
     480                 :             : 
     481                 :          28 : void RedBlueDoorTask::GenGrid() {
     482                 :          28 :   ClearGrid(2 * size_, size_);
     483                 :          28 :   WallRect(0, 0, 2 * size_, size_);
     484                 :          28 :   WallRect(size_ / 2, 0, size_, size_);
     485                 :          28 :   PlaceAgent(size_ / 2, 0, size_, size_, true);
     486                 :          28 :   red_door_pos_ = {size_ / 2, RandInt(1, size_ - 1)};
     487                 :          28 :   blue_door_pos_ = {size_ / 2 + size_ - 1, RandInt(1, size_ - 1)};
     488         [ +  - ]:          28 :   PutObj(MakeDoor(kRed, false, false), red_door_pos_.first,
     489                 :             :          red_door_pos_.second);
     490         [ +  - ]:          28 :   PutObj(MakeDoor(kBlue, false, false), blue_door_pos_.first,
     491                 :             :          blue_door_pos_.second);
     492                 :          28 :   SetMission("open the red door then the blue door", 0);
     493                 :          28 : }
     494                 :             : 
     495                 :        1225 : void RedBlueDoorTask::BeforeStep(Act act, const WorldObj& pre_fwd) {
     496         [ -  + ]:        1224 :   red_open_before_ =
     497                 :        1225 :       GetCell(red_door_pos_.first, red_door_pos_.second).GetDoorOpen();
     498         [ -  + ]:        1226 :   blue_open_before_ =
     499                 :        1224 :       GetCell(blue_door_pos_.first, blue_door_pos_.second).GetDoorOpen();
     500                 :        1226 : }
     501                 :             : 
     502                 :        1226 : void RedBlueDoorTask::AfterStep(Act act, const WorldObj& pre_fwd,
     503                 :             :                                 const Pos& fwd_pos,
     504                 :             :                                 const WorldObj& pre_carrying, float* reward,
     505                 :             :                                 bool* terminated) {
     506                 :             :   bool red_open_after =
     507                 :        1226 :       GetCell(red_door_pos_.first, red_door_pos_.second).GetDoorOpen();
     508                 :             :   bool blue_open_after =
     509                 :        1225 :       GetCell(blue_door_pos_.first, blue_door_pos_.second).GetDoorOpen();
     510         [ +  + ]:        1225 :   if (blue_open_after) {
     511         [ -  + ]:           2 :     if (red_open_before_) {
     512                 :           0 :       *reward = SuccessReward();
     513                 :             :     }
     514                 :           2 :     *terminated = true;
     515   [ +  +  -  + ]:        1223 :   } else if (red_open_after && blue_open_before_) {
     516                 :           0 :     *terminated = true;
     517                 :             :   }
     518                 :        1225 : }
     519                 :             : 
     520                 :          21 : LockedRoomTask::LockedRoomTask(int size, int max_steps)
     521         [ +  - ]:          42 :     : MiniGridTask("locked_room", max_steps, 7, false, 6), size_(size) {}
     522                 :             : 
     523                 :          21 : void LockedRoomTask::GenGrid() {
     524                 :          21 :   ClearGrid(size_, size_);
     525         [ +  + ]:         420 :   for (int i = 0; i < size_; ++i) {
     526         [ +  - ]:         399 :     PutObj(WorldObj(kWall, kGrey), i, 0);
     527         [ +  - ]:         798 :     PutObj(WorldObj(kWall, kGrey), i, size_ - 1);
     528                 :             :   }
     529         [ +  + ]:         420 :   for (int j = 0; j < size_; ++j) {
     530         [ +  - ]:         399 :     PutObj(WorldObj(kWall, kGrey), 0, j);
     531         [ +  - ]:         798 :     PutObj(WorldObj(kWall, kGrey), size_ - 1, j);
     532                 :             :   }
     533                 :          21 :   int left_wall = size_ / 2 - 2;
     534                 :          21 :   int right_wall = size_ / 2 + 2;
     535         [ +  + ]:         420 :   for (int j = 0; j < size_; ++j) {
     536   [ +  -  +  - ]:         798 :     PutObj(WorldObj(kWall, kGrey), left_wall, j);
     537         [ +  - ]:         798 :     PutObj(WorldObj(kWall, kGrey), right_wall, j);
     538                 :             :   }
     539                 :             :   struct LockedRoomInfo {
     540                 :             :     Pos top;
     541                 :             :     Pos size;
     542                 :             :     Pos door_pos;
     543                 :             :     Color color{kRed};
     544                 :             :     bool locked{false};
     545                 :             :   };
     546                 :             :   std::vector<LockedRoomInfo> rooms;
     547         [ +  + ]:          84 :   for (int n = 0; n < 3; ++n) {
     548                 :          63 :     int j = n * (size_ / 3);
     549         [ +  + ]:         504 :     for (int i = 0; i < left_wall; ++i) {
     550         [ +  - ]:         882 :       PutObj(WorldObj(kWall, kGrey), i, j);
     551                 :             :     }
     552         [ +  + ]:         566 :     for (int i = right_wall; i < size_; ++i) {
     553         [ +  - ]:        1006 :       PutObj(WorldObj(kWall, kGrey), i, j);
     554                 :             :     }
     555                 :          63 :     int room_w = left_wall + 1;
     556         [ +  - ]:          63 :     int room_h = size_ / 3 + 1;
     557                 :          63 :     rooms.emplace_back(
     558   [ +  -  +  - ]:          63 :         LockedRoomInfo{{0, j}, {room_w, room_h}, {left_wall, j + 3}});
     559                 :          63 :     rooms.emplace_back(
     560         [ +  - ]:          63 :         LockedRoomInfo{{right_wall, j}, {room_w, room_h}, {right_wall, j + 3}});
     561                 :             :   }
     562         [ +  - ]:          21 :   int locked_idx = RandInt(0, static_cast<int>(rooms.size()));
     563         [ +  - ]:          21 :   rooms[locked_idx].locked = true;
     564                 :             :   goal_pos_ = {
     565                 :          21 :       RandInt(rooms[locked_idx].top.first + 1,
     566         [ +  - ]:          21 :               rooms[locked_idx].top.first + rooms[locked_idx].size.first - 1),
     567                 :          21 :       RandInt(
     568                 :             :           rooms[locked_idx].top.second + 1,
     569         [ +  - ]:          21 :           rooms[locked_idx].top.second + rooms[locked_idx].size.second - 1)};
     570         [ +  - ]:          21 :   PutObj(WorldObj(kGoal, kGreen), goal_pos_.first, goal_pos_.second);
     571         [ +  - ]:          21 :   std::vector<Color> colors(kColors.begin(), kColors.end());
     572         [ +  + ]:         147 :   for (auto& room : rooms) {
     573         [ +  - ]:         126 :     int idx = RandInt(0, static_cast<int>(colors.size()));
     574                 :         126 :     room.color = colors[idx];
     575                 :             :     colors.erase(colors.begin() + idx);
     576   [ -  +  +  - ]:         252 :     PutObj(MakeDoor(room.color, room.locked, false), room.door_pos.first,
     577                 :             :            room.door_pos.second);
     578                 :             :   }
     579                 :             :   int key_room_idx = locked_idx;
     580         [ +  + ]:          54 :   while (key_room_idx == locked_idx) {
     581         [ +  - ]:          33 :     key_room_idx = RandInt(0, static_cast<int>(rooms.size()));
     582                 :             :   }
     583                 :          21 :   Pos key_pos{RandInt(rooms[key_room_idx].top.first + 1,
     584         [ +  - ]:          21 :                       rooms[key_room_idx].top.first +
     585         [ +  - ]:          21 :                           rooms[key_room_idx].size.first - 1),
     586                 :          21 :               RandInt(rooms[key_room_idx].top.second + 1,
     587                 :          21 :                       rooms[key_room_idx].top.second +
     588         [ +  - ]:          21 :                           rooms[key_room_idx].size.second - 1)};
     589   [ -  +  +  - ]:          21 :   PutObj(WorldObj(kKey, rooms[locked_idx].color), key_pos.first,
     590                 :             :          key_pos.second);
     591         [ +  - ]:          21 :   PlaceAgent(left_wall, 0, right_wall - left_wall, size_, true);
     592                 :             :   SetMission(
     593         [ +  - ]:          21 :       MissionLockedRoom(rooms[locked_idx].color, rooms[key_room_idx].color), 0);
     594                 :          21 : }
     595                 :             : 
     596                 :             : }  // namespace minigrid
        

Generated by: LCOV version 2.0-1