def area_containing(points):
    min_x = min((p.x for p in points), default=0)
    min_y = min((p.y for p in points), default=0)
    max_x = max((p.x for p in points), default=0)
    max_y = max((p.y for p in points), default=0)

    return Area(lower=Point(min_x, min_y), upper=Point(max_x + 1, max_y + 1))
示例#2
0
def areas(draw,
          max_modulus=50,
          min_width=0,
          max_width=None,
          min_height=0,
          max_height=None):
    lower = draw(
        st.builds(
            Point,
            st.integers(min_value=-max_modulus,
                        max_value=max_modulus - min_width),
            st.integers(min_value=-max_modulus,
                        max_value=max_modulus - min_height),
        ))

    max_x = max_y = max_modulus
    if max_width is not None:
        max_x = min(max_x, lower.x + max_width)
    if max_height is not None:
        max_y = min(max_y, lower.y + max_height)

    upper = draw(
        st.builds(
            Point,
            st.integers(min_value=lower.x + min_width, max_value=max_x),
            st.integers(min_value=lower.y + min_height, max_value=max_y),
        ))

    return Area(lower, upper)
 def test_move_of_non_existent_character(self, character,
                                         non_existent_character):
     roster = Roster.for_mapping({Point(0, 0): character},
                                 Area(Point(0, 0), Point(5, 5)))
     move = Move(non_existent_character, Point(1, 1), Point(2, 1))
     with pytest.raises(ValueError):
         move.next_roster(roster)
示例#4
0
def non_overlapping_areas(draw):
    """Produce a pair of areas with no points in common.

    This works by producing the first area, then producing another area in one of the
    four overlapping areas of space that won't intersect with it. There's probably a
    neater way to do this, but this does the trick.
    """
    lower = draw(points())
    upper = draw(points())
    area = Area(lower, upper)

    left = st.builds(Point, x=st.integers(max_value=lower.x), y=st.integers())
    right = st.builds(Point,
                      x=st.integers(min_value=upper.x + 1),
                      y=st.integers())
    down = st.builds(Point, x=st.integers(), y=st.integers(max_value=lower.y))
    up = st.builds(Point,
                   x=st.integers(),
                   y=st.integers(min_value=upper.y + 1))

    second_area = draw(
        st.one_of(
            st.builds(Area, lower=left, upper=left),
            st.builds(Area, lower=right, upper=right),
            st.builds(Area, lower=down, upper=down),
            st.builds(Area, lower=up, upper=up),
        ))

    return (area, second_area)
示例#5
0
    def _split(self) -> Tuple[Area, Area, LowerFunc]:
        if self._area.width >= self._area.height:
            # Split horizontally
            midpoint_x = (self._area._lower.x + self._area._upper.x) // 2
            lower_area = Area(self._area._lower,
                              Point(midpoint_x, self._area._upper.y))
            upper_area = Area(Point(midpoint_x, self._area._lower.y),
                              self._area._upper)
            lower_func = lambda point: point.x < midpoint_x

            return (lower_area, upper_area, lower_func)
        else:
            # Split vertically
            midpoint_y = (self._area._lower.y + self._area._upper.y) // 2
            lower_area = Area(self._area._lower,
                              Point(self._area._upper.x, midpoint_y))
            upper_area = Area(Point(self._area._lower.x, midpoint_y),
                              self._area._upper)
            lower_func = lambda point: point.y < midpoint_y

            return (lower_area, upper_area, lower_func)
 def test_population(self, population):
     world_area = Area.from_zero(5, 5)
     builder = Builder(world_area, population)
     roster = builder.roster
     assert roster.width == 5
     assert roster.height == 5
     total_characters = 0
     for position, character in roster.positions:
         assert position in world_area
         assert character in population
         total_characters = total_characters + 1
     assert total_characters == len(
         [c for c in population if c is not None])
    def test_zombie_approaches_human(self):
        zombie = default_zombie()
        human = default_human()

        characters = {Point(0, 0): zombie, Point(2, 2): human}
        area = Area(Point(0, 0), Point(3, 3))
        roster = Roster.partitioned(characters,
                                    area=area,
                                    partition_func=LifeState.for_character)

        roster = Tick(roster).next()

        assert sorted(roster.positions) == [(Point(1, 1), zombie),
                                            (Point(2, 2), human)]
 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),
     }
def rosters(draw,
            inhabitants=st.one_of(st.builds(default_human),
                                  st.builds(default_zombie))):
    width, height = draw(world_dimensions), draw(world_dimensions)
    assume(width > 0)
    assume(height > 0)
    area = Area(Point(0, 0), Point(width, height))
    points = st.builds(
        Point,
        st.integers(min_value=0, max_value=width - 1),
        st.integers(min_value=0, max_value=height - 1),
    )
    characters = draw(st.dictionaries(points, inhabitants))
    return Roster.partitioned(characters,
                              area=area,
                              partition_func=LifeState.for_character)
示例#10
0
def random_barriers(counter: Iterable[Any], area: Area) -> Barriers:
    def x_coord() -> int:
        return random.randint(area._lower.x, area._upper.x - 1)

    def y_coord() -> int:
        return random.randint(area._lower.y, area._upper.y - 1)

    barrier_areas = set()
    for _ in counter:
        if random.choice([True, False]):
            # Vertical barrier
            x1 = x_coord()
            x2 = x1 + 1
            y1, y2 = sorted([y_coord(), y_coord()])
        else:
            # Horizontal barrier
            x1, x2 = sorted([x_coord(), x_coord()])
            y1 = y_coord()
            y2 = y1 + 1

        barrier_areas.add(Area(Point(x1, y1), Point(x2, y2)))

    return Barriers.for_areas(barrier_areas)
示例#11
0
    def test_width(self):
        lower = Point(0, 0)
        upper = Point(2, 2)
        area = Area(lower, upper)

        assert area.width == 2
示例#12
0
 def test_contains_lower_bound(self, points):
     lower, upper = points
     assert lower in Area(lower, upper)
示例#13
0
 def test_construction_from_zero(self, width, height):
     assert Area.from_zero(width, height) == Area(Point(0, 0),
                                                  Point(width, height))
示例#14
0
 def test_two_point_constructor(self, point_a, point_b):
     Area(point_a, point_b)
示例#15
0
 def test_from_origin_type(self, lower, upper, origin):
     area = Area(lower, upper)
     assert isinstance(area.from_origin(origin), BoundingBox)
示例#16
0
 def test_includes_midpoint(self, points):
     lower, upper = points
     midpoint = Point((lower.x + upper.x) // 2, (lower.y + upper.y) // 2)
     assert midpoint in Area(lower, upper)
示例#17
0
 def test_no_nearest_character(self, character):
     roster = Roster.for_mapping(
         {Point(1, 1): character},
         area=Area(Point(0, 0), Point(2, 2)),
     )
     assert roster.nearest_to(Point(1, 1), key=()) is None
示例#18
0
 def test_empty_roster(self):
     characters: Mapping[Point, Any] = {}
     roster = Roster.for_mapping(characters, Area(Point(0, 0), Point(5, 5)))
     assert not roster
示例#19
0
 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()
示例#20
0
        yield
        sleep_time = max(next_tick - current_time(), 0)
        sleep(sleep_time)


def clear() -> None:
    print("\033[H\033[J", end="")


if __name__ == "__main__":
    population = Population[Character](
        (DENSITY * (1 - ZOMBIE_CHANCE), default_human),
        (DENSITY * ZOMBIE_CHANCE, default_zombie),
    )

    world_area = Area.from_zero(world_width, world_height)
    barriers = random_barriers(range(BARRIERS), world_area)

    empty = RenderEmpty.SPACE if world_size_auto and barriers else RenderEmpty.DOT

    builder = Builder(world_area, population, barriers)
    roster = builder.roster
    renderer = Renderer(roster, barriers, empty=empty)

    ticks = islice(each_interval(TICK), MAX_AGE)

    tracing_context = ExitStack()

    trace_file_name = environ.get("TRACEFILE")
    if trace_file_name:
        trace_file = open(trace_file_name, mode="w")
示例#21
0
 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}
示例#22
0
    def test_height(self):
        lower = Point(0, 0)
        upper = Point(2, 2)
        area = Area(lower, upper)

        assert area.height == 2
示例#23
0
class TestArea:
    def test_no_arg_constructor(self):
        with pytest.raises(TypeError) as exc:
            Area()  # type: ignore

    def test_single_arg_constructor(self):
        with pytest.raises(TypeError):
            Area(Point(1, 3))  # type: ignore

    @given(points(), points())
    def test_two_point_constructor(self, point_a, point_b):
        Area(point_a, point_b)

    @given(st.integers(), st.integers())
    def test_construction_from_zero(self, width, height):
        assert Area.from_zero(width, height) == Area(Point(0, 0),
                                                     Point(width, height))

    @given(ordered_points())
    def test_contains_lower_bound(self, points):
        lower, upper = points
        assert lower in Area(lower, upper)

    def test_width(self):
        lower = Point(0, 0)
        upper = Point(2, 2)
        area = Area(lower, upper)

        assert area.width == 2

    def test_height(self):
        lower = Point(0, 0)
        upper = Point(2, 2)
        area = Area(lower, upper)

        assert area.height == 2

    @given(points(), points())
    def test_excludes_upper_bound(self, lower, upper):
        assert upper not in Area(lower, upper)

    @given(ordered_points())
    def test_includes_midpoint(self, points):
        lower, upper = points
        midpoint = Point((lower.x + upper.x) // 2, (lower.y + upper.y) // 2)
        assert midpoint in Area(lower, upper)

    def test_excludes_on_x_coordinate(self):
        area = Area(Point(0, 0), Point(3, 3))
        assert Point(4, 1) not in area

    def test_excludes_on_y_coordinate(self):
        area = Area(Point(0, 0), Point(3, 3))
        assert Point(1, 4) not in area

    @given(
        st.builds(Area, points(bound=ITERATION_BOUND),
                  points(bound=ITERATION_BOUND)))
    def test_iteration_covers_area(self, area):
        area_points = list(area)
        for point in area:
            assert point in area_points

    @given(
        area=st.builds(Area, points(bound=ITERATION_BOUND),
                       points(bound=ITERATION_BOUND)),
        point=points(),
    )
    @example(Area(Point(-2, -2), Point(3, 3)), Point(2, 3))
    def test_iteration_is_limited_to_area(self, area, point):
        assume(point not in area)
        assert point not in list(area)

    @given(points(), points(), points())
    def test_from_origin_type(self, lower, upper, origin):
        area = Area(lower, upper)
        assert isinstance(area.from_origin(origin), BoundingBox)

    @given(st.builds(Area, points(), points()), points(), points())
    @example(Area(Point(0, 0), Point(2, 2)), Point(0, 0), Point(1, 1))
    def test_from_origin_containment(self, area, origin, point):
        from_origin = area.from_origin(origin)

        assert (point in area) == ((point - origin) in from_origin)

    @given(st.builds(Area, points(), points()), points())
    def test_areas_and_boxes(self, area, origin):
        assert area.from_origin(origin).to_area(origin) == area

    @given(overlapping_areas())
    def test_overlapping_areas(self, areas):
        area_a, area_b = areas
        assert area_a.intersects_with(area_b)
        assert area_b.intersects_with(area_a)

    @given(non_overlapping_areas())
    @example([Area(Point(0, 0), Point(2, 2)), Area(Point(2, 0), Point(4, 2))])
    @example([Area(Point(0, 0), Point(2, 2)), Area(Point(0, 2), Point(2, 4))])
    def test_non_overlapping_areas(self, areas):
        area_a, area_b = areas
        assert not area_a.intersects_with(area_b)
        assert not area_b.intersects_with(area_a)

    @given(
        areas=st.lists(st.builds(Area, points(), points()), min_size=2),
        point=points(),
    )
    def test_point_outside_intersection(self, areas, point):
        assume(any(point not in area for area in areas))
        intersection = reduce(lambda a, b: a.intersect(b), areas)
        assert point not in intersection

    @given(points_and_containing_areas())
    def test_point_inside_intersection(self, point_and_areas):
        point, areas = point_and_areas
        intersection = reduce(lambda a, b: a.intersect(b), areas)
        assert point in intersection
示例#24
0
 def test_excludes_upper_bound(self, lower, upper):
     assert upper not in Area(lower, upper)
示例#25
0
 def test_no_arg_constructor(self):
     with pytest.raises(TypeError) as exc:
         Area()  # type: ignore
示例#26
0
 def test_excludes_on_y_coordinate(self):
     area = Area(Point(0, 0), Point(3, 3))
     assert Point(1, 4) not in area
示例#27
0
 def test_single_arg_constructor(self):
     with pytest.raises(TypeError):
         Area(Point(1, 3))  # type: ignore
示例#28
0
@given(areas().flatmap(lambda a: st.tuples(st.just(a), points_in(a))))
def test_no_nearest(area_and_point):
    area, point = area_and_point
    tree = SpaceTree.build(area=area, positions={point: object()})

    assert tree.nearest_to(point) is None


@settings(max_examples=25)
@given(areas().flatmap(lambda a: st.tuples(
    st.just(a),
    st.lists(points_in(a), min_size=2, unique=True).flatmap(list_and_element),
)))
@example(
    area_and_points=(
        Area(Point(x=-257, y=0), Point(x=0, y=3)),
        (
            [
                Point(x=-1, y=0),
                Point(x=-3, y=0),
                Point(x=-1, y=1),
                Point(x=-1, y=2),
                Point(x=-2, y=1),
                Point(x=-5, y=0),
                Point(x=-6, y=0),
                Point(x=-7, y=0),
                Point(x=-2, y=0),
            ],
            Point(x=-3, y=0),
        ),
    ), )
示例#29
0
 def test_fails_if_instigator_not_in_roster(self, instigator, target):
     roster = Roster.for_mapping({Point(0, 0): target},
                                 Area(Point(0, 0), Point(5, 5)))
     action = ChangeCharacter(instigator, target, paint_blue)
     with pytest.raises(ValueError):
         action.next_roster(roster)