Beispiel #1
0
def test_step_moving_obstacles(
    objects: Sequence[Sequence[GridObject]],
    expected_objects: Sequence[Sequence[GridObject]],
):
    state = State(Grid.from_objects(objects), MagicMock())
    expected_state = State(Grid.from_objects(expected_objects), MagicMock())

    action = MagicMock()
    step_moving_obstacles(state, action)
    assert state.grid == expected_state.grid
def make_goal_state(agent_on_goal: bool) -> State:
    """makes a simple state with a wall in front of the agent"""
    grid = Grid(2, 1)
    grid[0, 0] = Goal()
    agent_position = (0, 0) if agent_on_goal else (1, 0)
    agent = Agent(agent_position, Orientation.N)
    return State(grid, agent)
def make_moving_obstacle_state(agent_on_obstacle: bool) -> State:
    """makes a simple state with goal object and agent on or off the goal"""
    grid = Grid(2, 1)
    grid[0, 0] = MovingObstacle()
    agent_position = (0, 0) if agent_on_obstacle else (1, 0)
    agent = Agent(agent_position, Orientation.N)
    return State(grid, agent)
def creeping_walls(
    state: State,
    action: Action,  # pylint: disable=unused-argument
    *,
    rng: Optional[rnd.Generator] = None,
) -> None:
    """randomly chooses a Floor tile and turns it into a Wall tile"""

    rng = get_gv_rng_if_none(rng)  # necessary to use rng object!

    # all positions associated with a Floor object
    floor_positions = [
        position for position in state.grid.positions()
        if isinstance(state.grid[position], Floor)
    ]

    try:
        # floor_positions could be an empty list
        position = rng.choice(floor_positions)
    except ValueError:
        # there are no floor positions
        pass
    else:
        # if we were able to sample a position, change the corresponding Floor
        # into a Wall
        state.grid[position] = Wall()
Beispiel #5
0
def match_key_color(
        *,
        rng: Optional[rnd.Generator] = None,  # pylint: disable=unused-argument
) -> State:
    """the agent has to pick the correct key to open a randomly colored door"""

    rng = get_gv_rng_if_none(rng)  # necessary to use rng object!

    # only consider these colors
    colors = [Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW]
    # randomly choose location of keys
    key1, key2, key3, key4 = rng.permute([Key(color) for color in colors])
    # randomly choose color of door
    door = Door(Door.Status.LOCKED, rng.choice(colors))

    # grids can be constructed directly from objects
    grid = Grid.from_objects([
        [Wall(), Wall(), Wall(), Wall(),
         Wall()],
        [Wall(), Wall(), Goal(), Wall(),
         Wall()],
        [Wall(), Wall(), door, Wall(), Wall()],
        [Wall(), key1, Floor(), key2, Wall()],
        [Wall(), key3, Floor(), key4, Wall()],
        [Wall(), Wall(), Wall(), Wall(),
         Wall()],
    ])

    # positioning the agent in the above grid
    agent = Agent((4, 2), Orientation.N)

    return State(grid, agent)
Beispiel #6
0
def actuate_box(
    state: State,
    action: Action,
    *,
    rng: Optional[rnd.Generator] = None,
) -> None:
    """Attempts to open door

    When not holding correct key with correct color:
        `open` or `closed` -> `open`
        `locked` -> `locked`

    When holding correct key:
        any state -> `open`

    """

    if action is not Action.ACTUATE:
        return

    position = state.agent.position_in_front()

    try:
        box = state.grid[position]
    except IndexError:
        return

    if not isinstance(box, Box):
        return

    state.grid[position] = box.content
Beispiel #7
0
def test_pickup_mechanics_drop():
    grid = Grid(height=3, width=4)
    agent = Agent(position=(1, 2), orientation=Orientation.S)
    item_pos = (2, 2)

    agent.obj = Key(Color.BLUE)
    state = State(grid, agent)

    # Can drop:
    next_state = step_with_copy(state, Action.PICK_N_DROP)
    assert isinstance(next_state.agent.obj, NoneGridObject)
    assert agent.obj == next_state.grid[item_pos]

    # Cannot drop:
    state.grid[item_pos] = Wall()

    next_state = step_with_copy(state, Action.PICK_N_DROP)
    assert isinstance(next_state.grid[item_pos], Wall)
    assert agent.obj == next_state.agent.obj
Beispiel #8
0
def test_pickup_mechanics_swap():
    grid = Grid(height=3, width=4)
    agent = Agent(position=(1, 2), orientation=Orientation.S)
    item_pos = (2, 2)

    agent.obj = Key(Color.BLUE)
    grid[item_pos] = Key(Color.GREEN)
    state = State(grid, agent)

    next_state = step_with_copy(state, Action.PICK_N_DROP)
    assert state.grid[item_pos] == next_state.agent.obj
    assert state.agent.obj == next_state.grid[item_pos]
Beispiel #9
0
def test_state_hash():
    wall_position = (0, 0)
    agent_position = (0, 1)
    agent_orientation = Orientation.N
    agent_object = None

    grid = Grid(2, 2)
    grid[wall_position] = Wall()
    agent = Agent(agent_position, agent_orientation, agent_object)
    state = State(grid, agent)

    hash(state)
Beispiel #10
0
def test_actuate_box(
    content: GridObject,
    orientation: Orientation,
    action: Action,
    expected: bool,
):
    grid = Grid(2, 1)
    grid[0, 0] = box = Box(content)
    agent = Agent((1, 0), orientation)
    state = State(grid, agent)

    actuate_box(state, action)
    assert (grid[0, 0] is box) != expected
    assert (grid[0, 0] is content) == expected
def test_minigrid_observation(agent: Agent):
    grid = Grid(10, 10)
    grid[5, 5] = Wall()

    state = State(grid, agent)
    observation_space = ObservationSpace(Shape(6, 5), [], [])
    observation = minigrid_observation(
        state, observation_space=observation_space
    )
    assert observation.agent.position == (5, 2)
    assert observation.agent.orientation == Orientation.N
    assert observation.agent.obj == state.agent.obj
    assert observation.grid.shape == Shape(6, 5)
    assert isinstance(observation.grid[3, 0], Wall)
Beispiel #12
0
def test_teleport(
    position_telepod1: Position,
    position_telepod2: Position,
    position_agent: Position,
    expected: Position,
):
    grid = Grid(2, 2)
    grid[position_telepod1] = Telepod(Color.RED)
    grid[position_telepod2] = Telepod(Color.RED)

    agent = Agent(position_agent, Orientation.N)
    state = State(grid, agent)

    step_telepod(state, Action.ACTUATE)
    assert state.agent.position == expected
Beispiel #13
0
def test_actuate_door(
    door_state: Door.Status,
    door_color: Color,
    key_color: Color,
    action: Action,
    expected_state: Door.Status,
):
    # agent facing door
    grid = Grid(2, 1)
    grid[0, 0] = door = Door(door_state, door_color)
    agent = Agent((1, 0), Orientation.N, Key(key_color))
    state = State(grid, agent)

    actuate_door(state, action)
    assert door.state == expected_state

    # agent facing away
    grid = Grid(2, 1)
    grid[0, 0] = door = Door(door_state, door_color)
    agent = Agent((1, 0), Orientation.S, Key(key_color))
    state = State(grid, agent)

    actuate_door(state, action)
    assert door.state == door_state
Beispiel #14
0
def test_pickup_mechanics_pickup():
    grid = Grid(height=3, width=4)
    agent = Agent(position=(1, 2), orientation=Orientation.S)
    item_pos = (2, 2)

    grid[item_pos] = Key(Color.GREEN)
    state = State(grid, agent)

    # Pick up works
    next_state = step_with_copy(state, Action.PICK_N_DROP)
    assert grid[item_pos] == next_state.agent.obj
    assert isinstance(next_state.grid[item_pos], Floor)

    # Pick up only works with correct action
    next_state = step_with_copy(state, Action.MOVE_LEFT)
    assert grid[item_pos] != next_state.agent.obj
    assert next_state.grid[item_pos] == grid[item_pos]
Beispiel #15
0
def test_pickup_mechanics_nothing_to_pickup():
    grid = Grid(height=3, width=4)
    agent = Agent(position=(1, 2), orientation=Orientation.S)
    item_pos = (2, 2)

    state = State(grid, agent)

    # Cannot pickup floor
    next_state = step_with_copy(state, Action.PICK_N_DROP)
    assert state == next_state

    # Cannot pickup door
    grid[item_pos] = Door(Door.Status.CLOSED, Color.GREEN)
    next_state = step_with_copy(state, Action.PICK_N_DROP)
    assert state == next_state

    assert isinstance(next_state.grid[item_pos], Door)
def test_minigrid_observation_partially_observable(
    agent: Agent, expected_objects: Sequence[Sequence[GridObject]]
):
    grid = Grid.from_objects(
        [
            [Floor(), Floor(), Floor()],
            [Wall(), Wall(), Wall()],
            [Floor(), Floor(), Floor()],
        ]
    )
    state = State(grid, agent)
    observation_space = ObservationSpace(Shape(6, 5), [], [])
    observation = minigrid_observation(
        state, observation_space=observation_space
    )
    expected = Grid.from_objects(expected_objects)
    assert observation.grid == expected
def simplest_reset(
        *,
        rng: Optional[rnd.Generator] = None,  # pylint: disable=unused-argument
) -> State:
    """smallest possible room with goal right in front of agent"""

    # constructed the grid directly from objects
    grid = Grid.from_objects([
        [Wall(), Wall(), Wall()],
        [Wall(), Goal(), Wall()],
        [Wall(), Floor(), Wall()],
        [Wall(), Wall(), Wall()],
    ])

    # positioning the agent in the above grid
    agent = Agent((2, 1), Orientation.N)

    return State(grid, agent)
Beispiel #18
0
def reset_empty(
    height: int,
    width: int,
    random_agent: bool = False,
    random_goal: bool = False,
    *,
    rng: Optional[rnd.Generator] = None,
) -> State:
    """An empty environment"""

    if height < 4 or width < 4:
        raise ValueError('height and width need to be at least 4')

    rng = get_gv_rng_if_none(rng)

    # TODO test creation (e.g. count number of walls, goals, check held item)

    grid = Grid(height, width)
    draw_wall_boundary(grid)

    if random_goal:
        goal_y = rng.integers(1, height - 2, endpoint=True)
        goal_x = rng.integers(1, width - 2, endpoint=True)
    else:
        goal_y = height - 2
        goal_x = width - 2

    grid[goal_y, goal_x] = Goal()

    if random_agent:
        agent_position = rng.choice([
            position for position in grid.positions()
            if isinstance(grid[position], Floor)
        ])
        agent_orientation = rng.choice(list(Orientation))
    else:
        agent_position = (1, 1)
        agent_orientation = Orientation.E

    agent = Agent(agent_position, agent_orientation)
    return State(grid, agent)
Beispiel #19
0
def reset_rooms(  # pylint: disable=too-many-locals
    height: int,
    width: int,
    layout: Tuple[int, int],
    *,
    rng: Optional[rnd.Generator] = None,
) -> State:

    rng = get_gv_rng_if_none(rng)

    # TODO test creation (e.g. count number of walls, goals, check held item)

    layout_height, layout_width = layout

    y_splits = np.linspace(
        0,
        height - 1,
        num=layout_height + 1,
        dtype=int,
    )

    if len(y_splits) != len(set(y_splits)):
        raise ValueError(
            f'insufficient height ({height}) for layout ({layout})')

    x_splits = np.linspace(
        0,
        width - 1,
        num=layout_width + 1,
        dtype=int,
    )

    if len(x_splits) != len(set(x_splits)):
        raise ValueError(
            f'insufficient width ({height}) for layout ({layout})')

    grid = Grid(height, width)
    draw_room_grid(grid, y_splits, x_splits, Wall)

    # passages in horizontal walls
    for y in y_splits[1:-1]:
        for x_from, x_to in mitt.pairwise(x_splits):
            x = rng.integers(x_from + 1, x_to)
            grid[y, x] = Floor()

    # passages in vertical walls
    for y_from, y_to in mitt.pairwise(y_splits):
        for x in x_splits[1:-1]:
            y = rng.integers(y_from + 1, y_to)
            grid[y, x] = Floor()

    # sample agent and goal positions
    agent_position, goal_position = rng.choice(
        [
            position for position in grid.positions()
            if isinstance(grid[position], Floor)
        ],
        size=2,
        replace=False,
    )
    agent_orientation = rng.choice(list(Orientation))

    grid[goal_position] = Goal()
    agent = Agent(agent_position, agent_orientation)
    return State(grid, agent)
Beispiel #20
0
def make_moving_obstacle_state():
    grid = Grid(3, 3)
    grid[1, 1] = MovingObstacle()
    agent = MagicMock()
    return State(grid, agent)
Beispiel #21
0
def _change_agent_orientation(state: State):
    """changes agent orientation"""
    state.agent.orientation = state.agent.orientation.rotate_back()


def _change_agent_object(state: State):
    """changes agent object"""
    state.agent.obj = (Key(Color.RED) if isinstance(
        state.agent.obj, NoneGridObject) else NoneGridObject())


@pytest.mark.parametrize(
    'state',
    [
        State(Grid(2, 3), Agent((0, 0), Orientation.N)),
        State(Grid(3, 2), Agent((1, 1), Orientation.S, Key(Color.RED))),
    ],
)
def test_state_eq(state: State):
    other_state = deepcopy(state)
    assert state == other_state

    other_state = deepcopy(state)
    _change_grid(other_state)
    assert state != other_state

    other_state = deepcopy(state)
    _change_agent_position(other_state)
    assert state != other_state
def make_key_state(has_key: bool) -> State:
    """makes a simple state with a door"""
    grid = Grid(1, 1)
    obj = Key(Color.RED) if has_key else None
    agent = Agent((0, 0), Orientation.N, obj)
    return State(grid, agent)
def make_door_state(door_status: Door.Status) -> State:
    """makes a simple state with a door"""
    grid = Grid(2, 1)
    grid[0, 0] = Door(door_status, Color.RED)
    agent = Agent((1, 0), Orientation.N)
    return State(grid, agent)
def make_wall_state(orientation: Orientation = Orientation.N) -> State:
    """makes a simple state with goal object and agent on or off the goal"""
    grid = Grid(2, 1)
    grid[0, 0] = Wall()
    agent = Agent((1, 0), orientation)
    return State(grid, agent)
Beispiel #25
0
def _change_grid(state: State):
    """changes one object in the grid"""
    state.grid[0,
               0] = (Wall() if isinstance(state.grid[0,
                                                     0], Floor) else Floor())
def make_5x5_goal_state() -> State:
    """makes a simple 5x5 state with goal object in the middle"""
    grid = Grid(5, 5)
    grid[2, 2] = Goal()
    agent = Agent((0, 0), Orientation.N)
    return State(grid, agent)
Beispiel #27
0
def simple_state_without_object() -> State:
    """ Returns a 2x2 (empty) grid with an agent without an item """
    return State(
        Grid(height=2, width=2),
        Agent(position=(0, 0), orientation=Orientation.N, obj=Floor()),
    )