def choose_maneuver(info: GameInfo, my_car: Car):
    ball = info.ball
    teammates = info.get_teammates(my_car)
    my_team = [my_car] + teammates
    their_goal = ground(info.their_goal.center)
    my_goal = ground(info.my_goal.center)

    # recovery
    if not my_car.on_ground:
        return Recovery(my_car)

    # kickoff
    if ball.position[0] == 0 and ball.position[1] == 0:

        # if I'm nearest to the ball, go for kickoff
        if min(my_team, key=lambda car: distance(car, ball)) is my_car:
            return kickoffs.choose_kickoff(info, my_car)

    if my_car.boost < 20:
        return Refuel(my_car, info)

    info.predict_ball()

    my_intercept = Intercept(my_car, info.ball_predictions)
    teammates_intercepts = [
        Intercept(mate, info.ball_predictions) for mate in teammates
    ]
    our_intercepts = teammates_intercepts + [my_intercept]

    good_intercepts = [
        i for i in our_intercepts
        if align(i.car.position, i.ball, their_goal) > 0.0
    ]
    if good_intercepts:
        best_intercept = min(good_intercepts,
                             key=lambda intercept: intercept.time)
    else:
        best_intercept = min(our_intercepts,
                             key=lambda i: distance(i.car, my_goal))

    if best_intercept is my_intercept:
        # if not completely out of position, go for a shot
        if (align(my_intercept.car.position, my_intercept.ball, their_goal) > 0
                or ground_distance(my_intercept, my_goal) > 6000):
            return offense.any_shot(info, my_intercept.car, their_goal,
                                    my_intercept)

        # otherwise try to clear
        else:
            return defense.any_clear(info, my_intercept.car)

    # if I'm nearest to goal, stay far back
    if min(my_team, key=lambda car: distance(car, my_goal)) is my_car:
        return GeneralDefense(my_car, info, my_intercept.position, 7000)

    # otherwise get into position
    return GeneralDefense(my_car, info, my_intercept.position, 4000)
Exemple #2
0
    def initialize_hive(self, packet: GameTickPacket) -> None:
        index = next(iter(self.drone_indices))
        self.team = packet.game_cars[index].team

        self.info = GameInfo(self.team)
        self.info.set_mode("soccar")
        self.strategy = HivemindStrategy(self.info, self.logger)
        self.draw = DrawingTool(self.renderer, self.team)
        self.drones = [Drone(self.info.cars[i], i) for i in self.drone_indices]

        self.logger.handlers[0].setLevel(
            logging.NOTSET)  # override handler level
        self.logger.setLevel(logging.INFO if RELEASE else logging.DEBUG)
        self.logger.info("Beehive initialized")
Exemple #3
0
def choose_maneuver(info: GameInfo, my_car: Car):
    ball = info.ball
    their_goal = ground(info.their_goal.center)
    my_goal = ground(info.my_goal.center)
    opponents = info.get_opponents()

    # recovery
    if not my_car.on_ground:
        return Recovery(my_car)

    # kickoff
    if ball.position[0] == 0 and ball.position[1] == 0:
        return kickoffs.choose_kickoff(info, my_car)

    info.predict_ball()

    my_intercept = Intercept(my_car, info.ball_predictions)
    their_intercepts = [
        Intercept(opponent, info.ball_predictions) for opponent in opponents
    ]
    their_intercept = min(their_intercepts, key=lambda i: i.time)
    opponent = their_intercept.car

    banned_boostpads = {
        pad
        for pad in info.large_boost_pads
        if abs(pad.position[1] -
               their_goal[1]) < abs(my_intercept.position[1] - their_goal[1])
        or abs(pad.position[0] - my_car.position[0]) > 6000
    }

    # if ball is in a dangerous position, clear it
    if (ground_distance(my_intercept, my_goal) < 3000
            and (abs(my_intercept.position[0]) < 2000
                 or abs(my_intercept.position[1]) < 4500)
            and my_car.position[2] < 300):
        if align(my_car.position, my_intercept.ball, their_goal) > 0.5:
            return offense.any_shot(info,
                                    my_intercept.car,
                                    their_goal,
                                    my_intercept,
                                    allow_dribble=True)
        return defense.any_clear(info, my_intercept.car)

    # if I'm low on boost and the ball is not near my goal, go for boost
    if my_car.boost < 10 and ground_distance(my_intercept, their_goal) > 3000:
        refuel = Refuel(my_car, info, forbidden_pads=banned_boostpads)
        if refuel.pad: return refuel

    ball_in_their_half = abs(my_intercept.position[1] - their_goal[1]) < 3000
    shadow_distance = 4000 if ball_in_their_half else 6000
    # if they can hit the ball sooner than me and they aren't out of position, wait in defense
    if (their_intercept.time < my_intercept.time
            and align(opponent.position, their_intercept.ball,
                      my_goal) > -0.1 + opponent.boost / 100
            and ground_distance(opponent, their_intercept) > 300
            and dot(opponent.velocity,
                    ground_direction(their_intercept, my_goal)) > 0):
        return GeneralDefense(my_car,
                              info,
                              my_intercept.position,
                              shadow_distance,
                              force_nearest=ball_in_their_half)

    # if not completely out of position, go for a shot
    if (align(my_car.position, my_intercept.ball, their_goal) > -0.5
            or ground_distance(my_intercept, their_goal) < 2000
            or ground_distance(opponent, their_intercept) < 300):
        if my_car.position[2] < 300:
            shot = offense.any_shot(info,
                                    my_intercept.car,
                                    their_goal,
                                    my_intercept,
                                    allow_dribble=True)
            if (not isinstance(shot, Strike)
                    or shot.intercept.time < their_intercept.time
                    or abs(shot.intercept.position[0]) < 3500):
                return shot

    if my_car.boost < 30:
        refuel = Refuel(my_car, info, forbidden_pads=banned_boostpads)
        if refuel.pad: return refuel

    # fallback
    return GeneralDefense(my_car,
                          info,
                          my_intercept.position,
                          shadow_distance,
                          force_nearest=ball_in_their_half)
Exemple #4
0
class Beehive(PythonHivemind):
    def __init__(self, *args):
        super().__init__(*args)
        self.info: GameInfo = None
        self.team: int = None
        self.draw: DrawingTool = None
        self.drones: List[Drone] = []
        self.strategy: HivemindStrategy = None

        self.last_latest_touch_time = 0.0

    def initialize_hive(self, packet: GameTickPacket) -> None:
        index = next(iter(self.drone_indices))
        self.team = packet.game_cars[index].team

        self.info = GameInfo(self.team)
        self.info.set_mode("soccar")
        self.strategy = HivemindStrategy(self.info, self.logger)
        self.draw = DrawingTool(self.renderer, self.team)
        self.drones = [Drone(self.info.cars[i], i) for i in self.drone_indices]

        self.logger.handlers[0].setLevel(
            logging.NOTSET)  # override handler level
        self.logger.setLevel(logging.INFO if RELEASE else logging.DEBUG)
        self.logger.info("Beehive initialized")

    def get_outputs(self, packet: GameTickPacket) -> Dict[int, PlayerInput]:
        self.info.read_packet(packet, self.get_field_info())

        # if a kickoff is happening and none of the drones have a Kickoff maneuver active, reset all drone maneuvers
        if (packet.game_info.is_kickoff_pause
                and self.info.ball.position[0] == 0
                and self.info.ball.position[1] == 0 and not any(
                    isinstance(drone.maneuver, Kickoff)
                    for drone in self.drones)):
            if len(self.drones) == 1:
                self.drones[0].maneuver = None
            else:
                self.strategy.set_kickoff_maneuvers(self.drones)

        # reset drone maneuvers when an opponent hits the ball
        touch = packet.game_ball.latest_touch
        if touch.time_seconds > self.last_latest_touch_time and touch.team != self.team:
            self.last_latest_touch_time = touch.time_seconds
            for drone in self.drones:
                if drone.maneuver and drone.maneuver.interruptible(
                ):  # don't reset a drone while dodging/recovering
                    drone.maneuver = None

        # reset drone maneuver when it gets demoed
        for drone in self.drones:
            if drone.maneuver and drone.car.demolished:
                drone.maneuver = None

        # if at least one drone doesn't have an active maneuver, execute strategy code
        if None in [drone.maneuver for drone in self.drones]:
            self.logger.debug("Setting maneuvers")
            if len(self.drones) == 1:
                self.drones[0].maneuver = teamplay_strategy.choose_maneuver(
                    self.info, self.drones[0].car)
            else:
                self.strategy.set_maneuvers(self.drones)

        for drone in self.drones:
            if drone.maneuver is None:
                continue

            # execute maneuvers
            drone.maneuver.step(self.info.time_delta)
            drone.controls = drone.maneuver.controls

            drone.maneuver.render(self.draw)

            # draw names of maneuvers above our drones
            self.draw.color(self.draw.yellow)
            self.draw.string(drone.car.position + vec3(0, 0, 50),
                             type(drone.maneuver).__name__)

            # expire finished maneuvers
            if drone.maneuver.finished:
                drone.maneuver = None

        if len(self.drones) > 1:
            self.strategy.avoid_demos_and_team_bumps(self.drones)

        self.strategy.render(self.draw)
        self.draw.execute()
        return {drone.index: drone.get_player_input() for drone in self.drones}
Exemple #5
0
 def initialize_agent(self):
     self.info = GameInfo(self.team)
     self.info.set_mode("soccar")
     self.draw = DrawingTool(self.renderer, self.team)
Exemple #6
0
class BotimusPrime(BaseAgent):
    RENDERING = True

    def __init__(self, name, team, index):
        super().__init__(name, team, index)
        self.info: GameInfo = None
        self.draw: DrawingTool = None

        self.tick_counter = 0
        self.last_latest_touch_time = 0

        self.maneuver: Optional[Maneuver] = None
        self.controls: SimpleControllerState = SimpleControllerState()

    def initialize_agent(self):
        self.info = GameInfo(self.team)
        self.info.set_mode("soccar")
        self.draw = DrawingTool(self.renderer, self.team)

    def get_output(self, packet: GameTickPacket):
        # wait a few ticks after initialization, so we work correctly in rlbottraining
        if self.tick_counter < 20:
            self.tick_counter += 1
            return Input()

        self.info.read_packet(packet, self.get_field_info())

        # cancel maneuver if a kickoff is happening and current maneuver isn't a kickoff maneuver
        if packet.game_info.is_kickoff_pause and not isinstance(
                self.maneuver, Kickoff):
            self.maneuver = None

        # reset maneuver when another car hits the ball
        touch = packet.game_ball.latest_touch
        if (touch.time_seconds > self.last_latest_touch_time
                and touch.player_name != packet.game_cars[self.index].name):
            self.last_latest_touch_time = touch.time_seconds

            # don't reset when we're dodging, wavedashing or recovering
            if self.maneuver and self.maneuver.interruptible():
                self.maneuver = None

        # choose maneuver
        if self.maneuver is None:
            if self.RENDERING:
                self.draw.clear()

            if self.info.get_teammates(self.info.cars[self.index]):
                self.maneuver = teamplay_strategy.choose_maneuver(
                    self.info, self.info.cars[self.index])
            else:
                self.maneuver = solo_strategy.choose_maneuver(
                    self.info, self.info.cars[self.index])

        # execute maneuver
        if self.maneuver is not None:
            self.maneuver.step(self.info.time_delta)
            self.controls = self.maneuver.controls

            if self.RENDERING:
                self.draw.group("maneuver")
                self.draw.color(self.draw.yellow)
                self.draw.string(
                    self.info.cars[self.index].position + vec3(0, 0, 50),
                    type(self.maneuver).__name__)
                self.maneuver.render(self.draw)

            # cancel maneuver when finished
            if self.maneuver.finished:
                self.maneuver = None

        if self.RENDERING:
            self.draw.execute()

        return self.controls
Exemple #7
0
def is_opponent_close(info: GameInfo, dist: float) -> bool:
    for opponent in info.get_opponents():
        if ground_distance(opponent.position + opponent.velocity * 0.5,
                           info.ball) < dist:
            return True
    return False