grg's picture
Cleaned old git history
be5548b
raw
history blame contribute delete
No virus
9.51 kB
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__(
grid_size=25,
max_steps=self.maxNumRooms * 20
)
def _gen_grid(self, width, height):
roomList = []
# Choose a random number of rooms to generate
numRooms = self._rand_int(self.minNumRooms, self.maxNumRooms+1)
while len(roomList) < numRooms:
curRoomList = []
entryDoorPos = (
self._rand_int(0, width - 2),
self._rand_int(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
# Create the grid
self.grid = Grid(width, height, nb_obj_dims=self.nb_obj_dims)
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._rand_elem(sorted(doorColors))
entryDoor = Door(doorColor)
self.grid.set(*room.entryDoorPos, entryDoor)
prevDoorColor = doorColor
prevRoom = roomList[idx-1]
prevRoom.exitDoorPos = room.entryDoorPos
# Randomize the starting agent position and direction
self.place_agent(roomList[0].top, roomList[0].size)
# Place the final goal in the last room
self.goal_pos = self.place_obj(Goal(), roomList[-1].top, roomList[-1].size)
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._rand_int(minSz, maxSz+1)
sizeY = self._rand_int(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._rand_int(y - sizeY + 2, y)
# Entry wall on the south
elif entryDoorWall == 1:
x = entryDoorPos[0]
topX = self._rand_int(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._rand_int(y - sizeY + 2, y)
# Entry wall on the top
elif entryDoorWall == 3:
x = entryDoorPos[0]
topX = self._rand_int(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.width or topY + sizeY >= self.height:
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._rand_elem(sorted(wallSet))
nextEntryWall = (exitDoorWall + 2) % 4
# Pick the exit door position
# Exit on right wall
if exitDoorWall == 0:
exitDoorPos = (
topX + sizeX - 1,
topY + self._rand_int(1, sizeY - 1)
)
# Exit on south wall
elif exitDoorWall == 1:
exitDoorPos = (
topX + self._rand_int(1, sizeX - 1),
topY + sizeY - 1
)
# Exit on left wall
elif exitDoorWall == 2:
exitDoorPos = (
topX,
topY + self._rand_int(1, sizeY - 1)
)
# Exit on north wall
elif exitDoorWall == 3:
exitDoorPos = (
topX + self._rand_int(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 MultiRoomEnvN4S5(MultiRoomEnv):
def __init__(self):
super().__init__(
minNumRooms=4,
maxNumRooms=4,
maxRoomSize=5
)
class MultiRoomEnvN6(MultiRoomEnv):
def __init__(self):
super().__init__(
minNumRooms=6,
maxNumRooms=6
)
class MultiRoomEnvN7S4(MultiRoomEnv):
def __init__(self):
super().__init__(
minNumRooms=7,
maxNumRooms=7,
maxRoomSize=4
)
class MultiRoomEnvN7S8(MultiRoomEnv):
def __init__(self):
super().__init__(
minNumRooms=7,
maxNumRooms=7,
maxRoomSize=8
)
class MultiRoomEnvN10S4(MultiRoomEnv):
def __init__(self):
super().__init__(
minNumRooms=10,
maxNumRooms=10,
maxRoomSize=4
)
class MultiRoomEnvN10S10(MultiRoomEnv):
def __init__(self):
super().__init__(
minNumRooms=10,
maxNumRooms=10,
maxRoomSize=10
)
class MultiRoomEnvN12S10(MultiRoomEnv):
def __init__(self):
super().__init__(
minNumRooms=12,
maxNumRooms=12,
maxRoomSize=10
)
register(
id='MiniGrid-MultiRoom-N2-S4-v0',
entry_point='gym_minigrid.envs:MultiRoomEnvN2S4'
)
register(
id='MiniGrid-MultiRoom-N4-S5-v0',
entry_point='gym_minigrid.envs:MultiRoomEnvN4S5'
)
register(
id='MiniGrid-MultiRoom-N6-v0',
entry_point='gym_minigrid.envs:MultiRoomEnvN6'
)
register(
id='MiniGrid-MultiRoom-N7-S4-v0',
entry_point='gym_minigrid.envs:MultiRoomEnvN7S4'
)
register(
id='MiniGrid-MultiRoom-N7-S8-v0',
entry_point='gym_minigrid.envs:MultiRoomEnvN7S8'
)
register(
id='MiniGrid-MultiRoom-N10-S4-v0',
entry_point='gym_minigrid.envs:MultiRoomEnvN10S4'
)
register(
id='MiniGrid-MultiRoom-N10-S10-v0',
entry_point='gym_minigrid.envs:MultiRoomEnvN10S10'
)
register(
id='MiniGrid-MultiRoom-N12-S10-v0',
entry_point='gym_minigrid.envs:MultiRoomEnvN12S10'
)