lockedroom.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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 randPos(self, env):
  16. topX, topY = self.top
  17. sizeX, sizeY = self.size
  18. return env._randPos(
  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. ):
  30. size = 19
  31. super().__init__(gridSize=size, maxSteps=10*size)
  32. self.observation_space = spaces.Dict({
  33. 'image': self.observation_space
  34. })
  35. self.reward_range = (-1, 1)
  36. def _genGrid(self, width, height):
  37. # Create the grid
  38. grid = Grid(width, height)
  39. # Generate the surrounding walls
  40. for i in range(0, width):
  41. grid.set(i, 0, Wall())
  42. grid.set(i, height-1, Wall())
  43. for j in range(0, height):
  44. grid.set(0, j, Wall())
  45. grid.set(width-1, j, Wall())
  46. # Hallway walls
  47. lWallIdx = width // 2 - 2
  48. rWallIdx = width // 2 + 2
  49. for j in range(0, height):
  50. grid.set(lWallIdx, j, Wall())
  51. grid.set(rWallIdx, j, Wall())
  52. self.rooms = []
  53. # Room splitting walls
  54. for n in range(0, 3):
  55. j = n * (height // 3)
  56. for i in range(0, lWallIdx):
  57. grid.set(i, j, Wall())
  58. for i in range(rWallIdx, width):
  59. grid.set(i, j, Wall())
  60. roomW = lWallIdx + 1
  61. roomH = height // 3 + 1
  62. self.rooms.append(Room(
  63. (0, j),
  64. (roomW, roomH),
  65. (lWallIdx, j + 3)
  66. ))
  67. self.rooms.append(Room(
  68. (rWallIdx, j),
  69. (roomW, roomH),
  70. (rWallIdx, j + 3)
  71. ))
  72. # Choose one random room to be locked
  73. lockedRoom = self._randElem(self.rooms)
  74. lockedRoom.locked = True
  75. goalPos = lockedRoom.randPos(self)
  76. grid.set(*goalPos, Goal())
  77. # Assign the door colors
  78. colors = set(COLOR_NAMES)
  79. for room in self.rooms:
  80. color = self._randElem(sorted(colors))
  81. colors.remove(color)
  82. room.color = color
  83. if room.locked:
  84. grid.set(*room.doorPos, LockedDoor(color))
  85. else:
  86. grid.set(*room.doorPos, Door(color))
  87. # Select a random room to contain the key
  88. while True:
  89. keyRoom = self._randElem(self.rooms)
  90. if keyRoom != lockedRoom:
  91. break
  92. keyPos = keyRoom.randPos(self)
  93. grid.set(*keyPos, Key(lockedRoom.color))
  94. # Randomize the player start position and orientation
  95. self.startPos = self._randPos(
  96. lWallIdx + 1, rWallIdx,
  97. 1, height-1
  98. )
  99. self.startDir = self._randInt(0, 4)
  100. # Generate the mission string
  101. self.mission = (
  102. 'get the %s key from the %s room, '
  103. 'then use it to unlock the %s door '
  104. 'so you can get to the goal'
  105. ) % (lockedRoom.color, keyRoom.color, lockedRoom.color)
  106. return grid
  107. def step(self, action):
  108. obs, reward, done, info = MiniGridEnv.step(self, action)
  109. return obs, reward, done, info
  110. register(
  111. id='MiniGrid-LockedRoom-v0',
  112. entry_point='gym_minigrid.envs:LockedRoom'
  113. )