def test_edible_apple(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    apple = Apple(reward=16,
                  shrink_ratio=0.5,
                  invisible_range=30 * 16,
                  min_reward=1)

    playground.add_agent(agent, ((100, 100), 0))
    playground.add_element(apple, ((140, 100), 0))

    engine = Engine(playground, time_limit=100)

    actions = {agent: {agent.activate: 1}}

    for rew in [16, 8, 4, 2, 1]:

        engine.step(actions)
        assert agent.reward == rew

    engine.step(actions)
    assert agent.reward == 0
    assert apple not in playground.elements

    engine.reset()

    for rew in [16, 8, 4, 2, 1]:
        engine.step(actions)
        assert agent.reward == rew

    engine.step(actions)
    assert agent.reward == 0
    assert apple not in playground.elements
Exemple #2
0
def test_add_remove_agent_in_area(base_forward_agent_random):
    playground_1 = SingleRoom((800, 400))
    agent = base_forward_agent_random

    areas = {
        'up': [0, 800, 0, 200],
        'down': [0, 800, 200, 400],
        'right': [400, 800, 0, 400],
        'left': [0, 400, 0, 400],
        'up-right': [400, 800, 0, 200],
        'up-left': [0, 400, 0, 200],
        'down-right': [400, 800, 200, 400],
        'down-left': [0, 400, 200, 400],
        'center': [200, 600, 100, 300]
    }

    for area_name, coord in areas.items():

        location, size = playground_1.grid_rooms[0][0].get_partial_area(
            area_name)

        pos_area_sampler = CoordinateSampler(location,
                                             area_shape='rectangle',
                                             size=size)

        playground_1.add_agent(agent, pos_area_sampler)

        min_x, max_x, min_y, max_y = coord

        assert min_x < agent.position[0] < max_x
        assert min_y < agent.position[1] < max_y

        playground_1.remove_agent(agent)
def test_grasping():

    playground = SingleRoom(size=(200, 200))

    agent_1 = BaseAgent(
        controller=External(),
        interactive=True,
        rotate=True,
        lateral=False,
        radius=10,
    )
    playground.add_agent(agent_1, ((100, 100), 0))

    elem = Physical(config_key='circle', mass=5, radius=10, graspable=True)
    initial_position_elem = ((100 + agent_1.base_platform.radius + elem.radius + 2, 100), 0)
    playground.add_element(elem, initial_position_elem)

    engine = Engine(playground)

    actions = {agent_1: {agent_1.grasp: 1, agent_1.rotation_velocity: 1}}
    engine.step(actions)
    engine.step(actions)

    assert (elem.position, elem.angle) != initial_position_elem
    assert elem.held_by[0].part.agent is agent_1

    engine.step()
    assert not elem.held_by
Exemple #4
0
def test_portal(base_forward_interactive_agent_external):

    playground = SingleRoom(size=(200, 200))
    agent = base_forward_interactive_agent_external

    portal_1 = Portal(color=PortalColor.RED)
    portal_2 = Portal(color=PortalColor.BLUE)
    portal_3 = Portal(color=PortalColor.GREEN)
    portal_4 = Portal(color=(50, 50, 50))

    playground.add_agent(agent, ((100, 80), 0))
    playground.add_element(portal_1, ((140, 80), math.pi))
    playground.add_element(portal_2, ((50, 50), math.pi/2))
    playground.add_element(portal_3, ((50, 120), -math.pi/2))
    playground.add_element(portal_4, ((150, 160), math.pi))

    portal_1.destination = portal_2
    portal_3.destination = portal_4

    engine = Engine(playground, time_limit=1000)

    actions = {agent: {agent.longitudinal_force: 1}}

    while engine.game_on:
        engine.step(actions)

    assert agent.position[1] == 160
    assert agent.angle % (2 * math.pi) == math.pi
def test_openclose_switch(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    door = Door(start_point=(180, 180), end_point=(160, 160), door_depth=5)
    playground.add_element(door, ((150, 150), 0))

    switch_1 = OpenCloseSwitch(door=door, invisible_range=40)
    playground.add_element(switch_1, ((140, 100), 0))

    playground.add_agent(agent, ((100, 100), 0))

    engine = Engine(playground, time_limit=100)
    actions = {agent: {agent.activate: 1}}

    engine.step(actions)
    assert door not in playground.elements

    engine.step(actions)
    assert door in playground.elements

    engine.step(actions)
    assert door not in playground.elements

    engine.step(actions)
    assert door in playground.elements
Exemple #6
0
def test_lock_key_door(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    playground.add_agent(agent, ((80, 100), 0))

    door = Door(start_point=(180, 180), end_point=(160, 160), door_depth=5)
    playground.add_element(door)

    switch = ContactSwitch(door=door)
    playground.add_element(switch, ((140, 100), 0))

    engine = Engine(playground, time_limit=200)

    # agent grasps and move forward
    actions = {agent: { agent.longitudinal_force: 1}}

    while engine.game_on:

        engine.step(actions)

    assert door not in playground.elements

    # agent stands still

    engine.reset()
    assert door in playground.elements

    while engine.game_on:
        engine.step()

    assert door in playground.elements
def test_dispenser_limit(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    dispenser = Dispenser(
        element_produced=Candy,
        production_area=CoordinateSampler(center=(50, 100),
                                          area_shape='circle',
                                          radius=10),
        production_limit=1,
        invisible_range=40,
        element_produced_params={'reward': 1})

    playground.add_agent(agent, ((100, 100), 0))
    playground.add_element(dispenser, ((140, 100), 0))

    engine = Engine(playground, time_limit=100)

    total_rew = 0

    while engine.game_on:

        if engine.elapsed_time < 50:
            actions = {agent: {agent.activate: 1}}

        else:
            actions = {agent: {agent.longitudinal_force: -1.}}
        engine.step(actions)
        total_rew += agent.reward

    assert total_rew == 1
Exemple #8
0
def test_add_remove_agent(base_forward_agent_random):
    playground_1 = SingleRoom(size=(200, 200))
    playground_2 = SingleRoom(size=(200, 200))
    agent = base_forward_agent_random
    playground_1.add_agent(agent)
    playground_1.remove_agent(agent)
    assert playground_1.agents == []
    playground_2.add_agent(agent)
Exemple #9
0
def test_engine(base_forward_agent_random):
    playground = SingleRoom(size=(200, 200))
    agent = base_forward_agent_random
    engine = Engine(playground, time_limit=100)
    playground.add_agent(agent)
    assert len(engine.agents) == 1
    playground.remove_agent(agent)
    assert len(engine.agents) == 0
def test_timer_switch(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    door = Door(start_point=(180, 180), end_point=(160, 160), door_depth=5)
    playground.add_element(door, ((150, 150), 0))

    timer = CountDownTimer(duration=10)
    switch_1 = TimerSwitch(door=door, invisible_range=40, timer=timer)
    playground.add_element(switch_1, ((140, 100), 0))
    playground.add_timer(timer, switch_1)

    playground.add_agent(agent, ((100, 100), 0))

    engine = Engine(playground, time_limit=100)
    actions = {agent: {agent.activate: 1}}

    assert door in playground.elements

    # Open a first time
    engine.step(actions)
    assert door not in playground.elements

    for i in range(9):
        engine.step()
        assert door not in playground.elements

    engine.step()
    assert door in playground.elements

    # Open a second time
    engine.step(actions)
    assert door not in playground.elements

    for i in range(9):
        engine.step()
        assert door not in playground.elements

    engine.step()
    assert door in playground.elements

    # Open multiple time time
    engine.step(actions)
    engine.step(actions)
    engine.step(actions)
    engine.step(actions)
    assert door not in playground.elements

    for i in range(9):
        engine.step()
        assert door not in playground.elements

    engine.step()
    assert door in playground.elements
Exemple #11
0
def test_vending_machine(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    playground.add_agent(agent, ((80, 100), 0))

    vending = VendingMachine(quantity_rewards=3, reward=10)
    playground.add_element(vending, ((140, 100), 0))

    coin = Coin(graspable=True, vending_machine=vending, radius=5)
    playground.add_element(
        coin, ((80 + agent.base_platform.radius + coin.radius + 2, 100), 0))

    engine = Engine(playground, time_limit=100)

    # agent grasps and move forward

    total_rew = 0

    actions = {agent: {agent.grasp: 1, agent.longitudinal_force: 1}}

    while engine.game_on:
        engine.step(actions)
        total_rew += agent.reward
    assert total_rew == 10
    assert not agent.grasped_elements

    engine.step(actions)
    assert not agent.grasped_elements

    # test reset
    engine.reset()
    total_rew = 0

    while engine.game_on:
        actions = {agent: {agent.grasp: 1, agent.longitudinal_force: 1}}
        engine.step(actions)
        total_rew += agent.reward

    assert total_rew > 0

    # agent stands still

    engine.reset()
    total_rew = 0

    while engine.game_on:
        engine.step()
        total_rew += agent.reward

    assert total_rew == 0
Exemple #12
0
def test_list_sensors():

    playground = SingleRoom(size=(300, 200))

    agent_1 = BaseAgent(
        controller=External(),
        interactive=False,
        rotate=False,
        lateral=False
    )

    sensor_1 = RgbCamera(anchor=agent_1.base_platform, invisible_elements=agent_1.parts, range=400)
    sensor_2 = Lidar(anchor=agent_1.base_platform, invisible_elements=agent_1.parts, range=400)
    sensor_3 = SemanticRay(anchor=agent_1.base_platform, invisible_elements=agent_1.parts, range=400)

    agent_1.add_sensor(sensor_1)
    agent_1.add_sensor(sensor_2)
    agent_1.add_sensor(sensor_3)

    playground.add_agent(agent_1, ((100, 100), 0))

    disabler = SensorDisabler(disabled_sensor_types=[RgbCamera, SemanticRay])
    playground.add_element(disabler, ((100, 100), 0))

    engine = Engine(playground)
    engine.step()
    engine.update_observations()

    for sensor in [sensor_1, sensor_2, sensor_3]:

        if isinstance(sensor, RgbCamera):
            assert sensor._disabled
            assert np.all(sensor.sensor_values == sensor._get_null_sensor())

        elif isinstance(sensor, SemanticRay):
            assert sensor._disabled
            assert sensor.sensor_values == sensor._get_null_sensor()

        else:

            assert not sensor._disabled

            if isinstance(sensor.sensor_values, np.ndarray):
                assert not np.all(sensor.sensor_values == sensor._get_null_sensor())

            else:
                assert not sensor.sensor_values == sensor._get_null_sensor()
Exemple #13
0
def test_normalize_position_sensor():

    agent = BaseAgent(controller=External(), rotate=True)

    pos = Position(anchor=agent.base_platform, normalize=False)
    pos_norm = Position(anchor=agent.base_platform, normalize=True)
    agent.add_sensor(pos)
    agent.add_sensor(pos_norm)

    playground = SingleRoom((400, 400))
    playground.add_agent(agent, initial_coordinates=((100, 200), math.pi))

    engine = Engine(playground, time_limit=1000)
    engine.update_observations()

    assert np.all(pos.sensor_values == np.asarray((100, 200, math.pi)))
    assert np.all(pos_norm.sensor_values == np.asarray((0.25, 0.5, 0.5)))
def test_termination_zone(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    goal = GoalZone(reward=100, size=(5, 5))
    playground.add_agent(agent, ((100, 100), 0))
    playground.add_element(goal, ((140, 100), 0))

    engine = Engine(playground, time_limit=100)

    actions = {agent: {agent.longitudinal_force: 1}}

    while engine.game_on:
        engine.step(actions)

    assert agent.reward > 0
    assert playground.done
def test_reward_zone(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    healing_zone = HealingZone(reward=3, limit=31)
    playground.add_agent(agent, ((100, 100), 0))
    playground.add_element(healing_zone, ((100, 100), 0))

    engine = Engine(playground, time_limit=50)

    total_rew = 0

    while engine.game_on:
        engine.step()
        total_rew += agent.reward

    assert total_rew == 31
Exemple #16
0
def test_beam_orientation(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))
    agent = base_forward_interactive_agent_external
    beam = InvisibleBeam(destination=((50, 50), math.pi/2))

    playground.add_agent(agent, ((100, 100), 0))
    playground.add_element(beam, ((140, 100), 0))

    engine = Engine(playground, time_limit=100)

    actions = {agent: {agent.longitudinal_force: 1}}

    while engine.game_on:
        engine.step(actions)

    assert agent.position[0] == 50

    engine.terminate()
Exemple #17
0
def test_contact_candy(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    candy = Candy(reward=12)
    playground.add_agent(agent, ((60, 100), 0))
    playground.add_element(candy, ((160, 100), 0))

    engine = Engine(playground, time_limit=100)

    total_rew = 0
    actions = {agent: {agent.longitudinal_force: 1}}

    while engine.game_on:
        engine.step(actions)
        total_rew += agent.reward

    assert total_rew > 0
def test_reward_changer(reward, base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    color_1 = (100, 100, 0)
    color_2 = (0, 100, 100)
    colors = [color_1, color_2]
    durations = [3, 4]

    roa = RewardOnActivation(reward=reward)
    change = FlipReward(textures=colors, element_changed=roa)
    timer = PeriodicTimer(durations=durations)

    playground.add_agent(agent, ((80, 100), 0))
    playground.add_element(
        roa, ((80 + agent.base_platform.radius + roa.radius + 2, 100), 0))
    playground.add_element(change, ((40, 40), 0))
    playground.add_timer(timer, change)

    engine = Engine(playground, time_limit=100)
    actions = {agent: {agent.activate: 1}}

    index_color = 0

    while engine.game_on:

        sign = 1

        for d in durations:

            for t in range(d - 1):
                engine.step(actions)
                assert change.texture.base_color == colors[index_color]
                assert agent.reward == sign * reward

            sign *= -1
            index_color = (index_color + 1) % len(colors)

            engine.step(actions)

            assert change.texture.base_color == colors[index_color]
            assert agent.reward == sign * reward
def test_grasping_sensor():

    playground = SingleRoom(size=(200, 200))

    agent_1 = BaseAgent(
        controller=External(),
        interactive=True,
        rotate=True,
        lateral=False,
        radius=10,
    )

    rgb = RgbCamera(anchor=agent_1.base_platform)
    agent_1.add_sensor(rgb)

    playground.add_agent(agent_1, ((100, 100), 0))

    elem = Physical(config_key='circle', mass=5, radius=10, graspable=True)
    initial_position_elem = ((100 + agent_1.base_platform.radius + elem.radius + 2, 100), 0)
    playground.add_element(elem, initial_position_elem)

    engine = Engine(playground)
    engine.step()
    engine.update_observations()
    obs_1 = rgb.sensor_values[:]

    actions = {agent_1: {agent_1.grasp: 1}}
    engine.step(actions)
    engine.update_observations()
    obs_2 = rgb.sensor_values[:]

    engine.update_observations(grasped_invisible=True)
    obs_3 = rgb.sensor_values[:]

    assert (obs_1 == obs_2).all()
    assert (obs_3 != obs_1).any()

    playground.remove_add_within(elems_remove=[elem], elems_add=[])
    engine.step()
    engine.update_observations()
    obs_4 = rgb.sensor_values[:]

    assert (obs_4 == obs_3).all()
Exemple #20
0
def test_disable_communication_receiver():

    playground = SingleRoom(size=(300, 200))

    agent_1 = BaseAgent(
        controller=External(),
        interactive=False,
        rotate=False,
        lateral=False
    )

    agent_2 = BaseAgent(
        controller=External(),
        interactive=False,
        rotate=False,
        lateral=False
    )

    comm_1 = CommunicationDevice(agent_1.base_platform)
    agent_1.add_communication(comm_1)

    comm_2 = CommunicationDevice(agent_2.base_platform)
    agent_2.add_communication(comm_2)

    playground.add_agent(agent_1, ((100, 100), 0))
    playground.add_agent(agent_2, ((200, 100), 0))

    disabler = CommunicationDisabler()
    playground.add_element(disabler, ((200, 100), 0))

    assert agent_1.communication
    assert agent_2.communication

    engine = Engine(playground)

    messages = [(comm_1, 'test', comm_2)]
    engine.step(messages=messages)

    assert not comm_1._disabled
    assert comm_2._disabled

    assert comm_2.received_message == []
Exemple #21
0
def test_beam_area(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))
    agent = base_forward_interactive_agent_external

    area = CoordinateSampler(center=(50, 50), area_shape='rectangle', size=(20, 20))

    beam = InvisibleBeam(destination=area)

    playground.add_agent(agent, ((100, 100), 0))
    playground.add_element(beam, ((140, 100), 0))

    engine = Engine(playground, time_limit=100)

    actions = {agent: {agent.longitudinal_force: 1}}

    while not agent.has_teleported:
        engine.step(actions)

    assert 30 <= agent.position[0] <= 80
    assert 30 <= agent.position[1] <= 80
Exemple #22
0
def test_contact_termination(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    goal = VisibleEndGoal(reward=100)
    playground.add_agent(agent, ((100, 100), 0))
    playground.add_element(goal, ((140, 100), 0))

    engine = Engine(playground, time_limit=100)

    total_rew = 0
    actions = {agent: {agent.longitudinal_force: 1}}

    while engine.game_on:
        engine.step(actions)
        total_rew += agent.reward

    assert total_rew > 0
    assert playground.done
Exemple #23
0
def test_beam_homing(base_forward_interactive_agent_external):

    playground = SingleRoom(size=(200, 200))
    agent = base_forward_interactive_agent_external

    destination = Physical(config_key='pentagon')
    playground.add_element(destination, ((70, 70), 0))

    beam = VisibleBeamHoming(destination=destination, invisible_range=4)

    playground.add_agent(agent, ((100, 100), 0))
    playground.add_element(beam, ((140, 100), 0))

    engine = Engine(playground, time_limit=100)

    actions = {agent: {agent.longitudinal_force: 1}}

    while not agent.has_teleported:
        engine.step(actions)

    assert agent.position.get_distance(destination.position) < agent.base_platform.radius + destination.radius + 4 + 3
def test_reward_on_activation(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    roa = RewardOnActivation(reward=5, quantity_rewards=10, invisible_range=40)

    playground.add_agent(agent, ((100, 100), 0))
    playground.add_element(roa, ((140, 100), 0))

    engine = Engine(playground, time_limit=100)

    total_rew = 0
    actions = {agent: {agent.activate: 1}}

    while engine.game_on:

        engine.step(actions)
        total_rew += agent.reward

    assert total_rew == 50
def test_equip_communication(comm_radius):

    playground = SingleRoom(size=(300, 200))

    agent_1 = BaseAgent(controller=External(),
                        interactive=False,
                        rotate=False,
                        lateral=False)

    agent_2 = BaseAgent(controller=External(),
                        interactive=False,
                        rotate=False,
                        lateral=False)

    comm_1 = CommunicationDevice(agent_1.base_platform, comm_radius)
    agent_1.add_communication(comm_1)

    playground.add_agent(agent_1, ((100, 100), 0))
    playground.add_agent(agent_2, ((200, 100), 0))

    assert agent_1.communication
    assert not agent_2.communication
def test_moving_element(basic_element):
    playground = SingleRoom(size=(200, 200))

    agent = BaseAgent(controller=External(),
                      interactive=False,
                      rotate=False,
                      lateral=False)
    actions = {agent: {agent.longitudinal_force: 1.}}

    playground.add_agent(agent, ((50, 100), 0))
    playground.add_element(basic_element, ((100, 100), 0))

    engine = Engine(playground, time_limit=100)

    while engine.game_on:
        engine.step(actions)

    if basic_element.movable:
        assert agent.position[0] > 100
        assert basic_element.position[0] > 100
    else:
        assert basic_element.position[0] == 100
Exemple #27
0
def test_chest(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    playground.add_agent(agent, ((80, 100), 0))

    chest = Chest(treasure=Candy())
    playground.add_element(chest, ((140, 100), 0))

    key = Key(graspable=True, locked_elem=chest, radius=5)
    playground.add_element(
        key, ((80 + agent.base_platform.radius + key.radius + 2, 100), 0))

    engine = Engine(playground, time_limit=200)

    # agent grasps and move forward

    total_rew = 0

    while engine.game_on:

        actions = {agent: {agent.grasp: 1, agent.longitudinal_force: 1}}
        engine.step(actions)
        total_rew += agent.reward

    assert total_rew > 0

    # agent stands still

    engine.reset()
    total_rew = 0

    while engine.game_on:
        engine.step()
        total_rew += agent.reward

    assert total_rew == 0
def test_transmission_range(range_1, range_2, distance, in_range):

    playground = SingleRoom(size=(300, 200))

    agent_1 = BaseAgent(controller=External(),
                        interactive=False,
                        rotate=False,
                        lateral=False)

    agent_2 = BaseAgent(controller=External(),
                        interactive=False,
                        rotate=False,
                        lateral=False)

    comm_1 = CommunicationDevice(agent_1.base_platform, range_1)
    agent_1.add_communication(comm_1)

    comm_2 = CommunicationDevice(agent_2.base_platform, range_2)
    agent_2.add_communication(comm_2)

    playground.add_agent(agent_1, ((100, 100), 0))
    playground.add_agent(agent_2, ((100 + distance, 100), 0))

    assert agent_1.communication
    assert agent_2.communication

    assert comm_1.in_transmission_range(comm_2) is in_range
    assert comm_2.in_transmission_range(comm_1) is in_range

    engine = Engine(playground)

    messages = [(comm_1, 'test', comm_2)]
    engine.step(messages=messages)

    if in_range:
        assert comm_2.received_message == [(comm_1, 'test')]
    else:
        assert comm_2.received_message == []
Exemple #29
0
def test_lock_key_door(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    playground.add_agent(agent, ((80, 100), 0))

    door = Door(start_point=(180, 180), end_point=(160, 160), door_depth=5)
    playground.add_element(door)

    lock = Lock(door)
    playground.add_element(lock, ((140, 100), 0))

    key = Key(graspable=True, locked_elem=lock, radius=5)
    playground.add_element(
        key, ((80 + agent.base_platform.radius + key.radius + 2, 100), 0))

    engine = Engine(playground, time_limit=200)

    # agent grasps and move forward

    while engine.game_on:

        actions = {agent: {agent.grasp: 1, agent.longitudinal_force: 1}}
        engine.step(actions)

    assert door not in playground.elements

    # agent stands still

    engine.reset()
    assert door in playground.elements

    while engine.game_on:
        engine.step()

    assert door in playground.elements
def test_color_changing(base_forward_interactive_agent_external):
    playground = SingleRoom(size=(200, 200))

    agent = base_forward_interactive_agent_external

    color_1 = (100, 100, 0)
    color_2 = (0, 100, 100)
    color_3 = (20, 200, 2)
    colors = [color_1, color_2, color_3]
    durations = [3, 4, 5]

    elem = ColorChanging(textures=colors)

    playground.add_agent(agent, ((80, 100), 0))
    playground.add_element(
        elem, ((80 + agent.base_platform.radius + elem.radius + 2, 100), 0))

    timer = PeriodicTimer(durations=durations)

    playground.add_timer(timer, elem)

    engine = Engine(playground, time_limit=100)

    while engine.game_on:

        index_color = 0

        for d in durations:

            for _ in range(d):
                assert elem.texture.base_color == colors[index_color]
                engine.step()

            index_color += 1

        assert elem.texture.base_color == colors[0]