Ejemplo n.º 1
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)))
Ejemplo n.º 2
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)
Ejemplo n.º 3
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
Ejemplo n.º 4
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]))
         if car_speed.norm() < 1:
             for washer in washers:
                 yield make_has_intersection_with_lane(
                     position=washer.position,
                     course=washer.speed * 150,
                     barriers=car_barriers,
                     width=context.game.washer_radius,
                 )(0)
         else:
             car_line = Line(car_position, car_position + car_speed)
             for washer in washers:
                 washer_line = Line(washer.position,
                                    washer.position + washer.speed)
                 intersection = washer_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() > washer_speed * 150:
                     continue
                 washer_dir = intersection - washer.position
                 if (washer_dir.norm() > 0 and
                         washer_dir.cos(washer.speed) < 0):
                     continue
                 car_time = car_dir.norm() / car_speed.norm()
                 washer_time = washer_dir.norm() / washer.speed.norm()
                 if abs(car_time - washer_time) <= WASHER_INTERVAL:
                     yield True
Ejemplo n.º 5
0
    def __call__(self, course, angle, direct_speed: Point, angular_speed_angle,
                 engine_power, wheel_turn, target_speed: Point, tick,
                 backward):
        direction = Point(1, 0).rotate(angle)
        radius = -(direction * self.distance_to_wheels).rotate(pi / 2)
        angular_speed = radius.left_orthogonal() * angular_speed_angle
        speed = direct_speed + angular_speed
        target_acceleration = self.__speed(target_speed - speed)
        tangential_acceleration = speed - self.__previous_speed
        centripetal_acceleration = (-radius *
                                    self.__previous_angular_speed_angle**2)
        acceleration = tangential_acceleration + centripetal_acceleration
        acceleration_derivative = self.__acceleration(target_acceleration -
                                                      acceleration)
        cos_val = acceleration_derivative.cos(direction)
        if -sqrt(2) / 2 < cos_val < sqrt(2) / 2:
            cos_val = sqrt(2) / 2 if cos_val >= 0 else -sqrt(2) / 2
        target_engine_power = acceleration_derivative.norm() * cos_val
        target_engine_power = max(-1, min(1, target_engine_power))
        if (speed.norm() > 0 and target_speed.norm() > 0
                and speed.cos(target_speed) > -cos(1) or speed.norm() == 0):
            if speed.norm() > target_speed.norm():
                target_engine_power = (1 if direction.cos(speed) > -cos(1) else
                                       -1)
                brake = True
            else:
                target_engine_power = (
                    1 if direction.cos(target_speed) > -cos(1) else -1)
                brake = False
        else:
            brake = True
        target_angle = course.absolute_rotation()
        direction_angle_error = normalize_angle(target_angle - angle)
        direction_angle_error = relative_angle_error(direction_angle_error)
        speed_angle_error = normalize_angle(speed.absolute_rotation() - angle)
        speed_angle_error = relative_angle_error(speed_angle_error)
        if (backward and target_speed.norm() > 0
                and direction.cos(target_speed) < -cos(1)):
            direction_angle_error = -direction_angle_error
            speed_angle_error = -speed_angle_error
        angle_error = max(direction_angle_error, speed_angle_error, key=abs)
        angle_derivative = self.__angle(angle_error)
        target_wheel_turn = self.__angular_speed_angle(angle_derivative -
                                                       angular_speed_angle)
        target_wheel_turn = max(-1, min(1, target_wheel_turn))
        self.__previous_speed = speed
        self.__previous_angular_speed_angle = angular_speed_angle
        if 'CONTROL_PLOTS' in environ and environ['CONTROL_PLOTS'] == '1':

            def append_point(name, current, target):
                # append_value(name + ' x', current.x, target.x)
                # append_value(name + ' y', current.y, target.y)
                append_value(name + ' norm', current.norm(), target.norm())

            def append_value(name, current, target):
                history = self.history[name]
                history.current.append(current)
                history.target.append(target)

            append_point('speed', speed, target_speed)
            append_point('acceleration', acceleration, target_acceleration)
            append_value('engine_power', engine_power, target_engine_power)
            append_value('angle', angle, target_angle)
            append_value('wheel_turn', wheel_turn, target_wheel_turn)

            if tick % 50 == 0:

                def draw(name):
                    plot = self.plots[name]
                    history = self.history[name]
                    plot.clear()
                    plot.lines(
                        range(tick + 1 - len(history.current), tick + 1),
                        history.current)
                    plot.lines(range(tick + 1 - len(history.target), tick + 1),
                               history.target,
                               linestyle='--')
                    plot.draw()

                def draw_point(name):
                    # draw(name + ' x')
                    # draw(name + ' y')
                    draw(name + ' norm')

                draw_point('speed')
                draw_point('acceleration')
                draw('engine_power')
                draw('angle')
                draw('wheel_turn')
        return Control(target_engine_power, target_wheel_turn, brake)
Ejemplo n.º 6
0
 def update(self, speed: Point, durability):
     self.__history.append(self.Conf(speed.norm(), durability))