lockedroom.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from gym_minigrid.minigrid import (
  2. COLOR_NAMES,
  3. Door,
  4. Goal,
  5. Grid,
  6. Key,
  7. MiniGridEnv,
  8. MissionSpace,
  9. Wall,
  10. )
  11. class LockedRoom:
  12. def __init__(self, top, size, doorPos):
  13. self.top = top
  14. self.size = size
  15. self.doorPos = doorPos
  16. self.color = None
  17. self.locked = False
  18. def rand_pos(self, env):
  19. topX, topY = self.top
  20. sizeX, sizeY = self.size
  21. return env._rand_pos(topX + 1, topX + sizeX - 1, topY + 1, topY + sizeY - 1)
  22. class LockedRoomEnv(MiniGridEnv):
  23. """
  24. Environment in which the agent is instructed to go to a given object
  25. named using an English text string
  26. """
  27. def __init__(self, size=19, **kwargs):
  28. self.size = size
  29. mission_space = MissionSpace(
  30. mission_func=lambda lockedroom_color, keyroom_color, door_color: f"get the {lockedroom_color} key from the {keyroom_color} room, unlock the {door_color} door and go to the goal",
  31. ordered_placeholders=[COLOR_NAMES] * 3,
  32. )
  33. super().__init__(
  34. mission_space=mission_space,
  35. width=size,
  36. height=size,
  37. max_steps=10 * size,
  38. **kwargs,
  39. )
  40. def _gen_grid(self, width, height):
  41. # Create the grid
  42. self.grid = Grid(width, height)
  43. # Generate the surrounding walls
  44. for i in range(0, width):
  45. self.grid.set(i, 0, Wall())
  46. self.grid.set(i, height - 1, Wall())
  47. for j in range(0, height):
  48. self.grid.set(0, j, Wall())
  49. self.grid.set(width - 1, j, Wall())
  50. # Hallway walls
  51. lWallIdx = width // 2 - 2
  52. rWallIdx = width // 2 + 2
  53. for j in range(0, height):
  54. self.grid.set(lWallIdx, j, Wall())
  55. self.grid.set(rWallIdx, j, Wall())
  56. self.rooms = []
  57. # Room splitting walls
  58. for n in range(0, 3):
  59. j = n * (height // 3)
  60. for i in range(0, lWallIdx):
  61. self.grid.set(i, j, Wall())
  62. for i in range(rWallIdx, width):
  63. self.grid.set(i, j, Wall())
  64. roomW = lWallIdx + 1
  65. roomH = height // 3 + 1
  66. self.rooms.append(LockedRoom((0, j), (roomW, roomH), (lWallIdx, j + 3)))
  67. self.rooms.append(
  68. LockedRoom((rWallIdx, j), (roomW, roomH), (rWallIdx, j + 3))
  69. )
  70. # Choose one random room to be locked
  71. lockedRoom = self._rand_elem(self.rooms)
  72. lockedRoom.locked = True
  73. goalPos = lockedRoom.rand_pos(self)
  74. self.grid.set(*goalPos, Goal())
  75. # Assign the door colors
  76. colors = set(COLOR_NAMES)
  77. for room in self.rooms:
  78. color = self._rand_elem(sorted(colors))
  79. colors.remove(color)
  80. room.color = color
  81. if room.locked:
  82. self.grid.set(*room.doorPos, Door(color, is_locked=True))
  83. else:
  84. self.grid.set(*room.doorPos, Door(color))
  85. # Select a random room to contain the key
  86. while True:
  87. keyRoom = self._rand_elem(self.rooms)
  88. if keyRoom != lockedRoom:
  89. break
  90. keyPos = keyRoom.rand_pos(self)
  91. self.grid.set(*keyPos, Key(lockedRoom.color))
  92. # Randomize the player start position and orientation
  93. self.agent_pos = self.place_agent(
  94. top=(lWallIdx, 0), size=(rWallIdx - lWallIdx, height)
  95. )
  96. # Generate the mission string
  97. self.mission = (
  98. "get the %s key from the %s room, "
  99. "unlock the %s door and "
  100. "go to the goal"
  101. ) % (lockedRoom.color, keyRoom.color, lockedRoom.color)