Exemplo n.º 1
0
    def get_shot(self, target=None, weight=None, cap=None):
        if self.predictions['self_min_time_to_ball'] == 7:
            return

        if self.can_shoot is None or self.predictions['own_goal'] or (
                self.playstyle is self.playstyles.Neutral
                and target is self.best_shot):
            if weight is None:
                weight = get_weight(self, target)

            can_aerial = self.aerials
            can_double_jump = self.double_jump
            can_jump = self.jump
            can_ground = self.ground_shot

            if len(self.friends) == 0:
                can_aerial = can_aerial and (self.predictions['own_goal'] or
                                             (self.me.location.z > 300
                                              and self.me.airborne))
                self_intercept_location = self.ball_prediction_struct.slices[
                    self.min_intercept_slice].physics.location
                self_intercept_location = Vector(
                    abs(self_intercept_location.x),
                    self_intercept_location.y * side(self.team))
                can_double_jump = can_double_jump and (
                    self_intercept_location.x < 1300
                    or self_intercept_location.y > 3840)

            if not can_aerial and not can_double_jump and not can_jump and not can_ground:
                return

            if target is self.anti_shot and self.me.location.y * side(
                    self.team) > 5120:
                target = None

            shot = find_shot(self,
                             target,
                             weight=weight,
                             cap_=6 if cap is None else cap,
                             can_aerial=can_aerial,
                             can_double_jump=can_double_jump,
                             can_jump=can_jump,
                             can_ground=can_ground
                             ) if target is not None else find_any_shot(
                                 self,
                                 cap_=3 if cap is None else cap,
                                 can_aerial=can_aerial,
                                 can_double_jump=can_double_jump,
                                 can_jump=can_jump,
                                 can_ground=can_ground)

            if shot is not None:
                return {
                    "weight": weight,
                    "intercept_time": shot.intercept_time,
                    "is_best_shot": target is self.best_shot,
                    "shot": shot
                }
Exemplo n.º 2
0
    def get_shot(self, target=None, weight=None, cap=None):
        if self.me.minimum_time_to_ball == 7:
            return

        if weight is None:
            weight = self.get_weight(target)

        can_aerial = self.aerials
        can_double_jump = self.double_jump
        can_jump = self.jump
        can_ground = self.ground_shot

        if self.num_friends == 0 and self.num_foes == 1:
            can_aerial = can_aerial and (
                self.is_own_goal or
                (self.me.location.z > 300 and self.me.airborne)
                or target is self.best_shot or not self.can_any_foe_aerial())

        if self.num_friends == 0:
            self_intercept_location = self.ball_prediction_struct.slices[
                self.min_intercept_slice].physics.location
            self_intercept_location = Vector(
                abs(self_intercept_location.x),
                self_intercept_location.y * self.side)
            can_double_jump = can_double_jump and (
                self_intercept_location.x < 1300
                or self_intercept_location.y > 3840)

        if not can_aerial and not can_double_jump and not can_jump and not can_ground:
            return

        if target is self.anti_shot and self.me.location.y * self.side > 5120:
            target = None

        shot = find_shot(
            self,
            target,
            weight=weight,
            cap_=6 if cap is None else cap,
            can_aerial=can_aerial,
            can_double_jump=can_double_jump,
            can_jump=can_jump,
            can_ground=can_ground) if target is not None else find_any_shot(
                self,
                cap_=4 if cap is None else cap,
                can_aerial=can_aerial,
                can_double_jump=can_double_jump,
                can_jump=can_jump,
                can_ground=can_ground)

        if shot is not None:
            return shot
Exemplo n.º 3
0
    def run(self):
        # NOTE This method is ran every tick

        # If the kickoff isn't done
        if not self.kickoff_done:
            # If the stack is clear
            if self.is_clear():
                # Push a generic kickoff to the stack
                # TODO make kickoff routines for each of the 5 kickoffs positions
                self.push(routines.generic_kickoff())

            # we don't want to do anything else during our kickoff
            return

        # If the stack if clear and we're in the air
        if self.is_clear() and self.me.airborne:
            # Recover - This routine supports floor, wall, and ceiling recoveries, as well as recovering towards a target
            self.push(routines.recovery())

            # we've made our decision and we don't want to run anything else
            return

        # If we have less than 36 boost
        # TODO this bot will go for boost no matter what - this is AWFUL, especially in a 1v1!
        if self.me.boost < 36:
            # If the stack is clear
            if self.is_clear():
                # Get a list of all of the large, active boosts
                boosts = tuple(boost for boost in self.boosts
                               if boost.active and boost.large)

                # if there's at least one large and active boost
                if len(boosts) > 0:
                    # Get the closest boost
                    closest_boost = min(boosts,
                                        key=lambda boost: boost.location.dist(
                                            self.me.location))
                    # Goto the nearest boost
                    self.push(routines.goto_boost(closest_boost))

            # we've made our decision and we don't want to run anything else
            if not self.is_clear():
                return

        # if the stack is clear, then run the following - otherwise, if the stack isn't empty, then look for a shot every 4th tick while the other routine is running
        if self.is_clear() or self.odd_tick == 0:
            shot = None

            # TODO we might miss the net, even when using a target - make a pair of targets that are small than the goal so we have a better chance of scoring!
            # If the ball is on the enemy's side of the field, or slightly on our side
            if self.ball.location.y * utils.side(self.team) < 640:
                # Find a shot, on target - double_jump, jump_shot, and ground_shot  are automatically disabled if we're airborne
                shot = tools.find_shot(self, self.foe_goal_shot)

            # TODO Using an anti-target here could be cool - do to this, pass in a target tuple that's (right_target, left_target) (instead of (left, right)) into tools.find_shot (NOT tools.find_any_shot)
            # TODO When possible, we might want to take a little bit more time to shot the ball anywhere in the opponent's end - this target should probably be REALLY LONG AND HIGH!
            # If we're behind the ball and we couldn't find a shot on target
            if shot is None and self.ball.location.y * utils.side(
                    self.team) < self.me.location.y * utils.side(self.team):
                # Find a shot, but without a target - double_jump, jump_shot, and ground_shot are automatically disabled if we're airborne
                shot = tools.find_any_shot(self)

            # If we found a shot
            if shot is not None:
                # If the stack is clear
                if self.is_clear():
                    # Shoot
                    self.push(shot)
                # If the stack isn't clear
                else:
                    # Get the current shot's name (ex jump_shot, double_jump, ground_shot or Aerial) as a string
                    current_shot_name = self.stack[0].__class__.__name__
                    # Get the new shot's name as a string
                    new_shot_name = shot.__class__.__name__

                    # If the shots are the same type
                    if new_shot_name is current_shot_name:
                        # Update the existing shot with the new information
                        self.stack[0].update(shot)
                    # If the shots are of different types
                    else:
                        # Clear the stack
                        self.clear()
                        # Shoot
                        self.push(shot)

                # we've made our decision and we don't want to run anything else
                return

        # TODO this setup is far from ideal - a custom shadow/retreat routine is probably best for the bot...
        # Make sure to put custom routines in a separate file from VirxERLU routines, so you can easily update VirxERLU to newer versions.
        # If the stack is still clear
        if self.is_clear():
            # If ball is in our half
            if self.ball.location.y * utils.side(self.team) > 640:
                retreat_routine = routines.retreat()
                # Check if the retreat routine is viable
                if retreat_routine.is_viable(self):
                    # Retreat back to the net
                    self.push(retreat_routine)
            # If the ball isn't in our half
            else:
                shadow_routine = routines.shadow()
                # Check if the shadow routine is viable
                if shadow_routine.is_viable(self):
                    # Shadow
                    self.push(shadow_routine)