doorkey.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. from typing import Optional
  2. from minigrid.core.grid import Grid
  3. from minigrid.core.mission import MissionSpace
  4. from minigrid.core.world_object import Door, Goal, Key
  5. from minigrid.minigrid_env import MiniGridEnv
  6. class DoorKeyEnv(MiniGridEnv):
  7. """
  8. <p>
  9. <img src="https://raw.githubusercontent.com/Farama-Foundation/Minigrid/master/figures/door-key-curriculum.gif" alt="door-key-curriculum" width="200px"/>
  10. <img src="https://raw.githubusercontent.com/Farama-Foundation/Minigrid/master/figures/door-key-env.png" alt="door-key-env" width="200px"/>
  11. </p>
  12. ### Description
  13. This environment has a key that the agent must pick up in order to unlock a
  14. goal and then get to the green goal square. This environment is difficult,
  15. because of the sparse reward, to solve using classical RL algorithms. It is
  16. useful to experiment with curiosity or curriculum learning.
  17. ### Mission Space
  18. "use the key to open the door and then get to the goal"
  19. ### Action Space
  20. | Num | Name | Action |
  21. |-----|--------------|---------------------------|
  22. | 0 | left | Turn left |
  23. | 1 | right | Turn right |
  24. | 2 | forward | Move forward |
  25. | 3 | pickup | Pick up an object |
  26. | 4 | drop | Unused |
  27. | 5 | toggle | Toggle/activate an object |
  28. | 6 | done | Unused |
  29. ### Observation Encoding
  30. - Each tile is encoded as a 3 dimensional tuple:
  31. `(OBJECT_IDX, COLOR_IDX, STATE)`
  32. - `OBJECT_TO_IDX` and `COLOR_TO_IDX` mapping can be found in
  33. [minigrid/minigrid.py](minigrid/minigrid.py)
  34. - `STATE` refers to the door state with 0=open, 1=closed and 2=locked
  35. ### Rewards
  36. A reward of '1' is given for success, and '0' for failure.
  37. ### Termination
  38. The episode ends if any one of the following conditions is met:
  39. 1. The agent reaches the goal.
  40. 2. Timeout (see `max_steps`).
  41. ### Registered Configurations
  42. - `MiniGrid-DoorKey-5x5-v0`
  43. - `MiniGrid-DoorKey-6x6-v0`
  44. - `MiniGrid-DoorKey-8x8-v0`
  45. - `MiniGrid-DoorKey-16x16-v0`
  46. """
  47. def __init__(self, size=8, max_steps: Optional[int] = None, **kwargs):
  48. if max_steps is None:
  49. max_steps = 10 * size**2
  50. mission_space = MissionSpace(
  51. mission_func=lambda: "use the key to open the door and then get to the goal"
  52. )
  53. super().__init__(
  54. mission_space=mission_space, grid_size=size, max_steps=max_steps, **kwargs
  55. )
  56. def _gen_grid(self, width, height):
  57. # Create an empty grid
  58. self.grid = Grid(width, height)
  59. # Generate the surrounding walls
  60. self.grid.wall_rect(0, 0, width, height)
  61. # Place a goal in the bottom-right corner
  62. self.put_obj(Goal(), width - 2, height - 2)
  63. # Create a vertical splitting wall
  64. splitIdx = self._rand_int(2, width - 2)
  65. self.grid.vert_wall(splitIdx, 0)
  66. # Place the agent at a random position and orientation
  67. # on the left side of the splitting wall
  68. self.place_agent(size=(splitIdx, height))
  69. # Place a door in the wall
  70. doorIdx = self._rand_int(1, width - 2)
  71. self.put_obj(Door("yellow", is_locked=True), splitIdx, doorIdx)
  72. # Place a yellow key on the left side
  73. self.place_obj(obj=Key("yellow"), top=(0, 0), size=(splitIdx, height))
  74. self.mission = "use the key to open the door and then get to the goal"