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)
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)
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)
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)
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]
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