| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 | 
							- from gym_minigrid.minigrid import *
 
- from gym_minigrid.register import register
 
- class Room:
 
-     def __init__(self,
 
-         top,
 
-         size,
 
-         entryDoorPos,
 
-         exitDoorPos
 
-     ):
 
-         self.top = top
 
-         self.size = size
 
-         self.entryDoorPos = entryDoorPos
 
-         self.exitDoorPos = exitDoorPos
 
- class MultiRoomEnv(MiniGridEnv):
 
-     """
 
-     Environment with multiple rooms (subgoals)
 
-     """
 
-     def __init__(self,
 
-         minNumRooms,
 
-         maxNumRooms,
 
-         maxRoomSize=10
 
-     ):
 
-         assert minNumRooms > 0
 
-         assert maxNumRooms >= minNumRooms
 
-         assert maxRoomSize >= 4
 
-         self.minNumRooms = minNumRooms
 
-         self.maxNumRooms = maxNumRooms
 
-         self.maxRoomSize = maxRoomSize
 
-         self.rooms = []
 
-         super(MultiRoomEnv, self).__init__(
 
-             gridSize=25,
 
-             maxSteps=self.maxNumRooms * 20
 
-         )
 
-     def _genGrid(self, width, height):
 
-         roomList = []
 
-         # Choose a random number of rooms to generate
 
-         numRooms = self._randInt(self.minNumRooms, self.maxNumRooms+1)
 
-         while len(roomList) < numRooms:
 
-             curRoomList = []
 
-             entryDoorPos = (
 
-                 self._randInt(0, width - 2),
 
-                 self._randInt(0, width - 2)
 
-             )
 
-             # Recursively place the rooms
 
-             self._placeRoom(
 
-                 numRooms,
 
-                 roomList=curRoomList,
 
-                 minSz=4,
 
-                 maxSz=self.maxRoomSize,
 
-                 entryDoorWall=2,
 
-                 entryDoorPos=entryDoorPos
 
-             )
 
-             if len(curRoomList) > len(roomList):
 
-                 roomList = curRoomList
 
-         # Store the list of rooms in this environment
 
-         assert len(roomList) > 0
 
-         self.rooms = roomList
 
-         # Randomize the starting agent position and direction
 
-         topX, topY = roomList[0].top
 
-         sizeX, sizeY = roomList[0].size
 
-         self.startPos = (
 
-             self._randInt(topX + 1, topX + sizeX - 2),
 
-             self._randInt(topY + 1, topY + sizeY - 2)
 
-         )
 
-         self.startDir = self._randInt(0, 4)
 
-         # Create the grid
 
-         self.grid = Grid(width, height)
 
-         wall = Wall()
 
-         prevDoorColor = None
 
-         # For each room
 
-         for idx, room in enumerate(roomList):
 
-             topX, topY = room.top
 
-             sizeX, sizeY = room.size
 
-             # Draw the top and bottom walls
 
-             for i in range(0, sizeX):
 
-                 self.grid.set(topX + i, topY, wall)
 
-                 self.grid.set(topX + i, topY + sizeY - 1, wall)
 
-             # Draw the left and right walls
 
-             for j in range(0, sizeY):
 
-                 self.grid.set(topX, topY + j, wall)
 
-                 self.grid.set(topX + sizeX - 1, topY + j, wall)
 
-             # If this isn't the first room, place the entry door
 
-             if idx > 0:
 
-                 # Pick a door color different from the previous one
 
-                 doorColors = set(COLOR_NAMES)
 
-                 if prevDoorColor:
 
-                     doorColors.remove(prevDoorColor)
 
-                 # Note: the use of sorting here guarantees determinism,
 
-                 # This is needed because Python's set is not deterministic
 
-                 doorColor = self._randElem(sorted(doorColors))
 
-                 entryDoor = Door(doorColor)
 
-                 self.grid.set(*room.entryDoorPos, entryDoor)
 
-                 prevDoorColor = doorColor
 
-                 prevRoom = roomList[idx-1]
 
-                 prevRoom.exitDoorPos = room.entryDoorPos
 
-         # Place the final goal
 
-         while True:
 
-             self.goalPos = (
 
-                 self._randInt(topX + 1, topX + sizeX - 1),
 
-                 self._randInt(topY + 1, topY + sizeY - 1)
 
-             )
 
-             # Make sure the goal doesn't overlap with the agent
 
-             if self.goalPos != self.startPos:
 
-                 self.grid.set(*self.goalPos, Goal())
 
-                 break
 
-         self.mission = 'traverse the rooms to get to the goal'
 
-     def _placeRoom(
 
-         self,
 
-         numLeft,
 
-         roomList,
 
-         minSz,
 
-         maxSz,
 
-         entryDoorWall,
 
-         entryDoorPos
 
-     ):
 
-         # Choose the room size randomly
 
-         sizeX = self._randInt(minSz, maxSz+1)
 
-         sizeY = self._randInt(minSz, maxSz+1)
 
-         # The first room will be at the door position
 
-         if len(roomList) == 0:
 
-             topX, topY = entryDoorPos
 
-         # Entry on the right
 
-         elif entryDoorWall == 0:
 
-             topX = entryDoorPos[0] - sizeX + 1
 
-             y = entryDoorPos[1]
 
-             topY = self._randInt(y - sizeY + 2, y)
 
-         # Entry wall on the south
 
-         elif entryDoorWall == 1:
 
-             x = entryDoorPos[0]
 
-             topX = self._randInt(x - sizeX + 2, x)
 
-             topY = entryDoorPos[1] - sizeY + 1
 
-         # Entry wall on the left
 
-         elif entryDoorWall == 2:
 
-             topX = entryDoorPos[0]
 
-             y = entryDoorPos[1]
 
-             topY = self._randInt(y - sizeY + 2, y)
 
-         # Entry wall on the top
 
-         elif entryDoorWall == 3:
 
-             x = entryDoorPos[0]
 
-             topX = self._randInt(x - sizeX + 2, x)
 
-             topY = entryDoorPos[1]
 
-         else:
 
-             assert False, entryDoorWall
 
-         # If the room is out of the grid, can't place a room here
 
-         if topX < 0 or topY < 0:
 
-             return False
 
-         if topX + sizeX > self.gridSize or topY + sizeY >= self.gridSize:
 
-             return False
 
-         # If the room intersects with previous rooms, can't place it here
 
-         for room in roomList[:-1]:
 
-             nonOverlap = \
 
-                 topX + sizeX < room.top[0] or \
 
-                 room.top[0] + room.size[0] <= topX or \
 
-                 topY + sizeY < room.top[1] or \
 
-                 room.top[1] + room.size[1] <= topY
 
-             if not nonOverlap:
 
-                 return False
 
-         # Add this room to the list
 
-         roomList.append(Room(
 
-             (topX, topY),
 
-             (sizeX, sizeY),
 
-             entryDoorPos,
 
-             None
 
-         ))
 
-         # If this was the last room, stop
 
-         if numLeft == 1:
 
-             return True
 
-         # Try placing the next room
 
-         for i in range(0, 8):
 
-             # Pick which wall to place the out door on
 
-             wallSet = set((0, 1, 2, 3))
 
-             wallSet.remove(entryDoorWall)
 
-             exitDoorWall = self._randElem(sorted(wallSet))
 
-             nextEntryWall = (exitDoorWall + 2) % 4
 
-             # Pick the exit door position
 
-             # Exit on right wall
 
-             if exitDoorWall == 0:
 
-                 exitDoorPos = (
 
-                     topX + sizeX - 1,
 
-                     topY + self._randInt(1, sizeY - 1)
 
-                 )
 
-             # Exit on south wall
 
-             elif exitDoorWall == 1:
 
-                 exitDoorPos = (
 
-                     topX + self._randInt(1, sizeX - 1),
 
-                     topY + sizeY - 1
 
-                 )
 
-             # Exit on left wall
 
-             elif exitDoorWall == 2:
 
-                 exitDoorPos = (
 
-                     topX,
 
-                     topY + self._randInt(1, sizeY - 1)
 
-                 )
 
-             # Exit on north wall
 
-             elif exitDoorWall == 3:
 
-                 exitDoorPos = (
 
-                     topX + self._randInt(1, sizeX - 1),
 
-                     topY
 
-                 )
 
-             else:
 
-                 assert False
 
-             # Recursively create the other rooms
 
-             success = self._placeRoom(
 
-                 numLeft - 1,
 
-                 roomList=roomList,
 
-                 minSz=minSz,
 
-                 maxSz=maxSz,
 
-                 entryDoorWall=nextEntryWall,
 
-                 entryDoorPos=exitDoorPos
 
-             )
 
-             if success:
 
-                 break
 
-         return True
 
- class MultiRoomEnvN2S4(MultiRoomEnv):
 
-     def __init__(self):
 
-         super().__init__(
 
-             minNumRooms=2,
 
-             maxNumRooms=2,
 
-             maxRoomSize=4
 
-         )
 
- class MultiRoomEnvN6(MultiRoomEnv):
 
-     def __init__(self):
 
-         super().__init__(
 
-             minNumRooms=6,
 
-             maxNumRooms=6
 
-         )
 
- register(
 
-     id='MiniGrid-MultiRoom-N2-S4-v0',
 
-     entry_point='gym_minigrid.envs:MultiRoomEnvN2S4',
 
-     reward_threshold=1000.0
 
- )
 
- register(
 
-     id='MiniGrid-MultiRoom-N6-v0',
 
-     entry_point='gym_minigrid.envs:MultiRoomEnvN6',
 
-     reward_threshold=1000.0
 
- )
 
 
  |