redbluedoors.py 3.9 KB

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