redbluedoors.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. from gym_minigrid.minigrid import Door, Grid, MiniGridEnv, MissionSpace
  2. class RedBlueDoorEnv(MiniGridEnv):
  3. """
  4. ### Description
  5. The agent is randomly placed within a room with one red and one blue door
  6. facing opposite directions. The agent has to open the red door and then open
  7. the blue door, in that order. Note that, surprisingly, this environment is
  8. solvable without memory.
  9. ### Mission Space
  10. "open the red door then the blue door"
  11. ### Action Space
  12. | Num | Name | Action |
  13. |-----|--------------|---------------------------|
  14. | 0 | left | Turn left |
  15. | 1 | right | Turn right |
  16. | 2 | forward | Move forward |
  17. | 3 | pickup | Unused |
  18. | 4 | drop | Unused |
  19. | 5 | toggle | Toggle/activate an object |
  20. | 6 | done | Unused |
  21. ### Observation Encoding
  22. - Each tile is encoded as a 3 dimensional tuple:
  23. `(OBJECT_IDX, COLOR_IDX, STATE)`
  24. - `OBJECT_TO_IDX` and `COLOR_TO_IDX` mapping can be found in
  25. [gym_minigrid/minigrid.py](gym_minigrid/minigrid.py)
  26. - `STATE` refers to the door state with 0=open, 1=closed and 2=locked
  27. ### Rewards
  28. A reward of '1' is given for success, and '0' for failure.
  29. ### Termination
  30. The episode ends if any one of the following conditions is met:
  31. 1. The agent opens the blue door having already opened the red door.
  32. 2. The agent opens the blue door without having opened the red door yet.
  33. 3. Timeout (see `max_steps`).
  34. ### Registered Configurations
  35. - `MiniGrid-RedBlueDoors-6x6-v0`
  36. - `MiniGrid-RedBlueDoors-8x8-v0`
  37. """
  38. def __init__(self, size=8, **kwargs):
  39. self.size = size
  40. mission_space = MissionSpace(
  41. mission_func=lambda: "open the red door then the blue door"
  42. )
  43. super().__init__(
  44. mission_space=mission_space,
  45. width=2 * size,
  46. height=size,
  47. max_steps=20 * size * size,
  48. **kwargs
  49. )
  50. def _gen_grid(self, width, height):
  51. # Create an empty grid
  52. self.grid = Grid(width, height)
  53. # Generate the grid walls
  54. self.grid.wall_rect(0, 0, 2 * self.size, self.size)
  55. self.grid.wall_rect(self.size // 2, 0, self.size, self.size)
  56. # Place the agent in the top-left corner
  57. self.place_agent(top=(self.size // 2, 0), size=(self.size, self.size))
  58. # Add a red door at a random position in the left wall
  59. pos = self._rand_int(1, self.size - 1)
  60. self.red_door = Door("red")
  61. self.grid.set(self.size // 2, pos, self.red_door)
  62. # Add a blue door at a random position in the right wall
  63. pos = self._rand_int(1, self.size - 1)
  64. self.blue_door = Door("blue")
  65. self.grid.set(self.size // 2 + self.size - 1, pos, self.blue_door)
  66. # Generate the mission string
  67. self.mission = "open the red door then the blue door"
  68. def step(self, action):
  69. red_door_opened_before = self.red_door.is_open
  70. blue_door_opened_before = self.blue_door.is_open
  71. obs, reward, terminated, truncated, info = super().step(action)
  72. red_door_opened_after = self.red_door.is_open
  73. blue_door_opened_after = self.blue_door.is_open
  74. if blue_door_opened_after:
  75. if red_door_opened_before:
  76. reward = self._reward()
  77. terminated = True
  78. else:
  79. reward = 0
  80. terminated = True
  81. elif red_door_opened_after:
  82. if blue_door_opened_before:
  83. reward = 0
  84. terminated = True
  85. return obs, reward, terminated, truncated, info