lockedroom.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. from gym import spaces
  2. from gym_minigrid.minigrid import *
  3. from gym_minigrid.register import register
  4. class Room:
  5. def __init__(self,
  6. top,
  7. size,
  8. doorPos
  9. ):
  10. self.top = top
  11. self.size = size
  12. self.doorPos = doorPos
  13. self.color = None
  14. self.locked = False
  15. def rand_pos(self, env):
  16. topX, topY = self.top
  17. sizeX, sizeY = self.size
  18. return env._rand_pos(
  19. topX + 1, topX + sizeX - 1,
  20. topY + 1, topY + sizeY - 1
  21. )
  22. class LockedRoom(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__(
  28. self,
  29. size=19,
  30. **kwargs
  31. ):
  32. super().__init__(grid_size=size, max_steps=10*size, **kwargs)
  33. def _gen_grid(self, width, height):
  34. # Create the grid
  35. self.grid = Grid(width, height)
  36. # Generate the surrounding walls
  37. for i in range(0, width):
  38. self.grid.set(i, 0, Wall())
  39. self.grid.set(i, height-1, Wall())
  40. for j in range(0, height):
  41. self.grid.set(0, j, Wall())
  42. self.grid.set(width-1, j, Wall())
  43. # Hallway walls
  44. lWallIdx = width // 2 - 2
  45. rWallIdx = width // 2 + 2
  46. for j in range(0, height):
  47. self.grid.set(lWallIdx, j, Wall())
  48. self.grid.set(rWallIdx, j, Wall())
  49. self.rooms = []
  50. # Room splitting walls
  51. for n in range(0, 3):
  52. j = n * (height // 3)
  53. for i in range(0, lWallIdx):
  54. self.grid.set(i, j, Wall())
  55. for i in range(rWallIdx, width):
  56. self.grid.set(i, j, Wall())
  57. roomW = lWallIdx + 1
  58. roomH = height // 3 + 1
  59. self.rooms.append(Room(
  60. (0, j),
  61. (roomW, roomH),
  62. (lWallIdx, j + 3)
  63. ))
  64. self.rooms.append(Room(
  65. (rWallIdx, j),
  66. (roomW, roomH),
  67. (rWallIdx, j + 3)
  68. ))
  69. # Choose one random room to be locked
  70. lockedRoom = self._rand_elem(self.rooms)
  71. lockedRoom.locked = True
  72. goalPos = lockedRoom.rand_pos(self)
  73. self.grid.set(*goalPos, Goal())
  74. # Assign the door colors
  75. colors = set(COLOR_NAMES)
  76. for room in self.rooms:
  77. color = self._rand_elem(sorted(colors))
  78. colors.remove(color)
  79. room.color = color
  80. if room.locked:
  81. self.grid.set(*room.doorPos, Door(color, is_locked=True))
  82. else:
  83. self.grid.set(*room.doorPos, Door(color))
  84. # Select a random room to contain the key
  85. while True:
  86. keyRoom = self._rand_elem(self.rooms)
  87. if keyRoom != lockedRoom:
  88. break
  89. keyPos = keyRoom.rand_pos(self)
  90. self.grid.set(*keyPos, Key(lockedRoom.color))
  91. # Randomize the player start position and orientation
  92. self.agent_pos = self.place_agent(
  93. top=(lWallIdx, 0),
  94. 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)
  102. def step(self, action):
  103. obs, reward, done, info = MiniGridEnv.step(self, action)
  104. return obs, reward, done, info
  105. register(
  106. id='MiniGrid-LockedRoom-v0',
  107. entry_point='gym_minigrid.envs:LockedRoom'
  108. )