コード例 #1
0
    def __init__(self, car: Car, info: GameInfo, face_target: vec3,
                 distance_from_target: float):
        super().__init__(car)

        self.info = info
        self.face_target = face_target

        dist = min(distance_from_target,
                   ground_distance(face_target, self.info.my_goal.center) - 50)
        target_pos = ground(face_target) + ground_direction(
            face_target, self.info.my_goal.center) * dist

        near_goal = ground_distance(car, info.my_goal.center) < 3000
        side_shift = 400 if near_goal else 2000
        points = [
            target_pos + vec3(side_shift, 0, 0),
            target_pos - vec3(side_shift, 0, 0)
        ]
        target_pos = nearest_point(face_target,
                                   points) if near_goal else furthest_point(
                                       face_target, points)

        self.target = Arena.clamp(target_pos, 500)

        self.travel = Travel(car, self.target)
        self.travel.finish_distance = 800 if near_goal else 1500
        self.drive = Drive(car)

        self.start_time = car.time
        self.wait = Stop(car)
コード例 #2
0
    def __init__(self, car: Car, ball: Ball, target: vec3):
        super().__init__(car)

        self.ball = ball
        self.target = ground(target)
        self.drive = Drive(car)
        self._shift_direction = vec3(0, 0, 0)
コード例 #3
0
class Arrive(Maneuver):
    def __init__(self,
                 car: Car,
                 target=vec3(0, 0, 0),
                 time=0,
                 target_direction: vec3 = None):
        super().__init__(car)

        self.target_direction = target_direction
        self.target = target
        self.time = time
        self.drive = Drive(car, target)
        self.travel = Travel(car)
        self.lerp_t = 0.6

    def step(self, dt):
        target = self.target
        car = self.car

        if self.target_direction is not None:
            car_vel = norm(car.vel)
            target_direction = normalize(self.target_direction)
            shift = clamp(
                distance(car.pos, target) * self.lerp_t, 0, car_vel * 1.5)
            if shift < turn_radius(clamp(car_vel, 1400, 2000) * 1.1):
                shift = 0
            translated_target = target - target_direction * shift

            translated_time = self.time - distance(
                translated_target, target) / max(1, clamp(car_vel, 500, 2300))
        else:
            translated_target = target
            translated_time = self.time

        self.drive.target_pos = translated_target
        dist_to_target = distance(car.pos, translated_target)
        target_speed = clamp(
            dist_to_target / max(0.001, translated_time - car.time), 0, 2300)

        self.drive.target_speed = target_speed

        if car.boost < 1 and dist_to_target > 3000:
            self.travel.target = target
            self.travel.step(dt)
            self.controls = self.travel.controls
        else:
            self.drive.step(dt)
            self.controls = self.drive.controls

        self.finished = self.car.time >= self.time
        return self.finished

    def render(self, draw: DrawingTool):
        self.drive.render(draw)

        if self.target_direction is not None:
            draw.color(draw.lime)
            draw.triangle(self.target - self.target_direction * 250,
                          self.target_direction)
コード例 #4
0
    def __init__(self, car: Car, info: GameInfo, target=None):
        self.drive = Drive(car)
        self.reorient = Reorient(car)

        self.jumping = False
        self.time_for_jump = float("inf")
        self.timer = 0.0

        super().__init__(car, info, target)
コード例 #5
0
    def __init__(self, car: Car, info: GameInfo, target=None):
        self.drive = Drive(car)
        self.aerial_turn = AerialTurn(car)

        self.jumping = False
        self.time_for_jump = float("inf")
        self.timer = 0.0

        super().__init__(car, info, target)
コード例 #6
0
class Carry(Maneuver):
    """
    Carry the ball on roof towards a target.
    Finishes if the ball hits the floor.
    """
    def __init__(self, car: Car, ball: Ball, target: vec3):
        super().__init__(car)

        self.ball = ball
        self.target = ground(target)
        self.drive = Drive(car)
        self._shift_direction = vec3(0, 0, 0)

    def step(self, dt):
        ball = Ball(self.ball)
        car = self.car

        # simulate ball until it gets near the floor
        while (ball.position[2] > 120
               or ball.velocity[2] > 0) and ball.time < car.time + 10:
            ball.step(1 / 60)

        ball_local = local(car, ground(ball.position))
        target = local(car, self.target)

        shift = ground(direction(ball_local, target))
        shift[1] *= 1.8
        shift = normalize(shift)

        max_turn = clamp(norm(car.velocity) / 800, 0, 1)
        max_shift = normalize(vec3(1 - max_turn, max_turn * sign(shift[1]), 0))

        if abs(shift[1]) > abs(max_shift[1]) or shift[0] < 0:
            shift = max_shift
        shift *= clamp(car.boost, 30, 50)

        shift[1] *= clamp(norm(car.velocity) / 1000, 1, 2)

        self._shift_direction = normalize(world(car, shift) - car.position)

        target = world(car, ball_local - shift)
        speed = distance(car.position, target) / max(0.001,
                                                     ball.time - car.time)

        self.drive.target_speed = speed
        self.drive.target_pos = target

        self.drive.step(dt)
        self.controls = self.drive.controls
        self.finished = self.ball.position[2] < 100 or ground_distance(
            self.ball, self.car) > 2000

    def render(self, draw: DrawingTool):
        draw.color(draw.pink)
        draw.triangle(self.car.position + self._shift_direction * 50,
                      self._shift_direction)
コード例 #7
0
ファイル: arrive.py プロジェクト: robbai/RLBotPack
    def __init__(self, car: Car):
        super().__init__(car)

        self.target_direction: vec3 = None
        self.target: vec3 = None
        self.time: float = 0
        self.drive = Drive(car)
        self.travel = Travel(car)
        self.lerp_t = 0.6
        self.allow_dodges_and_wavedashes: bool = True
        self.additional_shift = 0
コード例 #8
0
ファイル: diagonal.py プロジェクト: robbai/RLBotPack
    def __init__(self, car: Car, info: GameInfo):
        super().__init__(car)
        self.info = info

        self.drive = Drive(car)
        self.drive.target_speed = 2300

        self.dodge = Dodge(car)
        self.dodge.duration = 0.1
        self.dodge.direction = normalize(info.their_goal)

        self.phase = 0
コード例 #9
0
class ShadowDefense(Maneuver):

    DURATION = 0.5

    def __init__(self, car: Car, info: GameInfo, face_target: vec3, distance_from_target: float):
        super().__init__(car)

        self.info = info
        self.face_target = face_target

        dist = min(distance_from_target, ground_distance(face_target, self.info.my_goal.center) - 50)
        target_pos = ground(face_target) + ground_direction(face_target, self.info.my_goal.center) * dist

        near_goal = ground_distance(car, info.my_goal.center) < 3000
        side_shift = 400 if near_goal else 2000
        points = [target_pos + vec3(side_shift, 0, 0), target_pos - vec3(side_shift, 0, 0)]
        target_pos = nearest_point(face_target, points) if near_goal else farthest_point(face_target, points)
        target_pos = Arena.clamp(target_pos, 500)

        self.travel = Travel(car, target_pos)
        self.travel.finish_distance = 800 if near_goal else 1500
        self.drive = Drive(car)
        self.drive.target_speed = 1000
        self.stop = Stop(car)

        self.start_time = car.time

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

    def step(self, dt):
        self.travel.step(dt)
        self.controls = self.travel.controls

        if ground_distance(self.car, self.travel.target) < 3000:
            self.controls.boost = False

        if self.travel.finished:
            if angle_to(self.car, self.face_target) > 0.3:
                self.drive.target_pos = self.face_target
                self.drive.step(dt)
                self.controls = self.drive.controls
                self.controls.handbrake = False
            else:
                self.stop.step(dt)
                self.controls = self.stop.controls

        self.controls.boost = False

        self.finished = self.travel.driving and self.car.time > self.start_time + self.DURATION

    def render(self, draw: DrawingTool):
        self.travel.render(draw)
コード例 #10
0
class ShadowDefense(Maneuver):

    def __init__(self, car: Car, info: GameInfo, target: vec3, distance_from_target: float):
        super().__init__(car)

        self.info = info
        self.target = target

        ball = info.ball
        dist = min(distance_from_target, ground_distance(target, self.info.my_goal.center) - 50)
        target_pos = ground(target) + ground_direction(target, self.info.my_goal.center) * dist

        side_shift = distance_from_target / 4 if ground_distance(car, info.my_goal.center) > 2500 else 400
        points = [target_pos + vec3(side_shift, 0, 0), target_pos - vec3(side_shift, 0, 0)]
        target_pos = nearest_point(car.pos, points)

        self.target = Arena.clamp(target_pos, 700)

        self.travel = Travel(car, self.target)
        self.drive = Drive(car)

        self.start_time = car.time
        self.wait = Stop(car)

    def step(self, dt):
        ball = self.info.ball

        if (
            distance(self.car, ball) < 1000
            and align(self.car.pos, ball, self.info.my_goal.center) > 0.2
        ):
            shift = normalize(cross(direction(ball, self.car), vec3(0, 0, 1))) * 1000
            self.travel.target = nearest_point(self.car.pos, [ball.pos + shift, ball.pos - shift])
        else:
            self.travel.target = self.target

        self.travel.step(dt)
        self.controls = self.travel.controls
        if self.travel.finished:
            if angle_to(self.car, self.target) > 0.2 and norm(self.car.vel) < 600:
                self.drive.target_pos = self.target
                self.drive.step(dt)
                self.drive.target_speed = 500
                self.drive.controls.handbrake = False
                self.controls = self.drive.controls
            else:
                self.wait.step(dt)
                self.controls = self.wait.controls
        self.finished = self.travel._driving and self.car.time > self.start_time + 0.5

    def render(self, draw: DrawingTool):
        self.travel.render(draw)
コード例 #11
0
    def __init__(self,
                 car: Car,
                 target=vec3(0, 0, 0),
                 time=0,
                 target_direction: vec3 = None):
        super().__init__(car)

        self.target_direction = target_direction
        self.target = target
        self.time = time
        self.drive = Drive(car, target)
        self.travel = Travel(car)
        self.lerp_t = 0.6
コード例 #12
0
ファイル: arrive.py プロジェクト: ViliamVadocz/RLBotPack
    def __init__(self, car: Car):
        super().__init__(car)
        self.drive = Drive(car)
        self.travel = Travel(car)
        self.action = self.drive

        self.target_direction: Optional[None] = None
        self.target: vec3 = None
        self.arrival_time: float = 0
        self.backwards: bool = False

        self.lerp_t = 0.57
        self.allow_dodges_and_wavedashes: bool = True
        self.additional_shift = 0
コード例 #13
0
ファイル: carry.py プロジェクト: meckern/RLBotPack
class Carry(Maneuver):
    def __init__(self, car: Car, ball: Ball, target: vec3):
        super().__init__(car)

        self.ball = ball
        self.target = ground(target)
        self.drive = Drive(car)
        self._shift_direction = vec3(0, 0, 0)

    def step(self, dt):
        ball = Ball(self.ball)
        car = self.car

        while (ball.pos[2] > 120
               or ball.vel[2] > 0) and ball.t < car.time + 10:
            ball.step(1 / 60)

        ball_local = local(car, ground(ball.pos))
        target = local(car, self.target)

        shift = ground(direction(ball_local, target))
        shift[1] *= 1.8
        shift = normalize(shift)

        max_turn = clamp(norm(car.vel) / 800, 0, 1)
        max_shift = normalize(vec3(1 - max_turn, max_turn * sign(shift[1]), 0))

        if abs(shift[1]) > abs(max_shift[1]) or shift[0] < 0:
            shift = max_shift
        shift *= 45

        shift[1] *= clamp(norm(car.vel) / 1000, 1, 2)

        self._shift_direction = normalize(world(car, shift) - car.pos)

        target = world(car, ball_local - shift)
        speed = distance(car.pos, target) / max(0.001, ball.t - car.time)

        self.drive.target_speed = speed
        self.drive.target_pos = target

        self.drive.step(dt)
        self.controls = self.drive.controls
        self.finished = self.ball.pos[2] < 100 or ground_distance(
            self.ball, self.car) > 1500

    def render(self, draw: DrawingTool):
        draw.color(draw.pink)
        draw.triangle(self.car.pos + self._shift_direction * 50,
                      self._shift_direction)
コード例 #14
0
ファイル: diagonal.py プロジェクト: robbai/RLBotPack
class DiagonalKickoff(Maneuver):
    '''Dodge forward once to get there faster.'''
    def __init__(self, car: Car, info: GameInfo):
        super().__init__(car)
        self.info = info

        self.drive = Drive(car)
        self.drive.target_speed = 2300

        self.dodge = Dodge(car)
        self.dodge.duration = 0.1
        self.dodge.direction = normalize(info.their_goal)

        self.phase = 0

    def step(self, dt):
        if self.phase == 0:
            self.controls.throttle = 1
            self.controls.boost = 1
            if ground_distance(self.car, self.info.ball) < 2950:
                print("entering phase 1")
                self.phase = 1

        if self.phase == 1:
            self.dodge.step(dt)
            self.controls = self.dodge.controls
            if self.dodge.finished and self.car.on_ground:
                print("entering phase 2")
                self.phase = 2
                self.dodge = Dodge(self.car)
                self.dodge.duration = 0.18
                self.dodge.direction = direction(self.car.position,
                                                 self.info.ball.position)

        if self.phase == 2:
            self.drive.step(dt)
            self.controls = self.drive.controls
            if distance(self.car, self.info.ball) < 850:
                print("entering phase 3")
                self.phase = 3

        if self.phase == 3:
            self.dodge.step(dt)
            self.controls = self.dodge.controls

        self.finished = self.info.ball.position[0] != 0 and self.dodge.finished

    def render(self, draw: DrawingTool):
        pass
コード例 #15
0
ファイル: travel.py プロジェクト: meckern/RLBotPack
    def __init__(self,
                 car: Car,
                 target: vec3 = vec3(0, 0, 0),
                 waste_boost=False):
        super().__init__(car)

        self.target = Arena.clamp(ground(target), 100)
        self.waste_boost = waste_boost
        self.finish_distance = 500

        self._time_on_ground = 0
        self._driving = True

        self.dodge_duration = 1.6
        self.halflip_duration = 2
        self.wavedash_duration = 1.3

        # decide whether to start driving backwards and halfflip later
        forward_est = estimate_time(car, target, estimate_max_car_speed(car))
        backwards_est = estimate_time(car, target, 1400, -1) + 0.5
        backwards = backwards_est < forward_est \
                    and (distance(car, target) > 3000 or distance(car, target) < 300) \
                    and car.pos[2] < 200

        self.drive = Drive(car, self.target, 2300, backwards)
        self.action = self.drive
コード例 #16
0
ファイル: kickoff.py プロジェクト: Supersilver10/RLBotPack
    def __init__(self, car: Car, info: GameInfo):
        super().__init__(car)
        self.info: GameInfo = info

        self.drive = Drive(car, target_speed=2300)

        self.action: Maneuver = self.drive
        self.phase = 1
コード例 #17
0
 def __init__(self, car: Car, pad: Pad):
     super().__init__(car)
     self.drive = Drive(car,
                        target_pos=pad.position,
                        target_speed=2300,
                        backwards=True)
     self.phase = 1
     self.action = self.drive
コード例 #18
0
    def __init__(self, car: Car, info: GameInfo):
        super().__init__(car)
        self.info = info

        target_pos = vec3(0, sgn(info.my_goal.center[1]) * 100, 0)
        self.drive = Drive(car, target_pos, 2300)

        self.action: Maneuver = self.drive
        self.phase = 1
コード例 #19
0
class DriveBackwardsToGoal(Maneuver):
    """
    Simply drive backwards until we are in the center of our goal.
    This is useful if we are the nearest car to our goal on kickoff, in case we lose a kickoff horribly,
    we are in a good position to save.
    Note: This isn't an actual kickoff maneuver (it doesn't go for the ball), so it doesn't inherit from Kickoff.
    """
    def __init__(self, car: Car, info: GameInfo):
        super().__init__(car)
        self.drive = Drive(car)
        self.drive.backwards = True
        self.drive.target_pos = info.my_goal.center
        self.drive.target_speed = 1300

    def step(self, dt: float):
        self.drive.step(dt)
        self.controls = self.drive.controls

        if ground_distance(self.car, self.drive.target_pos) < 100:
            self.finished = True
コード例 #20
0
    def step(self, dt):
        target = self.target
        car = self.car

        if self.target_direction is not None:
            car_speed = norm(car.velocity)
            target_direction = normalize(self.target_direction)

            # in order to arrive in a direction, we need to shift the target in the opposite direction
            # the magnitude of the shift is based on how far are we from the target
            shift = clamp(
                ground_distance(car.position, target) * self.lerp_t, 0,
                car_speed * 1.5)

            # if we're too close to the target, aim for the actual target so we don't miss it
            if shift - self.additional_shift < Drive.turn_radius(
                    clamp(car_speed, 1400, 2000) * 1.1):
                shift = 0
            else:
                shift += self.additional_shift

            shifted_target = target - target_direction * shift

            time_shift = ground_distance(shifted_target, target) * 0.7 / clamp(
                car_speed, 500, 2300)
            shifted_arrival_time = self.arrival_time - time_shift

        else:
            shifted_target = target
            shifted_arrival_time = self.arrival_time

        self.drive.target_pos = shifted_target
        self.travel.target = shifted_target

        dist_to_target = ground_distance(car.position, shifted_target)
        time_left = nonzero(shifted_arrival_time - car.time)
        target_speed = clamp(dist_to_target / time_left, 0, 2300)
        self.drive.target_speed = target_speed
        self.drive.backwards = self.backwards

        # dodges and wavedashes can mess up correctly arriving, so we use them only if we really need them
        if ((self.allow_dodges_and_wavedashes
             and norm(car.velocity) < target_speed - 600 and car.boost < 20
             and not self.backwards)
                or not self.travel.driving  # a dodge/wavedash is in progress
            ):
            self.action = self.travel
        else:
            self.action = self.drive

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

        self.finished = self.car.time >= self.arrival_time
コード例 #21
0
    def __init__(self, car: Car, info: GameInfo, target: vec3, distance_from_target: float):
        super().__init__(car)

        self.info = info
        self.target = target

        ball = info.ball
        dist = min(distance_from_target, ground_distance(target, self.info.my_goal.center) - 50)
        target_pos = ground(target) + ground_direction(target, self.info.my_goal.center) * dist

        side_shift = distance_from_target / 4 if ground_distance(car, info.my_goal.center) > 2500 else 400
        points = [target_pos + vec3(side_shift, 0, 0), target_pos - vec3(side_shift, 0, 0)]
        target_pos = nearest_point(car.pos, points)

        self.target = Arena.clamp(target_pos, 700)

        self.travel = Travel(car, self.target)
        self.drive = Drive(car)

        self.start_time = car.time
        self.wait = Stop(car)
コード例 #22
0
    def __init__(self,
                 car: Car,
                 info: GameInfo,
                 face_target: vec3,
                 distance_from_target: float,
                 force_nearest=False):
        super().__init__(car)

        self.info = info
        self.face_target = face_target

        dist = min(distance_from_target,
                   ground_distance(face_target, self.info.my_goal.center) - 50)
        target_pos = ground(face_target) + ground_direction(
            face_target, self.info.my_goal.center) * dist

        near_goal = abs(car.position[1] - info.my_goal.center[1]) < 3000
        side_shift = 400 if near_goal else 1800
        points = target_pos + vec3(side_shift, 0, 0), target_pos - vec3(
            side_shift, 0, 0)
        if abs(self.car.position.x) > 3000:
            force_nearest = True
        target_pos = nearest_point(
            face_target,
            points) if near_goal or force_nearest else farthest_point(
                face_target, points)
        if abs(face_target[0]) < 1000 or ground_distance(car,
                                                         face_target) < 1000:
            target_pos = nearest_point(car.position, points)
        target_pos = Arena.clamp(target_pos, 500)

        self.travel = Travel(car, target_pos)
        self.travel.finish_distance = 800 if near_goal else 1500
        self.drive = Drive(car)
        self.stop = Stop(car)

        self.start_time = car.time

        self.pad = None
コード例 #23
0
ファイル: travel.py プロジェクト: Supersilver10/RLBotPack
    def __init__(self, car: Car, target: vec3 = vec3(0, 0, 0), waste_boost=False):
        super().__init__(car)

        self.target = Arena.clamp(ground(target), 100)
        self.waste_boost = waste_boost
        self.finish_distance = 500

        self._time_on_ground = 0
        self.driving = True

        # decide whether to start driving backwards and halfflip later
        forward_estimate = estimate_time(car, self.target)
        backwards_estimate = estimate_time(car, self.target, -1) + 0.5
        backwards = (
                dot(car.velocity, car.forward()) < 500
                and backwards_estimate < forward_estimate
                and (distance(car, self.target) > 3000 or distance(car, self.target) < 300)
                and car.position[2] < 200
        )

        self.drive = Drive(car, self.target, 2300, backwards)
        self.action = self.drive
コード例 #24
0
ファイル: arrive.py プロジェクト: robbai/RLBotPack
class Arrive(Maneuver):
    '''
    Arrive at a target position at a certain time (game seconds).
    You can also specify `target_direction`, and it will try to arrive
    at an angle. However this does work well only if the car is already
    roughly facing the specified direction, and only if it's far enough.
    '''
    def __init__(self, car: Car):
        super().__init__(car)

        self.target_direction: vec3 = None
        self.target: vec3 = None
        self.time: float = 0
        self.drive = Drive(car)
        self.travel = Travel(car)
        self.lerp_t = 0.6
        self.allow_dodges_and_wavedashes: bool = True
        self.additional_shift = 0

    def step(self, dt):
        target = self.target
        car = self.car

        if self.target_direction is not None:
            car_vel = norm(car.velocity)
            target_direction = normalize(self.target_direction)
            shift = clamp(
                distance(car.position, target) * self.lerp_t, 0, car_vel * 1.5)
            if shift - self.additional_shift < turn_radius(
                    clamp(car_vel, 1400, 2000) * 1.1):
                shift = 0
            else:
                shift += self.additional_shift
            translated_target = target - target_direction * shift

            translated_time = self.time - distance(
                translated_target, target) * 0.7 / max(
                    1, clamp(car_vel, 500, 2300))
        else:
            translated_target = target
            translated_time = self.time

        self.drive.target_pos = translated_target
        dist_to_target = distance(car.position, translated_target)
        target_speed = clamp(
            dist_to_target / max(0.001, translated_time - car.time), 0, 2300)

        self.drive.target_speed = target_speed

        if (self.allow_dodges_and_wavedashes and car.boost < 5 and
                dist_to_target > clamp(norm(car.velocity) + 600, 1400, 2300)
                and norm(car.velocity) < target_speed - 600
                or not self.travel.driving):
            self.travel.target = target
            self.travel.step(dt)
            self.controls = self.travel.controls
        else:
            self.drive.step(dt)
            self.controls = self.drive.controls

        self.finished = self.car.time >= self.time
        return self.finished

    def render(self, draw: DrawingTool):
        self.drive.render(draw)

        if self.target_direction is not None:
            draw.color(draw.lime)
            draw.triangle(self.target - self.target_direction * 250,
                          self.target_direction)
コード例 #25
0
ファイル: general_defense.py プロジェクト: azeemba/RLBotPack
class GeneralDefense(Maneuver):
    """
    First, attempt to rotate on the far side, and when far away enough from the target (usually the ball),
    turn around to face it. If already far enough and facing the target, just stop and wait.
    Also try to pickup boost pads along the way.
    This state expires after a short amount of time, so we can look if there's something better to do. If not,
    it can be simply instantiated again.
    """

    DURATION = 0.5

    BOOST_LOOK_RADIUS = 1200
    BOOST_LOOK_ANGLE = 0.5

    def __init__(self, car: Car, info: GameInfo, face_target: vec3,
                 distance_from_target: float):
        super().__init__(car)

        self.info = info
        self.face_target = face_target

        dist = min(distance_from_target,
                   ground_distance(face_target, self.info.my_goal.center) - 50)
        target_pos = ground(face_target) + ground_direction(
            face_target, self.info.my_goal.center) * dist

        near_goal = ground_distance(car, info.my_goal.center) < 3000
        side_shift = 400 if near_goal else 2500
        points = [
            target_pos + vec3(side_shift, 0, 0),
            target_pos - vec3(side_shift, 0, 0)
        ]
        target_pos = nearest_point(face_target,
                                   points) if near_goal else farthest_point(
                                       face_target, points)
        target_pos = Arena.clamp(target_pos, 500)

        self.travel = Travel(car, target_pos)
        self.travel.finish_distance = 800 if near_goal else 1500
        self.drive = Drive(car)
        self.stop = Stop(car)

        self.start_time = car.time

        self.pad = None

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

    def step(self, dt):
        # update finished state even if we are not using the controls
        self.travel.step(dt)

        if self.travel.finished:
            # turn around to face the target direction
            if angle_to(self.car, self.face_target) > 0.3:
                self.drive.target_pos = self.face_target
                self.drive.target_speed = 1000
                self.drive.step(dt)
                self.controls = self.drive.controls
                self.controls.handbrake = False
            else:
                self.stop.step(dt)
                self.controls = self.stop.controls

        else:
            self.pad = None

            # collect boost pads on the way (greedy algorithm, assumes first found is best)
            if self.car.boost < 90 and self.travel.interruptible():
                to_target = ground_direction(self.car, self.travel.target)

                for pad in self.info.large_boost_pads + self.info.small_boost_pads:
                    to_pad = ground_direction(self.car, pad)

                    if (pad.is_active and
                            distance(self.car, pad) < self.BOOST_LOOK_RADIUS
                            and angle_between(to_target,
                                              to_pad) < self.BOOST_LOOK_ANGLE):
                        self.pad = pad
                        self.drive.target_pos = pad.position
                        self.drive.target_speed = 2200
                        self.drive.step(dt)
                        self.controls = self.drive.controls
                        break

            # go to the actual target
            if self.pad is None:
                self.controls = self.travel.controls

        # don't waste boost during downtime
        self.controls.boost = False

        self.finished = self.travel.driving and self.car.time > self.start_time + self.DURATION

    def render(self, draw: DrawingTool):
        self.travel.render(draw)

        # render target pad
        if self.pad:
            draw.color(draw.blue)
            draw.circle(self.pad.position, 50)
コード例 #26
0
ファイル: arrive.py プロジェクト: ViliamVadocz/RLBotPack
class Arrive(Maneuver):
    """
    Arrive at a target position at a certain time (game seconds).
    You can also specify `target_direction`, and it will try to arrive
    at an angle. However this does work well only if the car is already
    roughly facing the specified direction, and only if it's far enough.
    """
    def __init__(self, car: Car):
        super().__init__(car)
        self.drive = Drive(car)
        self.travel = Travel(car)
        self.action = self.drive

        self.target_direction: Optional[None] = None
        self.target: vec3 = None
        self.arrival_time: float = 0
        self.backwards: bool = False

        self.lerp_t = 0.57
        self.allow_dodges_and_wavedashes: bool = True
        self.additional_shift = 0

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

    def step(self, dt):
        target = self.target
        car = self.car

        if self.target_direction is not None:
            car_speed = norm(car.velocity)
            target_direction = normalize(self.target_direction)

            # in order to arrive in a direction, we need to shift the target in the opposite direction
            # the magnitude of the shift is based on how far are we from the target
            shift = clamp(
                ground_distance(car.position, target) * self.lerp_t, 0,
                car_speed * 1.5)

            # if we're too close to the target, aim for the actual target so we don't miss it
            if shift - self.additional_shift < turn_radius(
                    clamp(car_speed, 1400, 2000) * 1.1):
                shift = 0
            else:
                shift += self.additional_shift

            shifted_target = target - target_direction * shift

            time_shift = ground_distance(shifted_target, target) * 0.7 / clamp(
                car_speed, 500, 2300)
            shifted_arrival_time = self.arrival_time - time_shift

        else:
            shifted_target = target
            shifted_arrival_time = self.arrival_time

        self.drive.target_pos = shifted_target
        self.travel.target = shifted_target

        dist_to_target = ground_distance(car.position, shifted_target)
        time_left = nonzero(shifted_arrival_time - car.time)
        target_speed = clamp(dist_to_target / time_left, 0, 2300)
        self.drive.target_speed = target_speed
        self.drive.backwards = self.backwards

        if ((self.allow_dodges_and_wavedashes
             and norm(car.velocity) < target_speed - 600 and car.boost < 20
             and not self.backwards)
                or not self.travel.driving  # a dodge/wavedash is in progress
            ):
            self.action = self.travel
        else:
            self.action = self.drive

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

        self.finished = self.car.time >= self.arrival_time

    def render(self, draw: DrawingTool):
        self.drive.render(draw)

        if self.target_direction is not None:
            draw.color(draw.lime)
            draw.triangle(self.target - self.target_direction * 250,
                          self.target_direction)
コード例 #27
0
class ShadowDefense(Maneuver):
    def __init__(self, car: Car, info: GameInfo, face_target: vec3,
                 distance_from_target: float):
        super().__init__(car)

        self.info = info
        self.face_target = face_target

        dist = min(distance_from_target,
                   ground_distance(face_target, self.info.my_goal.center) - 50)
        target_pos = ground(face_target) + ground_direction(
            face_target, self.info.my_goal.center) * dist

        near_goal = ground_distance(car, info.my_goal.center) < 3000
        side_shift = 400 if near_goal else 2000
        points = [
            target_pos + vec3(side_shift, 0, 0),
            target_pos - vec3(side_shift, 0, 0)
        ]
        target_pos = nearest_point(face_target,
                                   points) if near_goal else furthest_point(
                                       face_target, points)

        self.target = Arena.clamp(target_pos, 500)

        self.travel = Travel(car, self.target)
        self.travel.finish_distance = 800 if near_goal else 1500
        self.drive = Drive(car)

        self.start_time = car.time
        self.wait = Stop(car)

    def step(self, dt):
        ball = self.info.ball

        # if (
        #     distance(self.car, ball) < 1000
        #     and align(self.car.position, ball, self.info.my_goal.center) > 0.2
        # ):
        #     shift = normalize(cross(direction(ball, self.car), vec3(0, 0, 1))) * 1000
        #     self.travel.target = nearest_point(self.car.position, [ball.position + shift, ball.position - shift])
        # else:
        #     self.travel.target = self.target

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

        if ground_distance(self.car, self.travel.target) < 3000:
            self.controls.boost = False

        if self.travel.finished:
            if angle_to(self.car, self.face_target) > 0.3:
                self.drive.target_pos = self.face_target
                self.drive.step(dt)
                self.drive.target_speed = 700
                self.drive.controls.handbrake = False
                self.controls = self.drive.controls
            else:
                self.wait.step(dt)
                self.controls = self.wait.controls
        self.finished = self.travel.driving and self.car.time > self.start_time + 0.5

    def render(self, draw: DrawingTool):
        self.travel.render(draw)
コード例 #28
0
class DoubleJumpStrike(Strike):
    def intercept_predicate(self, car, ball):
        return 250 < ball.position[2] < 550

    def __init__(self, car: Car, info: GameInfo, target=None):
        self.drive = Drive(car)
        self.reorient = Reorient(car)

        self.jumping = False
        self.time_for_jump = float("inf")
        self.timer = 0.0

        super().__init__(car, info, target)

    def configure(self, intercept: Intercept):
        super().configure(intercept)
        self.drive.target_pos = ground(intercept.position)
        self.time_for_jump = self.double_jump_time_needed(
            intercept.position[2])

    def interruptible(self) -> bool:
        return not self.jumping and super().interruptible()

    def step(self, dt):
        if self.jumping:
            self.controls = Input()
            # first jump for full 0.2 sec
            if self.timer <= 0.2:
                self.controls.jump = True
            # single tick between jumps
            elif self.timer <= 0.2 + dt * JUMP_FALSE_TICKS:
                self.controls.jump = False
            # second jump
            else:
                self.controls.jump = True
                self.jumping = False
            self.timer += dt

        else:
            self.finished = self.intercept.time < self.info.time

            if self.car.on_ground:
                # manage speed before jump
                distance_to_target = ground_distance(self.car.position,
                                                     self.intercept.position)
                if distance_to_target < MIN_DIST_BEFORE_SPEED_CONTROL:
                    target_speed = distance_to_target / self.time_for_jump
                    self.drive.target_speed = -target_speed if self._should_strike_backwards else target_speed
                    self.drive.step(dt)
                    self.controls = self.drive.controls

                else:
                    super().step(dt)

                # decide when to jump
                ground_vel = ground(self.car.velocity)
                direction_to_target = ground_direction(self.car.position,
                                                       self.intercept.position)
                alignment = dot(normalize(ground_vel), direction_to_target)
                # check alignment
                if alignment >= MIN_ALIGNMENT:
                    # check that speed is correct
                    speed_in_direction = dot(ground_vel, direction_to_target)
                    time_to_target = distance_to_target / speed_in_direction
                    if self.time_for_jump - ALLOWED_TIME_ERROR <= time_to_target <= self.time_for_jump + ALLOWED_TIME_ERROR:
                        self.jumping = True

            # after jump (when the car is in the air)
            else:
                # face the ball for some additional height
                self.reorient.target_orientation = look_at(
                    direction(self.car.position, self.info.ball),
                    vec3(0, 0, 1))
                self.reorient.step(dt)
                self.controls = self.reorient.controls

    @staticmethod
    def double_jump_time_needed(height):
        """Return the time needed for the double jump to reach a given height"""
        # polynomial approximation
        a = 1.872348977E-8 * height * height * height
        b = -1.126747937E-5 * height * height
        c = 3.560647225E-3 * height
        d = -7.446058499E-3
        return a + b + c + d
コード例 #29
0
 def __init__(self, car: Car, info: GameInfo):
     super().__init__(car)
     self.drive = Drive(car)
     self.drive.backwards = True
     self.drive.target_pos = info.my_goal.center
     self.drive.target_speed = 1300