Beispiel #1
0
 def test_runs_away_from_zombie(self, human, environment_and_limits):
     environment, limits = environment_and_limits
     # Make sure there's actually room to run away
     assume(limits.intersect(BoundingBox.range(1)) == BoundingBox.range(1))
     move = human.move(FakeViewpoint(environment), limits)
     zombie_vector = environment[0][0]
     assert (zombie_vector - move).distance > zombie_vector.distance
class Undead:

    life_state = LifeState.UNDEAD
    movement_range = BoundingBox.range(1)
    attack_range = BoundingBox.range(1)
    next_state = None

    def attack(self, target_vectors: SupportsNearestHuman) -> Optional[Vector]:
        nearest_human = target_vectors.nearest_human
        if nearest_human is not None and nearest_human in self.attack_range:
            return nearest_human
        else:
            return None

    def best_move(
        self, target_vectors: SupportsNearestHuman, available_moves: Iterable[Vector]
    ) -> Vector:
        nearest_human = target_vectors.nearest_human
        if nearest_human:

            def move_rank(move: Vector) -> Tuple[float, float]:
                assert nearest_human is not None
                return ((nearest_human - move).distance, move.distance)

            return min(available_moves, key=move_rank)
        else:
            return shortest(available_moves)

    def __eq__(self, other: object) -> bool:
        return isinstance(other, Undead)
 def test_viewpoint_multiple_characters(self, char1, char2):
     roster = Roster.for_mapping(
         {
             Point(1, 1): char1,
             Point(2, 0): char2
         },
         area=Area(Point(0, 0), Point(3, 3)),
     )
     viewpoint = Viewpoint(Point(0, 1), roster)
     assert viewpoint.occupied_points_in(
         BoundingBox.range(1)) == {Vector(1, 0)}
     assert viewpoint.occupied_points_in(BoundingBox.range(5)) == {
         Vector(1, 0),
         Vector(2, -1),
     }
Beispiel #4
0
    def test_state_change_action(self):
        character = Character(state=Dead(age=20))
        viewpoint = FakeViewpoint([])
        next_action = character.next_action(viewpoint, BoundingBox.range(5),
                                            FakeActions())

        assert next_action == StateChange(Undead())
Beispiel #5
0
 def test_attack_action(self):
     character = Character(state=Undead())
     target = default_human()
     next_action = character.next_action(
         FakeViewpoint([(Vector(1, 1), target)]), BoundingBox.range(5),
         FakeActions())
     assert next_action == Attack(Vector(1, 1))
Beispiel #6
0
 def test_move_action(self):
     character = Character(state=Undead())
     environment = FakeViewpoint([(Vector(3, 3), default_human())])
     next_action: Action = character.next_action(environment,
                                                 BoundingBox.range(5),
                                                 FakeActions())
     assert next_action == Move(Vector(1, 1))
class Dead:
    def __init__(self, age: int = 0):
        self._age = age

    life_state = LifeState.DEAD
    movement_range = BoundingBox.range(0)

    _resurrection_age: ClassVar[int] = 20

    def attack(self, target_vectors: TargetVectors) -> Optional[Vector]:
        return None

    def best_move(
        self, target_vectors: TargetVectors, available_moves: Iterable[Vector]
    ) -> Vector:
        if Vector.ZERO not in available_moves:
            raise ValueError("Zero move unavailable for dead character")
        return Vector.ZERO

    @property
    def next_state(self) -> State:
        if self._age >= self._resurrection_age:
            return Undead()
        else:
            return Dead(self._age + 1)

    def __eq__(self, other: object) -> bool:
        return isinstance(other, Dead) and self._age == other._age
class Living:

    life_state = LifeState.LIVING
    movement_range = BoundingBox.range(2)
    next_state = None

    def attack(self, target_vectors: TargetVectors) -> Optional[Vector]:
        return None

    def best_move(
        self, target_vectors: TargetVectors, available_moves: Iterable[Vector]
    ) -> Vector:
        def nearest_zombie(move: Vector) -> Optional[Vector]:
            if (nearest := target_vectors.nearest_zombie_to(move)) is not None:
                return nearest - move
            else:
Beispiel #9
0
 def test_invalid_range(self):
     with pytest.raises(ValueError):
         BoundingBox.range(-1)
Beispiel #10
0
 def test_range(self, radius, vector):
     bounding_box = BoundingBox.range(radius)
     if abs(vector.dx) <= radius and abs(vector.dy) <= radius:
         assert vector in bounding_box
     else:
         assert vector not in bounding_box
Beispiel #11
0
 def test_total_barrier(self):
     obstacles = {Vector(1, y) for y in range(-2, 3)}
     available = available_moves(BoundingBox.range(2), obstacles)
     assert available == set(BoundingBox(Vector(-2, -2), Vector(1, 3)))
 def test_viewpoint_single_character(self, character):
     roster = Roster.for_mapping({Point(1, 1): character},
                                 area=Area(Point(0, 0), Point(2, 2)))
     viewpoint = Viewpoint(Point(1, 1), roster)
     assert viewpoint.occupied_points_in(
         BoundingBox.range(2)) == {Vector.ZERO}
 def test_empty_viewpoint(self):
     characters: Mapping[Point, Any] = {}
     roster = Roster.for_mapping(characters,
                                 area=Area(Point(0, 0), Point(2, 2)))
     viewpoint = Viewpoint(Point(1, 1), roster)
     assert viewpoint.occupied_points_in(BoundingBox.range(2)) == set()