MiniCraft - BlockedUnlockPickup
Reproduces the minigrid BlockedUnlockPickup 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 7from hcraft.examples.minicraft.minicraft import MiniCraftEnv 8 9MINICRAFT_NAME = "BlockedUnlockPickup" 10__doc__ = MiniCraftEnv.description(MINICRAFT_NAME, for_module_header=True) 11 12 13class MiniHCraftBlockedUnlockPickup(MiniCraftEnv): 14 MINICRAFT_NAME = MINICRAFT_NAME 15 __doc__ = MiniCraftEnv.description(MINICRAFT_NAME) 16 17 START = Zone("start_room") 18 """Start room.""" 19 BOX_ROOM = Zone("box_room") 20 """Room with a box inside.""" 21 22 KEY = Item("key") 23 """Key used to unlock the door.""" 24 BOX = Item("box") 25 """Box to pickup.""" 26 BALL = Item("ball") 27 """Ball blocking the door.""" 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 BLOCKED_DOOR = Item("blocked_door") 36 """Open but blocked door between the two rooms.""" 37 BLOCKED_LOCKED_DOOR = Item("blocked_locked_door") 38 """Locked and blocked door between the two rooms.""" 39 40 def __init__(self, **kwargs) -> None: 41 self.task = GetItemTask(self.BOX) 42 super().__init__( 43 self.MINICRAFT_NAME, 44 purpose=self.task, 45 start_zone=self.START, 46 **kwargs, 47 ) 48 49 def build_transformations(self) -> List[Transformation]: 50 transformations = [] 51 52 zones = (self.START, self.BOX_ROOM) 53 items_in_zone = [(self.KEY, self.START), (self.BOX, self.BOX_ROOM)] 54 55 for item, zone in items_in_zone: 56 inventory_changes = [ 57 Yield(CURRENT_ZONE, item, create=1), 58 # Prevent searching if already found 59 Yield(PLAYER, item, create=0, max=0), 60 ] 61 # Prevent searching if item was placed elsewhere 62 inventory_changes += [Yield(zone, item, create=0, max=0) for zone in zones] 63 search_for_item = Transformation( 64 f"search_for_{item.name}", 65 inventory_changes=inventory_changes, 66 zone=zone, 67 ) 68 transformations.append(search_for_item) 69 70 for item in (self.KEY, self.BOX, self.BALL): 71 pickup = Transformation( 72 f"pickup_{item.name}", 73 inventory_changes=[ 74 Use(CURRENT_ZONE, item, consume=1), 75 Yield(PLAYER, item, create=1), 76 # WEIGHT prevents carrying more than one item 77 Yield(PLAYER, self.WEIGHT, create=1, max=0), 78 ], 79 ) 80 put_down = Transformation( 81 f"put_down_{item.name}", 82 inventory_changes=[ 83 Use(PLAYER, item, consume=1), 84 Yield(CURRENT_ZONE, item, create=1), 85 # WEIGHT prevents carrying more than one item 86 Use(PLAYER, self.WEIGHT, consume=1), 87 ], 88 ) 89 transformations += [pickup, put_down] 90 91 search_for_door = Transformation( 92 "search_for_door", 93 inventory_changes=[ 94 Yield(self.START, self.BLOCKED_LOCKED_DOOR, create=1, max=0), 95 Yield(self.START, self.BLOCKED_DOOR, create=0, max=0), 96 Yield(self.START, self.LOCKED_DOOR, create=0, max=0), 97 Yield(self.START, self.OPEN_DOOR, create=0, max=0), 98 ], 99 zone=self.START, 100 ) 101 transformations.append(search_for_door) 102 103 unblock_locked_door = Transformation( 104 "unblock_locked_door", 105 inventory_changes=[ 106 Yield(PLAYER, self.BALL, create=1), 107 Yield(PLAYER, self.WEIGHT, create=1, max=0), 108 Use(self.START, self.BLOCKED_LOCKED_DOOR, consume=1), 109 Yield(self.START, self.LOCKED_DOOR, create=1), 110 ], 111 ) 112 transformations.append(unblock_locked_door) 113 114 block_locked_door = Transformation( 115 "block_locked_door", 116 inventory_changes=[ 117 Use(PLAYER, self.BALL, consume=1), 118 Use(PLAYER, self.WEIGHT, consume=1), 119 Use(self.START, self.LOCKED_DOOR, consume=1), 120 Yield(self.START, self.BLOCKED_LOCKED_DOOR, create=1), 121 ], 122 ) 123 transformations.append(block_locked_door) 124 125 unlock_door = Transformation( 126 "unlock_door", 127 inventory_changes=[ 128 Use(PLAYER, self.KEY), 129 Use(self.START, self.LOCKED_DOOR, consume=1), 130 Yield(self.START, self.OPEN_DOOR, create=1), 131 ], 132 ) 133 transformations.append(unlock_door) 134 135 block_door = Transformation( 136 "block_door", 137 inventory_changes=[ 138 Use(PLAYER, self.BALL, consume=1), 139 Use(PLAYER, self.WEIGHT, consume=1), 140 Use(self.START, self.OPEN_DOOR, consume=1), 141 Yield(self.START, self.BLOCKED_DOOR, create=1), 142 ], 143 ) 144 transformations.append(block_door) 145 146 unblock_door = Transformation( 147 "unblock_door", 148 inventory_changes=[ 149 Yield(PLAYER, self.BALL, create=1), 150 Yield(PLAYER, self.WEIGHT, create=1, max=0), 151 Use(self.START, self.BLOCKED_DOOR, consume=1), 152 Yield(self.START, self.OPEN_DOOR, create=1), 153 ], 154 ) 155 transformations.append(unblock_door) 156 157 move_to_box_room = Transformation( 158 "move_to_box_room", 159 destination=self.BOX_ROOM, 160 inventory_changes=[Use(CURRENT_ZONE, self.OPEN_DOOR)], 161 zone=self.START, 162 ) 163 transformations.append(move_to_box_room) 164 165 move_to_start_room = Transformation( 166 "move_to_start_room", 167 destination=self.START, 168 zone=self.BOX_ROOM, 169 ) 170 transformations.append(move_to_start_room) 171 172 return transformations
API Documentation
MINICRAFT_NAME =
'BlockedUnlockPickup'
class
MiniHCraftBlockedUnlockPickup(typing.Generic[~ObsType, ~ActType]):
14class MiniHCraftBlockedUnlockPickup(MiniCraftEnv): 15 MINICRAFT_NAME = MINICRAFT_NAME 16 __doc__ = MiniCraftEnv.description(MINICRAFT_NAME) 17 18 START = Zone("start_room") 19 """Start room.""" 20 BOX_ROOM = Zone("box_room") 21 """Room with a box inside.""" 22 23 KEY = Item("key") 24 """Key used to unlock the door.""" 25 BOX = Item("box") 26 """Box to pickup.""" 27 BALL = Item("ball") 28 """Ball blocking the door.""" 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 BLOCKED_DOOR = Item("blocked_door") 37 """Open but blocked door between the two rooms.""" 38 BLOCKED_LOCKED_DOOR = Item("blocked_locked_door") 39 """Locked and blocked door between the two rooms.""" 40 41 def __init__(self, **kwargs) -> None: 42 self.task = GetItemTask(self.BOX) 43 super().__init__( 44 self.MINICRAFT_NAME, 45 purpose=self.task, 46 start_zone=self.START, 47 **kwargs, 48 ) 49 50 def build_transformations(self) -> List[Transformation]: 51 transformations = [] 52 53 zones = (self.START, self.BOX_ROOM) 54 items_in_zone = [(self.KEY, self.START), (self.BOX, self.BOX_ROOM)] 55 56 for item, zone in items_in_zone: 57 inventory_changes = [ 58 Yield(CURRENT_ZONE, item, create=1), 59 # Prevent searching if already found 60 Yield(PLAYER, item, create=0, max=0), 61 ] 62 # Prevent searching if item was placed elsewhere 63 inventory_changes += [Yield(zone, item, create=0, max=0) for zone in zones] 64 search_for_item = Transformation( 65 f"search_for_{item.name}", 66 inventory_changes=inventory_changes, 67 zone=zone, 68 ) 69 transformations.append(search_for_item) 70 71 for item in (self.KEY, self.BOX, self.BALL): 72 pickup = Transformation( 73 f"pickup_{item.name}", 74 inventory_changes=[ 75 Use(CURRENT_ZONE, item, consume=1), 76 Yield(PLAYER, item, create=1), 77 # WEIGHT prevents carrying more than one item 78 Yield(PLAYER, self.WEIGHT, create=1, max=0), 79 ], 80 ) 81 put_down = Transformation( 82 f"put_down_{item.name}", 83 inventory_changes=[ 84 Use(PLAYER, item, consume=1), 85 Yield(CURRENT_ZONE, item, create=1), 86 # WEIGHT prevents carrying more than one item 87 Use(PLAYER, self.WEIGHT, consume=1), 88 ], 89 ) 90 transformations += [pickup, put_down] 91 92 search_for_door = Transformation( 93 "search_for_door", 94 inventory_changes=[ 95 Yield(self.START, self.BLOCKED_LOCKED_DOOR, create=1, max=0), 96 Yield(self.START, self.BLOCKED_DOOR, create=0, max=0), 97 Yield(self.START, self.LOCKED_DOOR, create=0, max=0), 98 Yield(self.START, self.OPEN_DOOR, create=0, max=0), 99 ], 100 zone=self.START, 101 ) 102 transformations.append(search_for_door) 103 104 unblock_locked_door = Transformation( 105 "unblock_locked_door", 106 inventory_changes=[ 107 Yield(PLAYER, self.BALL, create=1), 108 Yield(PLAYER, self.WEIGHT, create=1, max=0), 109 Use(self.START, self.BLOCKED_LOCKED_DOOR, consume=1), 110 Yield(self.START, self.LOCKED_DOOR, create=1), 111 ], 112 ) 113 transformations.append(unblock_locked_door) 114 115 block_locked_door = Transformation( 116 "block_locked_door", 117 inventory_changes=[ 118 Use(PLAYER, self.BALL, consume=1), 119 Use(PLAYER, self.WEIGHT, consume=1), 120 Use(self.START, self.LOCKED_DOOR, consume=1), 121 Yield(self.START, self.BLOCKED_LOCKED_DOOR, create=1), 122 ], 123 ) 124 transformations.append(block_locked_door) 125 126 unlock_door = Transformation( 127 "unlock_door", 128 inventory_changes=[ 129 Use(PLAYER, self.KEY), 130 Use(self.START, self.LOCKED_DOOR, consume=1), 131 Yield(self.START, self.OPEN_DOOR, create=1), 132 ], 133 ) 134 transformations.append(unlock_door) 135 136 block_door = Transformation( 137 "block_door", 138 inventory_changes=[ 139 Use(PLAYER, self.BALL, consume=1), 140 Use(PLAYER, self.WEIGHT, consume=1), 141 Use(self.START, self.OPEN_DOOR, consume=1), 142 Yield(self.START, self.BLOCKED_DOOR, create=1), 143 ], 144 ) 145 transformations.append(block_door) 146 147 unblock_door = Transformation( 148 "unblock_door", 149 inventory_changes=[ 150 Yield(PLAYER, self.BALL, create=1), 151 Yield(PLAYER, self.WEIGHT, create=1, max=0), 152 Use(self.START, self.BLOCKED_DOOR, consume=1), 153 Yield(self.START, self.OPEN_DOOR, create=1), 154 ], 155 ) 156 transformations.append(unblock_door) 157 158 move_to_box_room = Transformation( 159 "move_to_box_room", 160 destination=self.BOX_ROOM, 161 inventory_changes=[Use(CURRENT_ZONE, self.OPEN_DOOR)], 162 zone=self.START, 163 ) 164 transformations.append(move_to_box_room) 165 166 move_to_start_room = Transformation( 167 "move_to_start_room", 168 destination=self.START, 169 zone=self.BOX_ROOM, 170 ) 171 transformations.append(move_to_start_room) 172 173 return transformations
Reproduces the minigrid BlockedUnlockPickup gridworld environment as a HierarchyCraft environment.
MiniHCraftBlockedUnlockPickup(**kwargs)
41 def __init__(self, **kwargs) -> None: 42 self.task = GetItemTask(self.BOX) 43 super().__init__( 44 self.MINICRAFT_NAME, 45 purpose=self.task, 46 start_zone=self.START, 47 **kwargs, 48 )
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.
LOCKED_DOOR =
Item(name='locked_door')
Locked door between the two rooms, can be unlocked with a key.
BLOCKED_LOCKED_DOOR =
Item(name='blocked_locked_door')
Locked and blocked door between the two rooms.
50 def build_transformations(self) -> List[Transformation]: 51 transformations = [] 52 53 zones = (self.START, self.BOX_ROOM) 54 items_in_zone = [(self.KEY, self.START), (self.BOX, self.BOX_ROOM)] 55 56 for item, zone in items_in_zone: 57 inventory_changes = [ 58 Yield(CURRENT_ZONE, item, create=1), 59 # Prevent searching if already found 60 Yield(PLAYER, item, create=0, max=0), 61 ] 62 # Prevent searching if item was placed elsewhere 63 inventory_changes += [Yield(zone, item, create=0, max=0) for zone in zones] 64 search_for_item = Transformation( 65 f"search_for_{item.name}", 66 inventory_changes=inventory_changes, 67 zone=zone, 68 ) 69 transformations.append(search_for_item) 70 71 for item in (self.KEY, self.BOX, self.BALL): 72 pickup = Transformation( 73 f"pickup_{item.name}", 74 inventory_changes=[ 75 Use(CURRENT_ZONE, item, consume=1), 76 Yield(PLAYER, item, create=1), 77 # WEIGHT prevents carrying more than one item 78 Yield(PLAYER, self.WEIGHT, create=1, max=0), 79 ], 80 ) 81 put_down = Transformation( 82 f"put_down_{item.name}", 83 inventory_changes=[ 84 Use(PLAYER, item, consume=1), 85 Yield(CURRENT_ZONE, item, create=1), 86 # WEIGHT prevents carrying more than one item 87 Use(PLAYER, self.WEIGHT, consume=1), 88 ], 89 ) 90 transformations += [pickup, put_down] 91 92 search_for_door = Transformation( 93 "search_for_door", 94 inventory_changes=[ 95 Yield(self.START, self.BLOCKED_LOCKED_DOOR, create=1, max=0), 96 Yield(self.START, self.BLOCKED_DOOR, create=0, max=0), 97 Yield(self.START, self.LOCKED_DOOR, create=0, max=0), 98 Yield(self.START, self.OPEN_DOOR, create=0, max=0), 99 ], 100 zone=self.START, 101 ) 102 transformations.append(search_for_door) 103 104 unblock_locked_door = Transformation( 105 "unblock_locked_door", 106 inventory_changes=[ 107 Yield(PLAYER, self.BALL, create=1), 108 Yield(PLAYER, self.WEIGHT, create=1, max=0), 109 Use(self.START, self.BLOCKED_LOCKED_DOOR, consume=1), 110 Yield(self.START, self.LOCKED_DOOR, create=1), 111 ], 112 ) 113 transformations.append(unblock_locked_door) 114 115 block_locked_door = Transformation( 116 "block_locked_door", 117 inventory_changes=[ 118 Use(PLAYER, self.BALL, consume=1), 119 Use(PLAYER, self.WEIGHT, consume=1), 120 Use(self.START, self.LOCKED_DOOR, consume=1), 121 Yield(self.START, self.BLOCKED_LOCKED_DOOR, create=1), 122 ], 123 ) 124 transformations.append(block_locked_door) 125 126 unlock_door = Transformation( 127 "unlock_door", 128 inventory_changes=[ 129 Use(PLAYER, self.KEY), 130 Use(self.START, self.LOCKED_DOOR, consume=1), 131 Yield(self.START, self.OPEN_DOOR, create=1), 132 ], 133 ) 134 transformations.append(unlock_door) 135 136 block_door = Transformation( 137 "block_door", 138 inventory_changes=[ 139 Use(PLAYER, self.BALL, consume=1), 140 Use(PLAYER, self.WEIGHT, consume=1), 141 Use(self.START, self.OPEN_DOOR, consume=1), 142 Yield(self.START, self.BLOCKED_DOOR, create=1), 143 ], 144 ) 145 transformations.append(block_door) 146 147 unblock_door = Transformation( 148 "unblock_door", 149 inventory_changes=[ 150 Yield(PLAYER, self.BALL, create=1), 151 Yield(PLAYER, self.WEIGHT, create=1, max=0), 152 Use(self.START, self.BLOCKED_DOOR, consume=1), 153 Yield(self.START, self.OPEN_DOOR, create=1), 154 ], 155 ) 156 transformations.append(unblock_door) 157 158 move_to_box_room = Transformation( 159 "move_to_box_room", 160 destination=self.BOX_ROOM, 161 inventory_changes=[Use(CURRENT_ZONE, self.OPEN_DOOR)], 162 zone=self.START, 163 ) 164 transformations.append(move_to_box_room) 165 166 move_to_start_room = Transformation( 167 "move_to_start_room", 168 destination=self.START, 169 zone=self.BOX_ROOM, 170 ) 171 transformations.append(move_to_start_room) 172 173 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