示例#1
0
def simple_aim(position: Vector3, yaw: float, target: Vector3) -> float:
    pos_to_target = target - position
    facing = Vector3(math.cos(yaw), math.sin(yaw), 0)
    self_right = Vector3.cross_product(facing, Vector3(0, 0, 1))

    if Vector3.dot_product(self_right, pos_to_target) < 0:
        return 1.0
    else:
        return -1.0
示例#2
0
def arrive_on_time(position: Vector3, velocity: Vector3, target: Vector3,
                   time_taken: float) -> SimpleControllerState:
    to_target = target - position
    distance = to_target.magnitude()
    average_speed = distance / (time_taken + 0.0000001)
    current_speed = velocity.magnitude()
    target_speed = (1 -
                    SPEED_MATCH) * current_speed + SPEED_MATCH * average_speed

    controller = SimpleControllerState()

    if current_speed < target_speed:
        controller.throttle = 1
        controller.boost = target_speed > 1410
    else:
        controller.boost = False
        if current_speed - target_speed > 75:
            controller.throttle = -1
        else:
            controller.throttle = 0

    if current_speed < 100:
        controller.throttle = 0.2

    return controller
示例#3
0
    def decide_step(self, packet: GameTickPacket) -> BaseStep:
        # If the ball is going to land on our side, go and dribble it.
        # If the is ball on their side, hover over where the most damaged areas are on our side.
        # If the bot has possession of the ball and is aiming at the other side, dodge to flick it to the other side.

        ball = PhysicsObject(packet.game_ball.physics)
        bot = PhysicsObject(packet.game_cars[self.agent.index].physics)
        ball_landing, _ = predict_landing_pos_time(ball.location,
                                                   ball.velocity)
        ball_landing_on_our_side = (self.agent.team == 0 and ball_landing.y < 0
                                    ) or (self.agent.team == 1
                                          and ball_landing.y > 0)

        # Dodge if dodging is in progress and it is not going to expire. Else, expire dodge_step if it isn't already.
        if self.dodge_step is not None:  # Is dodging in progress?
            if self.dodge_step.get_output(
                    packet) is not None:  # Is it going to expire this frame?
                return self.dodge_step
            else:
                self.dodge_step = None  # Expire dodge_step

        if ball_landing_on_our_side:
            # If carrying the ball
            if Vector3.distance(ball.location, bot.location) < 300:
                # If the bot is facing the opponents' side, dodge into the ball. Else, dribble it.
                # if (1/4*math.pi < bot.rotation.z < 3/4*math.pi) if self.agent.team == 0 else (-3/4*math.pi < bot.rotation.z < -1/4*math.pi):
                #     # Instantiate a new DodgeStep if the previous one expired
                #     if self.dodge_step is None:
                #         self.dodge_step = DodgeStep(self.agent, ball.location)
                #     return self.dodge_step
                return DribbleStep(self.agent, ball.location)
            return SimpleDribbleStep(self.agent)
        else:
            # Stay on our side if the ball is on the opponents' side
            return HoverStep(self.agent)
示例#4
0
def get_tile_average(packet: GameTickPacket,
                     field_info: FieldInfoPacket) -> Vector3:
    num_tiles = 70  # Don't hard code this. It was like this because it was giving errors.
    sum_x = 0
    sum_y = 0
    sum_z = 0
    total_weight = 0
    weight_multiplier = 2  # tested 2 and 3, 2 seems better

    for num_tile in range(num_tiles):
        tile_weight = packet.dropshot_tiles[
            num_tile].tile_state**weight_multiplier
        tile_x = field_info.goals[num_tile].location.x * tile_weight
        tile_y = field_info.goals[num_tile].location.y * tile_weight
        tile_z = field_info.goals[num_tile].location.z * tile_weight

        sum_x += tile_x
        sum_y += tile_y
        sum_z += tile_z
        total_weight += tile_weight

    median_x = sum_x / total_weight
    median_y = sum_y / total_weight
    median_z = sum_z / total_weight

    return Vector3(median_x, median_y, median_z)
示例#5
0
    def __init__(self, agent: BaseAgent, zone: Zone):
        super().__init__(agent)
        self.steps: List[BaseStep] = []
        self.sequential = False
        self.zone: Zone = zone

        self.area: Vector3 = Vector3(2500, 2250, 0)
        if zone == Zone.FOUR:
            self.area.x *= -1
        if self.agent.team == 1:  # Orange team
            self.area.y *= -1
示例#6
0
    def __choose_kickoff_plan(self, packet: GameTickPacket) -> Plan:
        is_on_diagonal = False
        teammate_on_diagonal = []
        bot_loc = Vector3(packet.game_cars[self.agent.index].physics.location)

        # For every bot in our team
        for i in range(3 * self.agent.team, 3 * (self.agent.team + 1)):
            location = packet.game_cars[i].physics.location
            # We are using ranges instead of exact values because the game engine will not always have the exact value.
            if 1860 < abs(location.x) < 1870 and 2375 < abs(location.y) < 2385:
                if i == self.agent.index:
                    is_on_diagonal = True
                else:
                    teammate_on_diagonal.append(True)

        # On a kickoff, the bot goes to the ball if:
        # - It's the only one on a diagonal kickoff
        # - Or if the bot is on the left for blue, or the right for orange
        # (The second point is arbitrary but it's a good way to not double commit on the ball on kickoff)
        #
        # If it's not going for kickoff and it's the closest to the other side compared to the other non-kickoff bot,
        # it will go to the opponent's side and chill there waiting for the ball to be passed to it.
        #
        # The remaining bot will stay on its side.
        team_side_y = 1200 * (1 if self.agent.team else -1)
        if is_on_diagonal:
            if True not in teammate_on_diagonal:
                self.zone = Zone.THREE
                return DribblePlan(self.agent,
                                   Vector3(packet.game_ball.physics.location))
            else:
                if bot_loc.x > 0:
                    self.zone = Zone.THREE
                    return DribblePlan(
                        self.agent, Vector3(packet.game_ball.physics.location))
                else:
                    self.zone = Zone.FOUR
                    opponent_side = Vector3(bot_loc.x, -team_side_y, bot_loc.z)
                    return MovePlan(self.agent, opponent_side)
        else:
            if teammate_on_diagonal.count(True) == 2:
                self.zone = Zone.ONE_AND_TWO
                team_side = Vector3(bot_loc.x, team_side_y, bot_loc.z)
                return MovePlan(self.agent, team_side)
            else:
                if bot_loc.x > 0:
                    self.zone = Zone.ONE_AND_TWO
                    team_side = Vector3(bot_loc.x, team_side_y, bot_loc.z)
                    return MovePlan(self.agent, team_side)
                else:
                    self.zone = Zone.FOUR
                    opponent_side = Vector3(bot_loc.x, -team_side_y, bot_loc.z)
                    return MovePlan(self.agent, opponent_side)
示例#7
0
def predict_landing_pos_time(position: Vector3,
                             velocity: Vector3) -> Tuple[Vector3, float]:
    distance_ball_to_ground = GROUND_Z_AXIS - position.z
    a = velocity.z**2 / GRAVITY**2
    b = 2 * distance_ball_to_ground / GRAVITY
    quadratic = math.sqrt(a - b)
    flight_time = velocity.z / GRAVITY + quadratic
    distance_covered_x = velocity.x * flight_time
    distance_covered_y = velocity.y * flight_time

    landing_pos = position + Vector3(distance_covered_x, distance_covered_y,
                                     distance_ball_to_ground)

    return landing_pos, flight_time
示例#8
0
def get_ground_bounces(path: BallPrediction) -> List[Tuple[Vector3, float]]:
    ground_bounces: List[Tuple[Vector3, float]] = []
    for i in range(1, path.num_slices):
        prev_ang_v = path.slices[i - 1].physics.angular_velocity
        prev_norm_ang_vel = (math.sqrt(prev_ang_v.x**2 + prev_ang_v.y**2 +
                                       prev_ang_v.z**2))
        current_slice = path.slices[i]
        current_ang_v = current_slice.physics.angular_velocity
        current_norm_ang_vel = (math.sqrt(current_ang_v.x**2 +
                                          current_ang_v.y**2 +
                                          current_ang_v.z**2))
        if prev_norm_ang_vel != current_norm_ang_vel and current_slice.physics.location.z < 125:
            ground_bounces.append((Vector3(current_slice.physics.location),
                                   current_slice.game_seconds))

    return ground_bounces
示例#9
0
 def __init__(self, physics: game_data_struct.Physics):
     self.location: Vector3 = Vector3(physics.location)
     self.velocity: Vector3 = Vector3(physics.velocity)
     self.rotation: Vector3 = Vector3(physics.rotation)
     self.angular_velocity: Vector3 = Vector3(physics.angular_velocity)