text: from gym import spaces
  from gym_minigrid.minigrid import *
  from gym_minigrid.register import register
  
  class Room:
      def __init__(self,
          top,
          size,
          doorPos
      ):
          self.top = top
          self.size = size
          self.doorPos = doorPos
          self.color = None
          self.locked = False
  
      def rand_pos(self, env):
          topX, topY = self.top
          sizeX, sizeY = self.size
          return env._rand_pos(
              topX + 1, topX + sizeX - 1,
              topY + 1, topY + sizeY - 1
          )
  
  class LockedRoom(MiniGridEnv):
      """
      Environment in which the agent is instructed to go to a given object
      named using an English text string
      """
  
      def __init__(
          self,
          size=19
      ):
          super().__init__(grid_size=size, max_steps=10*size)
  
      def _gen_grid(self, width, height):
          # Create the grid
          self.grid = Grid(width, height)
  
          # Generate the surrounding walls
          for i in range(0, width):
              self.grid.set(i, 0, Wall())
              self.grid.set(i, height-1, Wall())
          for j in range(0, height):
              self.grid.set(0, j, Wall())
              self.grid.set(width-1, j, Wall())
  
          # Hallway walls
          lWallIdx = width // 2 - 2
          rWallIdx = width // 2 + 2
          for j in range(0, height):
              self.grid.set(lWallIdx, j, Wall())
              self.grid.set(rWallIdx, j, Wall())
  
          self.rooms = []
  
          # Room splitting walls
          for n in range(0, 3):
              j = n * (height // 3)
              for i in range(0, lWallIdx):
                  self.grid.set(i, j, Wall())
              for i in range(rWallIdx, width):
                  self.grid.set(i, j, Wall())
  
              roomW = lWallIdx + 1
              roomH = height // 3 + 1
              self.rooms.append(Room(
                  (0, j),
                  (roomW, roomH),
                  (lWallIdx, j + 3)
              ))
              self.rooms.append(Room(
                  (rWallIdx, j),
                  (roomW, roomH),
                  (rWallIdx, j + 3)
              ))
  
          # Choose one random room to be locked
          lockedRoom = self._rand_elem(self.rooms)
          lockedRoom.locked = True
          goalPos = lockedRoom.rand_pos(self)
          self.grid.set(*goalPos, Goal())
  
          # Assign the door colors
          colors = set(COLOR_NAMES)
          for room in self.rooms:
              color = self._rand_elem(sorted(colors))
              colors.remove(color)
              room.color = color
              if room.locked:
                  self.grid.set(*room.doorPos, Door(color, is_locked=True))
              else:
                  self.grid.set(*room.doorPos, Door(color))
  
          # Select a random room to contain the key
          while True:
              keyRoom = self._rand_elem(self.rooms)
              if keyRoom != lockedRoom:
                  break
          keyPos = keyRoom.rand_pos(self)
          self.grid.set(*keyPos, Key(lockedRoom.color))
  
          # Randomize the player start position and orientation
          self.agent_pos = self.place_agent(
              top=(lWallIdx, 0),
              size=(rWallIdx-lWallIdx, height)
          )
  
          # Generate the mission string
          self.mission = (
              'get the %s key from the %s room, '
              'unlock the %s door and '
              'go to the goal'
          ) % (lockedRoom.color, keyRoom.color, lockedRoom.color)
  
      def step(self, action):
          obs, reward, done, info = MiniGridEnv.step(self, action)
          return obs, reward, done, info
  
  register(
      id='MiniGrid-LockedRoom-v0',
      entry_point='gym_minigrid.envs:LockedRoom'
  )
  