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.

99 lines
3.2 KiB

2 months ago
  1. from __future__ import annotations
  2. from minigrid.core.constants import DIR_TO_VEC
  3. from minigrid.core.roomgrid import RoomGrid
  4. from minigrid.core.world_object import Ball, Box, Key
  5. from minigrid.envs.obstructedmaze import ObstructedMazeEnv
  6. class ObstructedMaze_Full(ObstructedMazeEnv):
  7. """
  8. A blue ball is hidden in one of the 4 corners of a 3x3 maze. Doors
  9. are locked, doors are obstructed by a ball and keys are hidden in
  10. boxes.
  11. All doors and their corresponding blocking balls will be added first,
  12. followed by the boxes containing the keys.
  13. """
  14. def __init__(
  15. self,
  16. agent_room=(1, 1),
  17. key_in_box=True,
  18. blocked=True,
  19. num_quarters=4,
  20. num_rooms_visited=25,
  21. **kwargs,
  22. ):
  23. self.agent_room = agent_room
  24. self.key_in_box = key_in_box
  25. self.blocked = blocked
  26. self.num_quarters = num_quarters
  27. super().__init__(
  28. num_rows=3, num_cols=3, num_rooms_visited=num_rooms_visited, **kwargs
  29. )
  30. def _gen_grid(self, width, height):
  31. super()._gen_grid(width, height)
  32. middle_room = (1, 1)
  33. # Define positions of "side rooms" i.e. rooms that are neither
  34. # corners nor the center.
  35. side_rooms = [(2, 1), (1, 2), (0, 1), (1, 0)][: self.num_quarters]
  36. for i in range(len(side_rooms)):
  37. side_room = side_rooms[i]
  38. # Add a door between the center room and the side room
  39. self.add_door(
  40. *middle_room, door_idx=i, color=self.door_colors[i], locked=False
  41. )
  42. for k in [-1, 1]:
  43. # Add a door to each side of the side room w/o placing a key
  44. self.add_locked_door(
  45. *side_room,
  46. door_idx=(i + k) % 4,
  47. color=self.door_colors[(i + k) % len(self.door_colors)],
  48. blocked=self.blocked,
  49. )
  50. # Add keys after all doors and their blocking balls are added
  51. for k in [-1, 1]:
  52. self.add_key(
  53. *side_room,
  54. color=self.door_colors[(i + k) % len(self.door_colors)],
  55. key_in_box=self.key_in_box,
  56. )
  57. corners = [(2, 0), (2, 2), (0, 2), (0, 0)][: self.num_quarters]
  58. ball_room = self._rand_elem(corners)
  59. self.obj, _ = self.add_object(
  60. ball_room[0], ball_room[1], "ball", color=self.ball_to_find_color
  61. )
  62. self.place_agent(*self.agent_room)
  63. def add_locked_door(self, i, j, door_idx=0, color=None, blocked=False):
  64. door, door_pos = RoomGrid.add_door(self, i, j, door_idx, color, locked=True)
  65. if blocked:
  66. vec = DIR_TO_VEC[door_idx]
  67. blocking_ball = Ball(self.blocking_ball_color) if blocked else None
  68. self.grid.set(door_pos[0] - vec[0], door_pos[1] - vec[1], blocking_ball)
  69. return door, door_pos
  70. def add_key(
  71. self,
  72. i,
  73. j,
  74. color=None,
  75. key_in_box=False,
  76. ):
  77. obj = Key(color)
  78. if key_in_box:
  79. box = Box(self.box_color)
  80. box.contains = obj
  81. obj = box
  82. self.place_in_room(i, j, obj)