Esempio n. 1
0
class Strike(Maneuver):

    allow_backwards = False
    update_interval = 0.3
    stop_updating = 0.8
    max_additional_time = 1

    def __init__(self, car: Car, info: GameInfo, target: vec3 = None):
        super().__init__(car)

        self.info = info
        self.target = target

        self.arrive = Arrive(car)
        self.intercept: Intercept = None

        self._has_drawn_prediction = False
        self._last_update_time = car.time
        self._should_strike_backwards = False
        self._initial_time = 999999
        self.update()
        self._initial_time = self.intercept.time

    def intercept_predicate(self, car: Car, ball: Ball):
        return True

    def configure(self, intercept: Intercept):
        self.arrive.target = intercept.ground_pos
        self.arrive.time = intercept.time
        self.arrive.drive.backwards = self._should_strike_backwards

    def update(self):
        self.intercept = Intercept(self.car, self.info.ball_predictions,
                                   self.intercept_predicate)
        if self.allow_backwards:
            backwards_intercept = Intercept(self.car,
                                            self.info.ball_predictions,
                                            self.intercept_predicate,
                                            backwards=True)
            if backwards_intercept.time + 0.1 < self.intercept.time:
                self.intercept = backwards_intercept
                self._should_strike_backwards = True
            else:
                self._should_strike_backwards = False

        self.configure(self.intercept)
        self._last_update_time = self.car.time
        if not self.intercept.is_viable or self.intercept.time > self._initial_time + self.max_additional_time:
            self.finished = True

    def update_requirement(self):
        return self.intercept.time > self.car.time + self.stop_updating

    def step(self, dt):
        self.arrive.step(dt)
        self.controls = self.arrive.controls
        self.finished = self.arrive.finished

        if self.arrive.drive.target_speed < 300:
            self.controls.throttle = 0

        if self.car.time > self._last_update_time + self.update_interval:

            if self.update_requirement():

                prediction_steps = int(
                    (self.intercept.time - self.car.time + 1) * 60)
                self.info.predict_ball(prediction_steps, 1 / 60)
                self._has_drawn_prediction = False
                self.update()

    def render(self, draw: DrawingTool):
        self.arrive.render(draw)
        draw.color(draw.lime)
        draw.circle(self.intercept.ground_pos, 93)
        draw.point(self.intercept.ball.pos)

        if self.target is not None:
            draw.color(draw.yellow)
            draw.point(self.target)

        if not self._has_drawn_prediction:
            self._has_drawn_prediction = True
            draw.ball_prediction(self.info, self.intercept.time)

    @staticmethod
    def pick_easiest_target(car: Car, ball: Ball, targets) -> vec3:
        best_dot = -99
        best_target = None
        for target in targets:
            this_dot = dot(ground_direction(car, ball),
                           ground_direction(ball, target))
            if this_dot > best_dot:
                best_dot = this_dot
                best_target = target
        return best_target

    @staticmethod
    def pick_easiest_direction(car: Car, ball: Ball, directions) -> vec3:
        best_dot = -99
        best_direction = None
        for d in directions:
            this_dot = dot(ground_direction(car, ball), d)
            if this_dot > best_dot:
                best_dot = this_dot
                best_direction = d
        return best_direction
Esempio n. 2
0
class Strike(Maneuver):
    allow_backwards = False
    update_interval = 0.2
    stop_updating = 0.3
    max_additional_time = 0.5

    def __init__(self, car: Car, info: GameInfo, target: vec3 = None):
        super().__init__(car)

        self.info: GameInfo = info
        self.target: Optional[vec3] = target

        self.arrive = Arrive(car)
        self.intercept: Intercept = None

        self._has_drawn_prediction = False
        self._last_update_time = car.time
        self._should_strike_backwards = False
        self._initial_time = math.inf
        self.update_intercept()
        self._initial_time = self.intercept.time

    def intercept_predicate(self, car: Car, ball: Ball):
        return True

    def configure(self, intercept: Intercept):
        self.arrive.target = intercept.ground_pos
        self.arrive.arrival_time = intercept.time
        self.arrive.backwards = self._should_strike_backwards

    def update_intercept(self):
        self.intercept = Intercept(self.car, self.info.ball_predictions,
                                   self.intercept_predicate)

        if self.allow_backwards:
            backwards_intercept = Intercept(self.car,
                                            self.info.ball_predictions,
                                            self.intercept_predicate,
                                            backwards=True)
            if backwards_intercept.time + 0.1 < self.intercept.time:
                self.intercept = backwards_intercept
                self._should_strike_backwards = True
            else:
                self._should_strike_backwards = False

        self.configure(self.intercept)
        self._last_update_time = self.car.time
        if not self.intercept.is_viable or self.intercept.time > self._initial_time + self.max_additional_time:
            self.finished = True

    def interruptible(self) -> bool:
        return self.arrive.interruptible()

    def step(self, dt):
        if (self._last_update_time + self.update_interval < self.car.time <
                self.intercept.time - self.stop_updating and self.car.on_ground
                and not self.controls.jump):
            self.info.predict_ball(time_limit=self.intercept.time -
                                   self.car.time + 1)
            self._has_drawn_prediction = False
            self.update_intercept()

        self.arrive.step(dt)
        self.controls = self.arrive.controls

        if self.arrive.drive.target_speed < 300:
            self.controls.throttle = 0

        if self.arrive.finished:
            self.finished = True

    def render(self, draw: DrawingTool):
        self.arrive.render(draw)
        draw.color(draw.lime)
        draw.circle(self.intercept.ground_pos, Ball.radius)
        draw.point(self.intercept.ball.position)

        if self.target:
            strike_direction = ground_direction(self.intercept.ground_pos,
                                                self.target)
            draw.color(draw.cyan)
            draw.triangle(self.intercept.ground_pos + strike_direction * 150,
                          strike_direction,
                          length=100)

        if not self._has_drawn_prediction:
            self._has_drawn_prediction = True
            draw.ball_prediction(self.info.ball_predictions,
                                 self.intercept.time)

    @staticmethod
    def pick_easiest_target(car: Car, ball: Ball, targets: List[vec3]) -> vec3:
        return max(targets,
                   key=lambda target: dot(ground_direction(car, ball),
                                          ground_direction(ball, target)))