def test_car_can_only_overdrive_headlights_by_one_unit():
    headlight_range = 2
    with pytest.raises(ValueError):
        patient = Road(headlight_range, Car(0, speed=headlight_range + 2))

    patient = Road(headlight_range, Car(0, headlight_range + 1))
    assert patient.speed_limit() == headlight_range + 1

    patient = next(patient.successors(UP))[0]
    assert patient.speed_limit() == headlight_range + 1
    patient._car.speed == patient.speed_limit()

    patient = next(patient.successors(DOWN))[0]
    patient._car.speed == headlight_range
def test_number_of_successors_invisible_obstacle_and_variable_speeds(
        obst, action, speed):
    headlight_range = 2
    road_test = Road(headlight_range, Car(1, speed), [obst])
    probs = [prob for next_state, prob in road_test.successors(action)]
    assert (len(probs) == 4 *
            max(0, speed - int(action == LEFT or action == RIGHT)) + 1)
def test_crashing_into_right_wall():
    patient = Road(1, Car(3, 1), [])
    successors = list(patient.successors(RIGHT))
    assert len(successors) == 1
    s, p = successors[0]
    assert p == 1.0
    assert s.to_key() != patient.to_key()
    assert s.to_key() == (-1, 0, frozenset())
    assert s.to_s() == ' ' * 7 + '\n' + ' ' * 7
def test_moving_car_appears_when_stopped():
    s = Road(headlight_range=3,
             car=Car(2, 0),
             obstacles=[Pedestrian(-1, -1, speed=1, prob_of_appearing=0.5)],
             allowed_obstacle_appearance_columns=[{1}])
    successors = [(sp.to_key(), prob) for sp, prob in s.successors(NO_OP)]
    assert len(successors) == 2
    assert successors[0] == ((2, 0, frozenset()), 0.5)
    assert successors[1] == ((2, 0, frozenset([('p', 0, 1, 1, 0)])), 0.5)
def test_car_has_crashed(col):
    patient = Road(4, Car(col, 1), [])
    assert patient.has_crashed()
    assert patient.has_crashed(Car(col, 1))
    assert not patient.has_crashed(Car(0, 1))
    assert patient.to_key() == (-1, 0, frozenset())

    for action in ACTIONS:
        successors, probs = zip(*patient.successors(action))
        assert [s.to_key() for s in successors] == [(-1, 0, frozenset())]
        assert sum(probs) == pytest.approx(1.0)
def test_obstacle_appearance_prob(p):
    s = Road(headlight_range=3,
             car=Car(2, 1),
             obstacles=[Bump(-1, -1, prob_of_appearing=p)],
             allowed_obstacle_appearance_columns=[{1}])
    successors = [(sp.to_key(), prob) for sp, prob in s.successors(NO_OP)]

    if p < 1:
        assert len(successors) == 2
        assert successors[0] == ((2, 1, frozenset()), 1.0 - p)
    else:
        assert len(successors) == 1
    assert successors[int(p < 1) * 1] == ((2, 1, frozenset([('b', 0, 1, 0, 0)
                                                            ])), p)

    s = Road(headlight_range=3,
             car=Car(2, 1),
             obstacles=[
                 Bump(-1, -1, prob_of_appearing=p),
                 Pedestrian(-1, -1, prob_of_appearing=p)
             ],
             allowed_obstacle_appearance_columns=[{1}, {2}])
    successors = [(sp.to_key(), prob) for sp, prob in s.successors(NO_OP)]

    if p < 1:
        assert len(successors) == 4

        assert successors[1] == ((2, 1, frozenset([('b', 0, 1, 0, 0)])),
                                 pytest.approx(p * (1 - p)))
        assert successors[2] == ((2, 1, frozenset([('p', 0, 2, 0, 0)])),
                                 pytest.approx(p * (1 - p)))
        assert successors[0] == ((2, 1, frozenset()),
                                 pytest.approx(1 - 2 * p * (1 - p) - p * p))
    else:
        assert len(successors) == 1
    assert successors[int(p < 1) * 3] == ((2, 1,
                                           frozenset([('b', 0, 1, 0, 0),
                                                      ('p', 0, 2, 0, 0)])),
                                          pytest.approx(p * p))
def test_transition_probs_with_invisible_obstacle(obst, action):
    headlight_range = 2
    road_test = Road(headlight_range, Car(1, 1), [obst])
    probs = [prob for next_state, prob in road_test.successors(action)]
    if action == LEFT or action == RIGHT:
        assert probs == [1.0]
    else:
        assert len(probs) == 5
        sum_probs = 0.0
        for i in range(len(probs)):
            assert 0.0 <= probs[i] <= 1.0
            sum_probs += probs[i]
        assert sum_probs == pytest.approx(1.0)
        assert probs[1:] == [obst.prob_of_appearing / 4] * 4
        assert probs[0] == 1 - sum([obst.prob_of_appearing / 4] * 4)
def test_successor_function_with_identical_states(p):
    expected_probs = [
        (1 - p)**2
    ] + [2 * p * (1 - p) / 4] * 4 + [2 * p / 3.0 * p / 4.0] * 6
    expected_probs = [
        pytest.approx(prob) for prob in expected_probs if prob > 0
    ]
    state = Road(headlight_range=3,
                 car=Car(1, 1),
                 obstacles=[
                     Bump(-1, -1, prob_of_appearing=p),
                     Bump(-1, -1, prob_of_appearing=p)
                 ])
    probs = [p for (s, p) in state.successors(NO_OP)]
    assert sum(probs) == pytest.approx(1.0)
    assert probs == expected_probs
def test_obstacles_cannot_appear_in_the_same_position(p):
    s = Road(headlight_range=3,
             car=Car(2, 1),
             obstacles=[
                 Bump(-1, -1, prob_of_appearing=p),
                 Pedestrian(-1, -1, prob_of_appearing=p)
             ],
             allowed_obstacle_appearance_columns=[{1}, {1}])
    successors = [(sp.to_key(), prob) for sp, prob in s.successors(NO_OP)]

    if p < 1:
        assert len(successors) == 3
        assert successors[2] == ((2, 1, frozenset([('p', 0, 1, 0, 0)])),
                                 p * (1 - p))
        assert successors[0] == ((2, 1, frozenset()),
                                 pytest.approx(1 - p - p * (1 - p)))
    else:
        assert len(successors) == 1
    assert successors[int(p < 1) * 1] == ((2, 1, frozenset([('b', 0, 1, 0, 0)
                                                            ])), p)
    assert sum(prob for _, prob in successors) == pytest.approx(1)
Example #10
0
def test_fast_obstacles(p):
    s = Road(headlight_range=3,
             car=Car(2, 1),
             obstacles=[Pedestrian(-1, -1, speed=4, prob_of_appearing=p)],
             allowed_obstacle_appearance_columns=[{1}])
    successors = [(sp.to_key(), prob) for sp, prob in s.successors(NO_OP)]

    if p < 1:
        assert len(successors) == 5
        assert successors[3] == ((2, 1, frozenset([('p', 0, 1, 4, 0)])),
                                 (1 - p)**4 * p)
        assert successors[2] == ((2, 1, frozenset([('p', 1, 1, 4, 0)])),
                                 (1 - p)**3 * p)
        assert successors[1] == ((2, 1, frozenset([('p', 2, 1, 4, 0)])),
                                 (1 - p)**2 * p)
        assert successors[4] == ((2, 1, frozenset([('p', 3, 1, 4, 0)])),
                                 (1 - p)**1 * p)
    else:
        assert len(successors) == 1

    assert successors[0] == ((2, 1, frozenset()),
                             pytest.approx((1 - p)**5 + p))
    assert sum(prob for _, prob in successors) == pytest.approx(1)
Example #11
0
def test_probabilities_error():
    state = Road(headlight_range=3,
                 car=Car(1, 1),
                 obstacles=[Bump(-1, -1), Bump(-1, -1)])
    probs = [p for (s, p) in state.successors(NO_OP)]
    assert sum(probs) == pytest.approx(1.0)
Example #12
0
def test_successor_probabilities(speed):
    state = Road(headlight_range=6,
                 car=Car(1, speed),
                 obstacles=[Bump(-1, -1)])
    probs = [p for (s, p) in state.successors(UP)]
    assert sum(probs) == pytest.approx(1.0)
Example #13
0
def test_transition_probs_with_one_obstacle_are_1(obst, action):
    headlight_range = 2
    road_test = Road(headlight_range, Car(1, 1), [obst])
    probs = [prob for next_state, prob in road_test.successors(action)]
    assert probs == [1.0]
Example #14
0
def test_transition_probs_without_obstacles_are_always_1(action):
    headlight_range = 4
    patient = Road(headlight_range, Car(0, 1))
    for next_state, prob in patient.successors(action):
        assert prob == 1.0