You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

109 lines
3.7 KiB

from __future__ import annotations
from minigrid.core.grid import Grid
from minigrid.core.mission import MissionSpace
from minigrid.core.world_object import Door, Goal, Key
from minigrid.minigrid_env import MiniGridEnv
class DoubleDoorEnv(MiniGridEnv):
"""
## Description
This environment has a key that the agent must pick up in order to unlock a
goal and then get to the green goal square. This environment is difficult,
because of the sparse reward, to solve using classical RL algorithms. It is
useful to experiment with curiosity or curriculum learning.
## Mission Space
"use the key to open the door and then get to the goal"
## Action Space
| Num | Name | Action |
|-----|--------------|---------------------------|
| 0 | left | Turn left |
| 1 | right | Turn right |
| 2 | forward | Move forward |
| 3 | pickup | Pick up an object |
| 4 | drop | Unused |
| 5 | toggle | Toggle/activate an object |
| 6 | done | Unused |
## Observation Encoding
- Each tile is encoded as a 3 dimensional tuple:
`(OBJECT_IDX, COLOR_IDX, STATE)`
- `OBJECT_TO_IDX` and `COLOR_TO_IDX` mapping can be found in
[minigrid/minigrid.py](minigrid/minigrid.py)
- `STATE` refers to the door state with 0=open, 1=closed and 2=locked
## Rewards
A reward of '1 - 0.9 * (step_count / max_steps)' is given for success, and '0' for failure.
## Termination
The episode ends if any one of the following conditions is met:
1. The agent reaches the goal.
2. Timeout (see `max_steps`).
## Registered Configurations
- `MiniGrid-DoubleDoor-16x16-v0`
- `MiniGrid-DoubleDoor-12x12-v0`
- `MiniGrid-DoubleDoor-10x8-v0`
"""
def __init__(self, width=8, height=8, max_steps: int | None = None, **kwargs):
if max_steps is None:
max_steps = 10 * (width * height)
mission_space = MissionSpace(mission_func=self._gen_mission)
super().__init__(
mission_space=mission_space, width=width, height=height, max_steps=max_steps, **kwargs
)
@staticmethod
def _gen_mission():
return "use the key to open the door and then get to the goal"
def _gen_grid(self, width, height):
# Create an empty grid
self.grid = Grid(width, height)
# Generate the surrounding walls
self.grid.wall_rect(0, 0, width, height)
# Place a goal in the bottom-right corner
self.put_obj(Goal(), width - 2, height - 2)
# Create first vertical splitting wall
# splitIdx = self._rand_int(2, width - 2)
splitIdxOne = width // 3
self.grid.vert_wall(splitIdxOne, 0)
# Place the agent at a random position and orientation
# on the left side of the splitting wall
self.place_agent(size=(splitIdxOne, height))
# Place a door in the wall
doorIdx = height // 2
self.put_obj(Door("yellow", is_locked=True), splitIdxOne, doorIdx)
self.place_obj(obj=Key("yellow"), top=(0, 0), size=(splitIdxOne, height))
# Create second vertical splitting wall
splitIdxTwo = (width // 3) * 2
self.grid.vert_wall(splitIdxTwo, 0)
doorIdx = height // 2
self.put_obj(Door("red", is_locked=True), splitIdxTwo, doorIdx)
self.place_obj(obj=Key("red"), top=(splitIdxOne, 0), size=(splitIdxTwo - splitIdxOne, height))
# Place a yellow key on the left side
self.mission = "use the key to open the door and then get to the goal"