Example #1
0
def bresenham(line: Line):
    x1 = line.begin.x
    y1 = line.begin.y
    x2 = line.end.x
    y2 = line.end.y
    dx = x2 - x1
    dy = y2 - y1
    is_steep = abs(dy) > abs(dx)
    if is_steep:
        x1, y1 = y1, x1
        x2, y2 = y2, x2
    swapped = False
    if x1 > x2:
        x1, x2 = x2, x1
        y1, y2 = y2, y1
        swapped = True
    dx = x2 - x1
    dy = y2 - y1
    error = int(dx / 2.0)
    y_step = 1 if y1 < y2 else -1
    y = y1
    points = []
    for x in range(x1, x2 + 1):
        coord = Point(y, x) if is_steep else Point(x, y)
        points.append(coord)
        error -= abs(dy)
        if error < 0:
            y += y_step
            error += dx
    if swapped:
        points.reverse()
    return points
Example #2
0
 def test_for_initial_points_get_returns_direction(self):
     get_direction = DirectionDetector(
         begin=Point(0, 0),
         end=Point(1, 0),
         min_distance=1,
     )
     assert_that(get_direction(), equal_to(Point(1, 0)))
Example #3
0
 def test_for_graph_with_one_node_with_arc_returns_empty(self):
     result = shortest_path_with_direction(
         graph={0: Node(position=Point(0, 0), arcs=[Arc(dst=0, weight=1)])},
         src=0,
         dst=0,
         initial_direction=Point(1, 0),
         forbidden={})
     assert_that(list(result), equal_to([]))
Example #4
0
def tiles_at_line(line: Line):
    tiles = bresenham(line)
    for i, current in islice(enumerate(tiles), len(tiles) - 1):
        yield current
        following = tiles[i + 1]
        if current.x != following.x and current.y != following.y:
            yield current + Point(following.x - current.x, 0)
            yield current + Point(0, following.y - current.y)
Example #5
0
 def test_update_by_nearest_than_min_distance_returns_initial(self):
     get_direction = DirectionDetector(
         begin=Point(0, 0),
         end=Point(1, 0),
         min_distance=1,
     )
     get_direction.update(Point(1, 0.5))
     assert_that(get_direction(), equal_to(Point(1, 0)))
Example #6
0
 def test_update_by_exact_min_distance_returns_updated(self):
     get_direction = DirectionDetector(
         begin=Point(0, 0),
         end=Point(1, 0),
         min_distance=1,
     )
     get_direction.update(Point(1, 1))
     assert_that(get_direction(), equal_to(Point(0, 1)))
Example #7
0
 def test_for_2_2_left_right_and_any_left_right_returns_equal(self):
     result = adjust_path_point(previous=None,
                                current=TypedPoint(Point(2, 2),
                                                   PointType.LEFT_RIGHT),
                                following=TypedPoint(
                                    Point(4, 2), PointType.LEFT_RIGHT),
                                shift=1,
                                tile_size=4)
     assert_that(result, equal_to(Point(2, 2)))
Example #8
0
 def test_for_2_2_left_top_and_any_following_and_shift_1_returns_1_1(self):
     result = adjust_path_point(
         previous=None,
         current=TypedPoint(Point(2, 2), PointType.LEFT_TOP),
         following=TypedPoint(Point(2, 4), PointType.BOTTOM_TOP),
         shift=1,
         tile_size=4,
     )
     assert_that(result, equal_to(Point(1, 1)))
Example #9
0
 def test_for_2_2_left_right_and_any_top_left_previous_and_shift_1_returns_2_3(
         self):
     result = adjust_path_point(
         previous=TypedPoint(Point(0, 2), PointType.TOP_RIGHT),
         current=TypedPoint(Point(2, 2), PointType.LEFT_RIGHT),
         following=None,
         shift=1,
         tile_size=4,
     )
     assert_that(result, equal_to(Point(2, 2)))
Example #10
0
 def test_for_graph_with_two_disconnected_nodes_returns_empty(self):
     result = shortest_path_with_direction(graph={
         0:
         Node(position=Point(0, 0), arcs=[]),
         1:
         Node(position=Point(1, 0), arcs=[]),
     },
                                           src=0,
                                           dst=1,
                                           initial_direction=Point(1, 0),
                                           forbidden={})
     assert_that(list(result), equal_to([]))
Example #11
0
 def generate():
     l = Point(pos.x - 1, pos.y)
     if is_valid(l) and tiles[l.x][l.y] in HAS_LEFT_INPUT:
         yield l
     r = Point(pos.x + 1, pos.y)
     if is_valid(r) and tiles[r.x][r.y] in HAS_RIGHT_INPUT:
         yield r
     t = Point(pos.x, pos.y - 1)
     if is_valid(t) and tiles[t.x][t.y] in HAS_TOP_INPUT:
         yield t
     b = Point(pos.x, pos.y + 1)
     if is_valid(b) and tiles[b.x][b.y] in HAS_BOTTOM_INPUT:
         yield b
Example #12
0
 def test_from_vertical_to_next_vertical_returns_first_and_second_point(
         self):
     result = make_tiles_path(
         start_tile=Point(0, 1),
         waypoints=[[0, 1], [0, 2]],
         tiles=[
             [
                 TileType.EMPTY, TileType.VERTICAL, TileType.VERTICAL,
                 TileType.EMPTY
             ],
         ],
         direction=Point(1, 0),
     )
     assert_that(list(result), equal_to([Point(0, 1), Point(0, 2)]))
Example #13
0
def make_unit_barrier(unit):
    if isinstance(unit, RectangularUnit):
        return Unit(
            barrier=Circle(position=Point(unit.x, unit.y),
                           radius=min(unit.width, unit.height) / 2),
            speed=Point(unit.speed_x, unit.speed_y),
        )
    elif isinstance(unit, CircularUnit):
        return Unit(
            barrier=Circle(position=Point(unit.x, unit.y), radius=unit.radius),
            speed=Point(unit.speed_x, unit.speed_y),
        )
    else:
        return None
Example #14
0
 def reset(self):
     self.__speed = PidController(2, 0, 0)
     self.__acceleration = PidController(2, 0, 0)
     self.__angle = PidController(1, 0, 0)
     self.__angular_speed_angle = PidController(4, 0, 0)
     self.__previous_speed = Point(0, 0)
     self.__previous_angular_speed_angle = 0
Example #15
0
 def make(self, context: Context):
     waypoints = self._waypoints(context.me.next_waypoint_index,
                                 context.world.waypoints,
                                 len(context.world.waypoints) *
                                 context.game.lap_count)
     first_unknown = next(
         (i for i, v in enumerate(waypoints)
          if context.world.tiles_x_y[v[0]][v[1]] == TileType.UNKNOWN),
         len(waypoints))
     if first_unknown + 1 < len(waypoints):
         waypoints = waypoints[:first_unknown + 1]
     path = list(make_tiles_path(
         start_tile=context.tile,
         waypoints=waypoints,
         tiles=context.world.tiles_x_y,
         direction=context.direction,
     ))
     if not path:
         path = [self.start_tile]
     elif self.start_tile != path[0]:
         path = [self.start_tile] + path
     path = [(x + Point(0.5, 0.5)) * context.game.track_tile_size
             for x in path]
     shift = (context.game.track_tile_size / 2 -
              context.game.track_tile_margin -
              max(context.me.width, context.me.height) / 2)
     path = list(adjust_path(path, shift, context.game.track_tile_size))
     path = list(shift_on_direct(path))
     return path
Example #16
0
 def test_start_direct_backward_with_initial_speed(self):
     controller = Controller(distance_to_wheels=1)
     result = controller(
         course=Point(-1, 0),
         angle=0,
         direct_speed=Point(-1, 0),
         angular_speed_angle=0,
         engine_power=0,
         wheel_turn=0,
         target_speed=Point(-1, 0),
         tick=0,
         backward=False,
     )
     assert_that(result.engine_power, equal_to(-1))
     assert_that(result.wheel_turn, equal_to(0))
     assert_that(result.brake, equal_to(False))
Example #17
0
 def test_start_right(self):
     controller = Controller(distance_to_wheels=1)
     result = controller(
         course=Point(0, 1),
         angle=0,
         direct_speed=Point(0, 0),
         angular_speed_angle=0,
         engine_power=0,
         wheel_turn=0,
         target_speed=Point(0, 1),
         tick=0,
         backward=False,
     )
     assert_that(result.engine_power, equal_to(1))
     assert_that(result.wheel_turn, greater_than(0))
     assert_that(result.brake, equal_to(False))
Example #18
0
 def test_start_direct_backward_with_initial_opposite_speed_turn_left(self):
     controller = Controller(distance_to_wheels=1)
     result = controller(
         course=Point(-1, -0.1),
         angle=0,
         direct_speed=Point(1, 0),
         angular_speed_angle=0,
         engine_power=0,
         wheel_turn=0,
         target_speed=Point(-1, -0.1),
         tick=0,
         backward=True,
     )
     assert_that(result.engine_power, equal_to(-1))
     assert_that(result.wheel_turn, less_than(0))
     assert_that(result.brake, equal_to(True))
Example #19
0
 def test_over_three_vertical_returns_three_points(self):
     result = make_tiles_path(
         start_tile=Point(0, 1),
         waypoints=[[0, 1], [0, 2], [0, 3]],
         tiles=[
             [
                 TileType.EMPTY, TileType.VERTICAL, TileType.VERTICAL,
                 TileType.VERTICAL, TileType.EMPTY
             ],
         ],
         direction=Point(1, 0),
     )
     assert_that(list(result),
                 equal_to([Point(0, 1),
                           Point(0, 2),
                           Point(0, 3)]))
Example #20
0
 def use(car: Car):
     car_speed = Point(car.speed_x, car.speed_y)
     return (car.id != context.me.id and
             (context.speed.norm() > CAR_SPEED_FACTOR * car_speed.norm() or
              context.speed.norm() > 0 and
              (car_speed.norm() > 0 and
               abs(context.speed.cos(car_speed)) < cos(1) or
               car_speed.norm() == 0)))
Example #21
0
def shift_on_direct_x(path):
    last = next((i for i, p in islice(enumerate(path), 1, len(path))
                 if p.x != path[i - 1].x),
                len(path) - 1)
    x = path[last].x
    if x != path[0].x:
        return last, chain([path[0]],
                           (Point(x, p.y) for p in islice(path, 1, last)))
    return last, (p for p in path)
Example #22
0
def shift_on_direct_y(path):
    last = next((i for i, p in islice(enumerate(path), 1, len(path))
                 if p.y != path[i - 1].y),
                len(path) - 1)
    y = path[last].y
    if y != path[0].y:
        return last, chain([path[0]],
                           (Point(p.x, y) for p in islice(path, 1, last)))
    return last, (p for p in path)
Example #23
0
def get_best_bonuses_point(position, bonuses, tile_size, priority_conf):
    def priority(bonus):
        type_priority = get_bonus_type_priority(bonus.type, priority_conf)
        penalty = get_bonus_penalty(bonus, position, tile_size)
        return (type_priority * BONUS_TYPE_PRIORITY_FACTOR -
                penalty * BONUS_PENALTY_FACTOR)

    best = max(bonuses, key=priority)
    return Point(best.x, best.y) if priority(best) > 0 else position
Example #24
0
 def test_for_two_double_connected_nodes_returns_with_three_nodes(self):
     result = split_arcs(
         graph={
             0: Node(position=Point(0, 0), arcs=[Arc(dst=1, weight=1)]),
             1: Node(position=Point(0, 1), arcs=[Arc(dst=0, weight=1)]),
         })
     assert_that(
         result,
         equal_to({
             0:
             Node(position=Point(0, 0), arcs=[Arc(dst=2, weight=0.5)]),
             1:
             Node(position=Point(0, 1), arcs=[Arc(dst=2, weight=0.5)]),
             2:
             Node(position=Point(0, 0.5),
                  arcs=[Arc(dst=0, weight=0.5),
                        Arc(dst=1, weight=0.5)]),
         }))
Example #25
0
 def test_for_quadrant_from_left_top_to_right_top_with_direction_to_bottom_returns_path_direct_to_right_top(
         self):
     result = shortest_path_with_direction(graph={
         0:
         Node(position=Point(0, 0),
              arcs=[Arc(dst=1, weight=1),
                    Arc(dst=2, weight=1)]),
         1:
         Node(position=Point(0, 1), arcs=[Arc(dst=3, weight=1)]),
         2:
         Node(position=Point(1, 0), arcs=[]),
         3:
         Node(position=Point(1, 1), arcs=[Arc(dst=2, weight=1)]),
     },
                                           src=0,
                                           dst=2,
                                           initial_direction=Point(0, 1),
                                           forbidden={})
     assert_that(list(result), equal_to([2]))
Example #26
0
 def generate():
     for x, column in enumerate(tiles):
         for y, tile in enumerate(column):
             position = Point(x, y)
             yield get_point_index(position, row_size), make_tile_barriers(
                 tile_type=tile,
                 position=position,
                 margin=margin,
                 size=size,
             )
Example #27
0
 def clip_line(self, line: Line):
     k1 = self.point_code(line.begin)
     k2 = self.point_code(line.end)
     x1 = line.begin.x
     y1 = line.begin.y
     x2 = line.end.x
     y2 = line.end.y
     left = self.left_top.x
     top = self.left_top.y
     right = self.right_bottom.x
     bottom = self.right_bottom.y
     accept = False
     while True:
         if (k1 | k2) == 0:
             accept = True
             break
         if (k1 & k2) != 0:
             break
         opt = k1 or k2
         if opt & Rectangle.TOP:
             x = x1 + (x2 - x1) * (bottom - y1) / (y2 - y1)
             y = bottom
         elif opt & Rectangle.BOTTOM:
             x = x1 + (x2 - x1) * (top - y1) / (y2 - y1)
             y = top
         if opt & Rectangle.RIGHT:
             y = y1 + (y2 - y1) * (right - x1) / (x2 - x1)
             x = right
         elif opt & Rectangle.LEFT:
             y = y1 + (y2 - y1) * (left - x1) / (x2 - x1)
             x = left
         if opt == k1:
             x1, y1 = x, y
             k1 = self.point_code(Point(x1, y1))
         elif opt == k2:
             x2, y2 = x, y
             k2 = self.point_code(Point(x2, y2))
     if accept:
         return Line(Point(x1, y1), Point(x2, y2))
     else:
         return line
Example #28
0
def get_target_speed(course: Point, path, angle_to_direct_proportion,
                     max_speed, min_power):
    direct_factor = 1 / (angle_to_direct_proportion + 1)
    angle_factor = direct_factor * angle_to_direct_proportion
    if len(path) > 2:
        angle_factor *= max(1e-8 - 1,
                            min(1 - 1e-8, cos_product(path, min_power)))
    if course.norm() > 0:
        return course * max_speed / course.norm() * (direct_factor +
                                                     angle_factor)
    else:
        return Point(0, 0)
Example #29
0
def make_tiles_path(start_tile, waypoints, tiles, direction):
    graph = make_graph(tiles)
    graph = split_arcs(graph)
    graph = add_diagonal_arcs(graph)
    row_size = len(tiles[0])
    start = get_point_index(start_tile, row_size)
    waypoints = [get_index(x[0], x[1], row_size) for x in waypoints]
    if start != waypoints[0] and start in graph:
        waypoints = [start] + waypoints
    path = multi_path(graph, waypoints, direction)
    path = list(graph[x].position + Point(0.5, 0.5) for x in path)
    path = remove_split(path)
    return path
Example #30
0
 def generate():
     for car in context.opponents_cars:
         car_position = Point(car.x, car.y)
         car_speed = Point(car.speed_x, car.speed_y)
         car_barriers = list(make_units_barriers([car]))
         distance = (context.position - car_position).norm()
         if car_speed.norm() < 1:
             yield (not has_intersection_with_tiles(distance) and
                    make_has_intersection_with_lane(
                        position=context.position,
                        course=tire_speed * 50,
                        barriers=car_barriers,
                        width=context.game.tire_radius,
                    )(0))
         else:
             car_line = Line(car_position, car_position + car_speed)
             tire_line = Line(context.position,
                              context.position + tire_speed)
             intersection = tire_line.intersection(car_line)
             if intersection is None:
                 continue
             if not is_in_world(intersection, world_tiles, tile_size):
                 continue
             if is_in_empty_tile(intersection, world_tiles, tile_size):
                 continue
             car_dir = intersection - car_position
             if car_dir.norm() > 0 and car_dir.cos(car_speed) < 0:
                 continue
             if car_dir.norm() > context.game.tire_initial_speed * 50:
                 continue
             tire_dir = intersection - context.position
             if tire_dir.norm() > 0 and tire_dir.cos(tire_speed) < 0:
                 continue
             if has_intersection_with_tiles(tire_dir.norm()):
                 continue
             car_time = car_dir.norm() / car_speed.norm()
             tire_time = tire_dir.norm() / tire_speed.norm()
             if abs(car_time - tire_time) <= TIRE_INTERVAL:
                 yield True