MiniCraft - UnlockPickup

Reproduces the minigrid UnlockPickup gridworld environment as a HierarchyCraft environment.

Minigrid representation:

HierarchyCraft requirements graph:

  1from typing import List
  2
  3from hcraft.elements import Item, Zone
  4from hcraft.task import GetItemTask
  5from hcraft.transformation import Transformation, Use, Yield, PLAYER, CURRENT_ZONE
  6
  7
  8from hcraft.examples.minicraft.minicraft import MiniCraftEnv
  9
 10
 11MINICRAFT_NAME = "UnlockPickup"
 12__doc__ = MiniCraftEnv.description(MINICRAFT_NAME, for_module_header=True)
 13
 14
 15class MiniHCraftUnlockPickup(MiniCraftEnv):
 16    MINICRAFT_NAME = MINICRAFT_NAME
 17    __doc__ = MiniCraftEnv.description(MINICRAFT_NAME)
 18
 19    START = Zone("start_room")
 20    """Start room."""
 21    BOX_ROOM = Zone("box_room")
 22    """Room with a box inside."""
 23
 24    KEY = Item("key")
 25    """Key used to unlock the door."""
 26    BOX = Item("box")
 27    """Box to pickup."""
 28    WEIGHT = Item("weight")
 29    """Weight of carried items, can only be less than 1."""
 30
 31    OPEN_DOOR = Item("open_door")
 32    """Open door between the two rooms."""
 33    LOCKED_DOOR = Item("locked_door")
 34    """Locked door between the two rooms, can be unlocked with a key."""
 35
 36    def __init__(self, **kwargs) -> None:
 37        self.task = GetItemTask(self.BOX)
 38        super().__init__(
 39            self.MINICRAFT_NAME,
 40            purpose=self.task,
 41            start_zone=self.START,
 42            **kwargs,
 43        )
 44
 45    def build_transformations(self) -> List[Transformation]:
 46        transformations = []
 47
 48        zones = (self.START, self.BOX_ROOM)
 49        items_in_zone = [(self.KEY, self.START), (self.BOX, self.BOX_ROOM)]
 50
 51        for item, zone in items_in_zone:
 52            inventory_changes = [
 53                Yield(CURRENT_ZONE, item, create=1),
 54                # Prevent searching if already found
 55                Yield(PLAYER, item, create=0, max=0),
 56            ]
 57            # Prevent searching if item was placed elsewhere
 58            inventory_changes += [Yield(zone, item, create=0, max=0) for zone in zones]
 59            search_for_item = Transformation(
 60                f"search_for_{item.name}",
 61                inventory_changes=inventory_changes,
 62                zone=zone,
 63            )
 64            transformations.append(search_for_item)
 65
 66            pickup = Transformation(
 67                f"pickup_{item.name}",
 68                inventory_changes=[
 69                    Use(CURRENT_ZONE, item, consume=1),
 70                    Yield(PLAYER, item, create=1),
 71                    # WEIGHT prevents carrying more than one item
 72                    Yield(PLAYER, self.WEIGHT, create=1, max=0),
 73                ],
 74            )
 75            put_down = Transformation(
 76                f"put_down_{item.name}",
 77                inventory_changes=[
 78                    Use(PLAYER, item, consume=1),
 79                    Yield(CURRENT_ZONE, item, create=1),
 80                    # WEIGHT prevents carrying more than one item
 81                    Use(PLAYER, self.WEIGHT, consume=1),
 82                ],
 83            )
 84            transformations += [pickup, put_down]
 85
 86        search_for_door = Transformation(
 87            "search_for_door",
 88            inventory_changes=[
 89                Yield(CURRENT_ZONE, self.LOCKED_DOOR, max=0),
 90                Yield(CURRENT_ZONE, self.OPEN_DOOR, create=0, max=0),
 91            ],
 92            zone=self.START,
 93        )
 94        transformations.append(search_for_door)
 95
 96        unlock_door = Transformation(
 97            "unlock_door",
 98            inventory_changes=[
 99                Use(PLAYER, self.KEY),
100                Use(CURRENT_ZONE, self.LOCKED_DOOR, consume=1),
101                Yield(CURRENT_ZONE, self.OPEN_DOOR),
102            ],
103        )
104        transformations.append(unlock_door)
105
106        move_to_box_room = Transformation(
107            "move_to_box_room",
108            destination=self.BOX_ROOM,
109            inventory_changes=[Use(CURRENT_ZONE, self.OPEN_DOOR)],
110            zone=self.START,
111        )
112        transformations.append(move_to_box_room)
113
114        move_to_start_room = Transformation(
115            "move_to_start_room",
116            destination=self.START,
117            zone=self.BOX_ROOM,
118        )
119        transformations.append(move_to_start_room)
120
121        return transformations

API Documentation

MINICRAFT_NAME = 'UnlockPickup'
class MiniHCraftUnlockPickup(typing.Generic[~ObsType, ~ActType]):
 16class MiniHCraftUnlockPickup(MiniCraftEnv):
 17    MINICRAFT_NAME = MINICRAFT_NAME
 18    __doc__ = MiniCraftEnv.description(MINICRAFT_NAME)
 19
 20    START = Zone("start_room")
 21    """Start room."""
 22    BOX_ROOM = Zone("box_room")
 23    """Room with a box inside."""
 24
 25    KEY = Item("key")
 26    """Key used to unlock the door."""
 27    BOX = Item("box")
 28    """Box to pickup."""
 29    WEIGHT = Item("weight")
 30    """Weight of carried items, can only be less than 1."""
 31
 32    OPEN_DOOR = Item("open_door")
 33    """Open door between the two rooms."""
 34    LOCKED_DOOR = Item("locked_door")
 35    """Locked door between the two rooms, can be unlocked with a key."""
 36
 37    def __init__(self, **kwargs) -> None:
 38        self.task = GetItemTask(self.BOX)
 39        super().__init__(
 40            self.MINICRAFT_NAME,
 41            purpose=self.task,
 42            start_zone=self.START,
 43            **kwargs,
 44        )
 45
 46    def build_transformations(self) -> List[Transformation]:
 47        transformations = []
 48
 49        zones = (self.START, self.BOX_ROOM)
 50        items_in_zone = [(self.KEY, self.START), (self.BOX, self.BOX_ROOM)]
 51
 52        for item, zone in items_in_zone:
 53            inventory_changes = [
 54                Yield(CURRENT_ZONE, item, create=1),
 55                # Prevent searching if already found
 56                Yield(PLAYER, item, create=0, max=0),
 57            ]
 58            # Prevent searching if item was placed elsewhere
 59            inventory_changes += [Yield(zone, item, create=0, max=0) for zone in zones]
 60            search_for_item = Transformation(
 61                f"search_for_{item.name}",
 62                inventory_changes=inventory_changes,
 63                zone=zone,
 64            )
 65            transformations.append(search_for_item)
 66
 67            pickup = Transformation(
 68                f"pickup_{item.name}",
 69                inventory_changes=[
 70                    Use(CURRENT_ZONE, item, consume=1),
 71                    Yield(PLAYER, item, create=1),
 72                    # WEIGHT prevents carrying more than one item
 73                    Yield(PLAYER, self.WEIGHT, create=1, max=0),
 74                ],
 75            )
 76            put_down = Transformation(
 77                f"put_down_{item.name}",
 78                inventory_changes=[
 79                    Use(PLAYER, item, consume=1),
 80                    Yield(CURRENT_ZONE, item, create=1),
 81                    # WEIGHT prevents carrying more than one item
 82                    Use(PLAYER, self.WEIGHT, consume=1),
 83                ],
 84            )
 85            transformations += [pickup, put_down]
 86
 87        search_for_door = Transformation(
 88            "search_for_door",
 89            inventory_changes=[
 90                Yield(CURRENT_ZONE, self.LOCKED_DOOR, max=0),
 91                Yield(CURRENT_ZONE, self.OPEN_DOOR, create=0, max=0),
 92            ],
 93            zone=self.START,
 94        )
 95        transformations.append(search_for_door)
 96
 97        unlock_door = Transformation(
 98            "unlock_door",
 99            inventory_changes=[
100                Use(PLAYER, self.KEY),
101                Use(CURRENT_ZONE, self.LOCKED_DOOR, consume=1),
102                Yield(CURRENT_ZONE, self.OPEN_DOOR),
103            ],
104        )
105        transformations.append(unlock_door)
106
107        move_to_box_room = Transformation(
108            "move_to_box_room",
109            destination=self.BOX_ROOM,
110            inventory_changes=[Use(CURRENT_ZONE, self.OPEN_DOOR)],
111            zone=self.START,
112        )
113        transformations.append(move_to_box_room)
114
115        move_to_start_room = Transformation(
116            "move_to_start_room",
117            destination=self.START,
118            zone=self.BOX_ROOM,
119        )
120        transformations.append(move_to_start_room)
121
122        return transformations

Reproduces the minigrid UnlockPickup gridworld environment as a HierarchyCraft environment.

MiniHCraftUnlockPickup(**kwargs)
37    def __init__(self, **kwargs) -> None:
38        self.task = GetItemTask(self.BOX)
39        super().__init__(
40            self.MINICRAFT_NAME,
41            purpose=self.task,
42            start_zone=self.START,
43            **kwargs,
44        )
Arguments:
  • invalid_reward: Reward given to the agent for invalid actions. Defaults to -1.0.
  • max_step: Maximum number of steps before episode truncation. If None, never truncates the episode. Defaults to None.
  • render_window: Window using to render the environment with pygame.
MINICRAFT_NAME = 'UnlockPickup'
START = Zone(name='start_room')

Start room.

BOX_ROOM = Zone(name='box_room')

Room with a box inside.

KEY = Item(name='key')

Key used to unlock the door.

BOX = Item(name='box')

Box to pickup.

WEIGHT = Item(name='weight')

Weight of carried items, can only be less than 1.

OPEN_DOOR = Item(name='open_door')

Open door between the two rooms.

LOCKED_DOOR = Item(name='locked_door')

Locked door between the two rooms, can be unlocked with a key.

task
def build_transformations(self) -> List[hcraft.Transformation]:
 46    def build_transformations(self) -> List[Transformation]:
 47        transformations = []
 48
 49        zones = (self.START, self.BOX_ROOM)
 50        items_in_zone = [(self.KEY, self.START), (self.BOX, self.BOX_ROOM)]
 51
 52        for item, zone in items_in_zone:
 53            inventory_changes = [
 54                Yield(CURRENT_ZONE, item, create=1),
 55                # Prevent searching if already found
 56                Yield(PLAYER, item, create=0, max=0),
 57            ]
 58            # Prevent searching if item was placed elsewhere
 59            inventory_changes += [Yield(zone, item, create=0, max=0) for zone in zones]
 60            search_for_item = Transformation(
 61                f"search_for_{item.name}",
 62                inventory_changes=inventory_changes,
 63                zone=zone,
 64            )
 65            transformations.append(search_for_item)
 66
 67            pickup = Transformation(
 68                f"pickup_{item.name}",
 69                inventory_changes=[
 70                    Use(CURRENT_ZONE, item, consume=1),
 71                    Yield(PLAYER, item, create=1),
 72                    # WEIGHT prevents carrying more than one item
 73                    Yield(PLAYER, self.WEIGHT, create=1, max=0),
 74                ],
 75            )
 76            put_down = Transformation(
 77                f"put_down_{item.name}",
 78                inventory_changes=[
 79                    Use(PLAYER, item, consume=1),
 80                    Yield(CURRENT_ZONE, item, create=1),
 81                    # WEIGHT prevents carrying more than one item
 82                    Use(PLAYER, self.WEIGHT, consume=1),
 83                ],
 84            )
 85            transformations += [pickup, put_down]
 86
 87        search_for_door = Transformation(
 88            "search_for_door",
 89            inventory_changes=[
 90                Yield(CURRENT_ZONE, self.LOCKED_DOOR, max=0),
 91                Yield(CURRENT_ZONE, self.OPEN_DOOR, create=0, max=0),
 92            ],
 93            zone=self.START,
 94        )
 95        transformations.append(search_for_door)
 96
 97        unlock_door = Transformation(
 98            "unlock_door",
 99            inventory_changes=[
100                Use(PLAYER, self.KEY),
101                Use(CURRENT_ZONE, self.LOCKED_DOOR, consume=1),
102                Yield(CURRENT_ZONE, self.OPEN_DOOR),
103            ],
104        )
105        transformations.append(unlock_door)
106
107        move_to_box_room = Transformation(
108            "move_to_box_room",
109            destination=self.BOX_ROOM,
110            inventory_changes=[Use(CURRENT_ZONE, self.OPEN_DOOR)],
111            zone=self.START,
112        )
113        transformations.append(move_to_box_room)
114
115        move_to_start_room = Transformation(
116            "move_to_start_room",
117            destination=self.START,
118            zone=self.BOX_ROOM,
119        )
120        transformations.append(move_to_start_room)
121
122        return transformations

Build transformations for this MiniCraft environment

Inherited Members
hcraft.examples.minicraft.minicraft.MiniCraftEnv
description
hcraft.env.HcraftEnv
world
invalid_reward
max_step
name
render_window
render_mode
state
current_step
current_score
cumulated_score
episodes
task_successes
terminal_successes
purpose
metadata
truncated
observation_space
action_space
action_masks
step
render
reset
close
all_behaviors
solving_behavior
planning_problem
infos
gymnasium.core.Env
spec
unwrapped
np_random_seed
np_random
has_wrapper_attr
get_wrapper_attr
set_wrapper_attr