Beispiel #1
0
    def execute_dribbling(self):
        # Grab best pass
        self.pass_target, self.pass_score = evaluation.passing_positioning.eval_best_receive_point(
            main.ball().pos, main.our_robots(),
            AdaptiveFormation.FIELD_POS_WEIGHTS,
            AdaptiveFormation.NELDER_MEAD_ARGS,
            AdaptiveFormation.PASSING_WEIGHTS)

        # Grab shot chance
        self.shot_chance = evaluation.shooting.eval_shot(main.ball().pos)

        # Recalculate dribbler pos
        self.check_dribbling_timer += 1
        if (self.check_dribbling_timer > self.check_dribbling_timer_cutoff):
            self.check_dribbling_timer = 0
            self.dribbler.pos, _ = evaluation.passing_positioning.eval_best_receive_point(
                main.ball().pos, main.our_robots(),
                AdaptiveFormation.FIELD_POS_WEIGHTS,
                AdaptiveFormation.NELDER_MEAD_ARGS,
                AdaptiveFormation.DRIBBLING_WEIGHTS)

        # TODO: Get list of top X pass positions and have robots in good positions to reach them
        # Good positions can be definied by offensive / defensive costs
        # Offensive positions move onto the ball in the direction of the goal
        # Defensive cover the center of the field

        # Setup previous values (Basic complementary filter)
        c = .8
        self.prev_shot_chance = c * self.shot_chance + \
                                (1 - c) * self.prev_shot_chance
        self.prev_pass_score = c * self.pass_score + \
                               (1 - c) * self.prev_pass_score
    def on_enter_shoot(self):
        self.remove_all_subbehaviors()
        #Depending on shot and pass chances,
        #the striker will shoot
        #or
        #the striker will pass to the distractor and the distractor will shoot
        pass_striker_to_distractor_chance = evaluation.passing.eval_pass(
            self.striker_point, self.Distraction_recieve_pass_point,
            main.our_robots())
        shot_of_striker_chance = evaluation.shooting.eval_shot(
            self.striker_point, main.our_robots())
        shot_of_distractor_chance = evaluation.shooting.eval_shot(
            self.Distraction_recieve_pass_point, main.our_robots())

        if pass_striker_to_distractor_chance * shot_of_distractor_chance > shot_of_striker_chance:
            dont_shoot = True

        self.add_subbehavior(
            skills.move.Move(self.Distraction_recieve_pass_point),
            'make first distractor stay again',
            required=True)
        self.add_subbehavior(
            skills.move.Move(self.Distraction_point),
            'make distracor stay',
            required=False,
            priority=10)
        self.add_subbehavior(
            skills.pivot_kick.PivotKick(), 'shooting', required=True)
    def __init__(self):
        super().__init__(continuous=True)

        self.add_transition(behavior.Behavior.State.start,
                            behavior.Behavior.State.running, lambda: True,
                            'immediately')

        # Add a center blocker
        self.add_subbehavior(
            tactics.stopped.circle_on_center.CircleOnCenter(
                # TODO find a way to do this without hard coding 3
                # defense/goalie robots (or make those constants)
                min_robots=1 if (main.our_robots() is not None) and len(
                    main.our_robots()) > 3 else 0),
            'circle_up',
            priority=15,
            required=True)

        # Add two marker robots (with lower than defense priority)
        mark_one = skills.mark.Mark()
        self.add_subbehavior(mark_one,
                             'mark_one',
                             priority=planning_priority.PIVOT_KICK + 1,
                             required=False)
        mark_two = skills.mark.Mark()
        self.add_subbehavior(mark_two,
                             'mark_two',
                             priority=planning_priority.PIVOT_KICK,
                             required=False)
Beispiel #4
0
 def on_enter_strategizing(self):
     #pick a robot to talk to
     target_bot = random.randint(0,
                                 ((len(main.our_robots()) - 1) if
                                  (main.our_robots() is not None) else 0))
     self.subbehavior_with_name('coach').pos = (
         main.our_robots()[target_bot].pos + robocup.Point(
             -constants.Robot.Radius * 2, constants.Robot.Radius * 2))
     self.subbehavior_with_name(
         'coach').threshold = constants.Robot.Radius * 2
     print("\n\n Alright Number " + str(target_bot) + " here is the plan:")
def can_collect_ball_before_opponent(our_robots_to_check=None,
                                     their_robots_to_check=None,
                                     our_robots_to_dodge=None,
                                     their_robots_to_dodge=None,
                                     valid_error_percent=0.05):
    if our_robots_to_check is None:
        our_robots_to_check = main.our_robots()

    if their_robots_to_check is None:
        their_robots_to_check = main.their_robots()

    if our_robots_to_dodge is None:
        our_robots_to_dodge = main.our_robots()

    if their_robots_to_dodge is None:
        their_robots_to_dodge = main.their_robots()

    shortest_opp_time = float("inf")
    shortest_our_time = float("inf")
    dodge_dist = constants.Robot.Radius
    closest_robot = None

    # TODO: Do some sort of prediction as the ball moves
    target_pos = main.ball().pos

    # TODO: Take velocity and acceleration into account
    # Find closest opponent robot
    for bot in their_robots_to_check:
        dist = estimate_path_length(bot.pos, target_pos, our_robots_to_dodge,
                                    dodge_dist)
        target_dir = (target_pos - bot.pos).normalized()
        time = robocup.get_trapezoidal_time(
            dist, dist, 2.2, 1,
            target_dir.dot(bot.vel) / target_dir.mag(), 0)
        if (time < shortest_opp_time):
            shortest_opp_time = time

    # Find closest robot on our team
    for bot in our_robots_to_check:
        dist = estimate_path_length(bot.pos, target_pos, their_robots_to_dodge,
                                    dodge_dist)
        target_dir = (target_pos - bot.pos).normalized()
        time = robocup.get_trapezoidal_time(
            dist, dist, 2.2, 1,
            target_dir.dot(bot.vel) / target_dir.mag(), 0)
        if (time < shortest_our_time):
            shortest_our_time = time
            closest_robot = bot

    # Greater than 1 when we are further away
    print(shortest_our_time)
    print(shortest_opp_time)
    return shortest_our_time < shortest_opp_time * (
        1 + valid_error_percent), closest_robot
Beispiel #6
0
 def on_exit_restart_play_began(self):
     for bot in main.our_robots():
         if self._touching_ball(bot):
             self.kicker_shell_id = bot.shell_id()
             return
     if main.ball().valid:
         # pick our closest robot
         ball_pos = self.pre_ball_pos
         if not ball_pos:
             ball_pos = main.ball().pos
         bot = min(main.our_robots(),
                   key=lambda bot: bot.pos.dist_to(ball_pos))
         self.kicker_shell_id = bot.shell_id()
 def on_exit_restart_play_began(self):
     for bot in main.our_robots():
         if self._touching_ball(bot):
             self.kicker_shell_id = bot.shell_id()
             return
     if main.ball().valid:
         # pick our closest robot
         ball_pos = self.pre_ball_pos
         if not ball_pos:
             ball_pos = main.ball().pos
         bot = min(main.our_robots(),
                   key=lambda bot: bot.pos.dist_to(ball_pos))
         self.kicker_shell_id = bot.shell_id()
Beispiel #8
0
def can_collect_ball_before_opponent(our_robots_to_check=None,
                                     their_robots_to_check=None,
                                     our_robots_to_dodge=None,
                                     their_robots_to_dodge=None,
                                     valid_error_percent=0.05):
    if our_robots_to_check is None:
        our_robots_to_check = main.our_robots()

    if their_robots_to_check is None:
        their_robots_to_check = main.their_robots()

    if our_robots_to_dodge is None:
        our_robots_to_dodge = main.our_robots()

    if their_robots_to_dodge is None:
        their_robots_to_dodge = main.their_robots()

    shortest_opp_time = float("inf")
    shortest_our_time = float("inf")
    dodge_dist = constants.Robot.Radius
    closest_robot = None

    # TODO: Do some sort of prediction as the ball moves
    target_pos = main.ball().pos

    # TODO: Take velocity and acceleration into account
    # Find closest opponent robot
    for bot in their_robots_to_check:
        dist = estimate_path_length(bot.pos, target_pos, our_robots_to_dodge,
                                    dodge_dist)
        target_dir = (target_pos - bot.pos).normalized()
        time = robocup.get_trapezoidal_time(dist, dist, 2.2, 1,
                                            target_dir.dot(bot.vel) /
                                            target_dir.mag(), 0)
        if (time < shortest_opp_time):
            shortest_opp_time = time

    # Find closest robot on our team
    for bot in our_robots_to_check:
        dist = estimate_path_length(bot.pos, target_pos, their_robots_to_dodge,
                                    dodge_dist)
        target_dir = (target_pos - bot.pos).normalized()
        time = robocup.get_trapezoidal_time(dist, dist, 2.2, 1,
                                            target_dir.dot(bot.vel) /
                                            target_dir.mag(), 0)
        if (time < shortest_our_time):
            shortest_our_time = time
            closest_robot = bot

    return shortest_our_time < shortest_opp_time * (1 + valid_error_percent
                                                    ), closest_robot
Beispiel #9
0
    def add_shot_obstacle(self, excluded_robots=[]):
        pt = self.aim_target_point
        if pt != None:
            # segment centered at the target point that's @width wide and perpendicular to the shot
            shot_perp = (main.ball().pos - pt).perp_ccw().normalized()

            # Make the shot triangle obstacle a fixed width at the end unless
            # we're aiming at a segment. In that case, just use the length of
            # the segment.
            width = 0.5
            if isinstance(self.target, robocup.Segment):
                width = self.target.length()

            a = pt + shot_perp * width / 2.0
            b = pt - shot_perp * width / 2.0

            # build the obstacle polygon
            obs = robocup.Polygon()
            obs.add_vertex(main.ball().pos)
            obs.add_vertex(a)
            obs.add_vertex(b)

            # tell the bots to not go there
            for bot in main.our_robots():
                if bot not in excluded_robots + [self.robot]:
                    bot.add_local_obstacle(obs)
Beispiel #10
0
    def __init__(self):
        super().__init__(continuous=True)

        goalie = submissive_goalie.SubmissiveGoalie()
        goalie.shell_id = main.root_play().goalie_id
        self.add_subbehavior(goalie, "goalie", required=True)

        self.add_state(WingerWall.State.defending,
                       behavior.Behavior.State.running)

        self.add_transition(behavior.Behavior.State.start,
                            WingerWall.State.defending, lambda: True,
                            "immediately")

        self.aggression = 1
        self.kick_eval = robocup.KickEvaluator(main.system_state())
        self.wingers = []
        self.forwards = []
        self.max_wingers = 3
        self.max_wall = 3
        self.assigned_wingers = 0
        # List of tuples of (class score, robot obj)

        self.kick_eval.excluded_robots.clear()

        for bot in main.our_robots():
            self.kick_eval.add_excluded_robot(bot)
    def __init__(self):
        super().__init__(start_state=DoubleTouchTracker.State.start)

        for state in DoubleTouchTracker.State:
            self.add_state(state)

        # FIXME: is it only restart plays?
        self.add_transition(DoubleTouchTracker.State.start,
            DoubleTouchTracker.State.restart_play_began,
            lambda: (main.root_play().play != None
                and main.root_play().play.__class__.is_restart()
                and main.game_state().is_our_restart()),
            'we start running an offensive restart play')

        self.add_transition(DoubleTouchTracker.State.restart_play_began,
            DoubleTouchTracker.State.kicking,
            lambda: any(bot.has_ball() for bot in main.our_robots()),
            'one of our bots has the ball')

        self.add_transition(DoubleTouchTracker.State.kicking,
            DoubleTouchTracker.State.kicker_forbidden,
            lambda: not self.kicker_has_possession(),
            'kicker kicks or fumbles ball')

        self.add_transition(DoubleTouchTracker.State.kicker_forbidden,
            DoubleTouchTracker.State.other_robot_touched,
            lambda: self.other_robot_touching_ball(),
            'another robot has touched the ball')
    def execute_pass_set(self):
        # gets the best position to travel to for ball reception
        best_point = self.passing_point

        # sets the second point
        alt_point, value2 = evaluation.passing_positioning.eval_best_receive_point(
            self.passing_point, main.our_robots(),
            AdvanceZoneMidfielder.FIELD_POS_WEIGHTS,
            AdvanceZoneMidfielder.NELDER_MEAD_ARGS,
            AdvanceZoneMidfielder.PASSING_WEIGHTS)

        # check for futile position i.e the alternate position is in the way of a shot from best position
        if self.in_shot_triangle(best_point, alt_point):
            alt_point = self.remove_obstruction(best_point, alt_point)

        points = [best_point, alt_point]
        # moves the robots and assigns information
        for i in range(len(points)):
            if (self.moves[i] is None):
                self.moves[i] = skills.move.Move(points[i])
                self.add_subbehavior(self.moves[i],
                                     self.names[i],
                                     required=False,
                                     priority=self.priorities[i])
            else:
                self.moves[i].pos = points[i]
Beispiel #13
0
    def __init__(self):
        super().__init__(start_state=DoubleTouchTracker.State.start)

        for state in DoubleTouchTracker.State:
            self.add_state(state)

        # FIXME: is it only restart plays?
        self.add_transition(
            DoubleTouchTracker.State.start,
            DoubleTouchTracker.State.restart_play_began, lambda:
            (main.root_play().play != None and main.root_play().play.__class__.
             is_restart() and main.game_state().is_our_restart()),
            'we start running an offensive restart play')

        self.add_transition(
            DoubleTouchTracker.State.restart_play_began,
            DoubleTouchTracker.State.kicking,
            lambda: any(bot.has_ball() for bot in main.our_robots()),
            'one of our bots has the ball')

        self.add_transition(DoubleTouchTracker.State.kicking,
                            DoubleTouchTracker.State.kicker_forbidden,
                            lambda: not self.kicker_has_possession(),
                            'kicker kicks or fumbles ball')

        self.add_transition(DoubleTouchTracker.State.kicker_forbidden,
                            DoubleTouchTracker.State.other_robot_touched,
                            lambda: self.other_robot_touching_ball(),
                            'another robot has touched the ball')
 def kicker_has_possession(self):
     if self.kicker_shell_id != None:
         for bot in main.our_robots():
             if bot.shell_id() == self.kicker_shell_id:
                 # we use two methods here because the ball-sensor output is often jittery
                 return bot.has_ball() or evaluation.ball.robot_has_ball(bot)
     return False
Beispiel #15
0
    def __init__(self):
        super().__init__(continuous=True)

        self.ball_pos = self.get_ball_pos()

        self.add_state(FollowBall.State.ball_moved,
                       behavior.Behavior.State.running)

        self.add_state(FollowBall.State.nothing,
                       behavior.Behavior.State.running)

        ball_has_moved = (lambda: (self.get_ball_pos().x != self.ball_pos.x) or
                          (self.get_ball_pos().y != self.ball_pos.y))
        #in_ball_radius = (lambda : False)
        print(main.our_robots()[1].shell_id)

        self.add_transition(behavior.Behavior.State.start,
                            self.State.nothing, lambda: True, 'immediately')

        self.add_transition(self.State.ball_moved,
                            self.State.nothing, lambda: True,
                            'ball staying still')

        self.add_transition(self.State.nothing, self.State.ball_moved,
                            ball_has_moved, 'ball moved')
Beispiel #16
0
    def add_shot_obstacle(self, excluded_robots=[]):
        pt = self.aim_target_point
        if pt != None:
            # segment centered at the target point that's @width wide and perpendicular to the shot
            shot_perp = (main.ball().pos - pt).perp_ccw().normalized()

            # Make the shot triangle obstacle a fixed width at the end unless
            # we're aiming at a segment. In that case, just use the length of
            # the segment.
            width = 0.5
            if isinstance(self.target, robocup.Segment):
                width = self.target.length()

            a = pt + shot_perp * width / 2.0
            b = pt - shot_perp * width / 2.0

            # build the obstacle polygon
            obs = robocup.Polygon()
            obs.add_vertex(main.ball().pos)
            obs.add_vertex(a)
            obs.add_vertex(b)

            # tell the bots to not go there
            for bot in main.our_robots():
                if bot not in excluded_robots + [self.robot]:
                    bot.add_local_obstacle(obs)
    def __init__(self):
        super().__init__(start_state=DoubleTouchTracker.State.start)

        for state in DoubleTouchTracker.State:
            self.add_state(state)

        # FIXME: is it only restart plays?
        self.add_transition(
            DoubleTouchTracker.State.start,
            DoubleTouchTracker.State.restart_play_began,
            lambda: (main.root_play().play is not None and
                     main.root_play().play.__class__.is_restart() and
                     main.game_state().is_our_restart()),
            'we start running an offensive restart play')

        self.add_transition(
            DoubleTouchTracker.State.restart_play_began,
            DoubleTouchTracker.State.kicking,
            lambda: ((any(self._touching_ball(bot) for bot in main.our_robots())) or
                     main.game_state().is_playing()) and not main.game_state().is_placement(),
            'one of our bots has the ball or the ball was kicked')

        self.add_transition(DoubleTouchTracker.State.kicking,
                            DoubleTouchTracker.State.kicker_forbidden,
                            # The ball is no longer in restart, we have begun playing
                            (lambda: main.game_state().is_playing() or
                             # We aren't in a restart anymore
                             main.root_play().play is None or
                             not main.root_play().play.__class__.is_restart()),
                            'ball has moved and is now in play')

        self.add_transition(DoubleTouchTracker.State.kicker_forbidden,
                            DoubleTouchTracker.State.other_robot_touched,
                            lambda: self.other_robot_touching_ball(),
                            'another robot has touched the ball')
    def execute_pass_set(self):
        # gets the best position to travel to for ball reception
        best_point = self.passing_point

        # sets the second point
        alt_point, value2 = evaluation.passing_positioning.eval_best_receive_point(
                self.passing_point,
                main.our_robots(), AdvanceZoneMidfielder.FIELD_POS_WEIGHTS,
                AdvanceZoneMidfielder.NELDER_MEAD_ARGS,
                AdvanceZoneMidfielder.PASSING_WEIGHTS)

        # check for futile position i.e the alternate position is in the way of a shot from best position
        if self.in_shot_triangle(best_point, alt_point):
            alt_point = self.remove_obstruction(best_point, alt_point)

        points = [best_point, alt_point]
        # moves the robots and assigns information
        for i in range(len(points)):
            if (self.moves[i] is None):
                self.moves[i] = skills.move.Move(points[i])
                self.add_subbehavior(
                    self.moves[i],
                    self.names[i],
                    required=False,
                    priority=self.priorities[i])
            else:
                self.moves[i].pos = points[i]
    def other_robot_touching_ball(self):
        max_radius = constants.Robot.Radius + constants.Ball.Radius + 0.03
        for bot in list(main.our_robots()) + list(main.their_robots()):
            if bot.visible and (not bot.is_ours() or not bot.shell_id() == self.kicker_shell_id):
                if bot.pos.near_point(main.ball().pos, max_radius):
                    return True

        return False
Beispiel #20
0
 def kicker_has_possession(self):
     if self.kicker_shell_id != None:
         for bot in main.our_robots():
             if bot.shell_id() == self.kicker_shell_id:
                 # we use two methods here because the ball-sensor output is often jittery
                 return bot.has_ball() or evaluation.ball.robot_has_ball(
                     bot)
     return False
Beispiel #21
0
    def other_robot_touching_ball(self):
        max_radius = constants.Robot.Radius + constants.Ball.Radius + 0.03
        for bot in list(main.our_robots()) + list(main.their_robots()):
            if bot.visible and (not bot.is_ours()
                                or not bot.shell_id() == self.kicker_shell_id):
                if bot.pos.near_point(main.ball().pos, max_radius):
                    return True

        return False
    def execute_running(self):
        # abort if we can't see the ball
        if not main.ball().valid:
            return


        ball_pos = main.ball().pos


        # the closest of their bots to the ball is their kicker
        their_kicker = min(main.their_robots(), key=lambda opp: opp.pos.dist_to(ball_pos))


        # we build an array of (OpponentRobot, float distToClosestOfOurBots) tuples
        # we'll use these in a sec to assign our marking robots
        open_opps_and_dists = []
        for opp in main.their_robots():
            # ignore their kicker
            if opp == their_kicker: continue

            ball_dist = opp.pos.dist_to(ball_pos)

            # see if the opponent is close enough to the ball for us to care
            # if it is, we record the closest distance from one of our robots to it
            if ball_dist < 3.0:
                # which of our robots is closest to this opponent
                closest_self_dist = min([bot.pos.dist_to(opp.pos) for bot in main.our_robots()])
                open_opps_and_dists.append( (opp, closest_self_dist) )


        # Decide what each marking robot should do
        # @open_opps contains the robots we want to mark (if any)
        # any robot that isn't assigned a mark_robot will move towards the ball
        for i, mark_i in enumerate(self.marks):
            if mark_i.robot != None:
                if i < len(open_opps_and_dists):
                    # mark the opponent
                    mark_i.mark_robot = open_opps_and_dists[i][0]
                else:
                    pass
                    # NOTE: the old code ran these motion commands INSTEAD of running the mark command
                    # we could do that, but it'd require removing the subbehavior and re-adding a move or something...

                    # # move towards the ball and face it, but don't get within field center's radius
                    # pos = mark_i.robot.pos
                    # target = pos + (ball_pos - pos).normalized() * (ball_pos.dist_to(pos) - constants.Field.CenterRadius)
                    
                    # mark_i.robot.move(target)
                    # mark_i.face(ball_pos)


        # tell the marking robots to avoid eachother more than normal
        for i, mark_i in enumerate(self.marks):
            for j, mark_j in enumerate(self.marks):
                if i == j: continue
                if mark_i.robot != None and mark_j.robot != None:
                    mark_i.robot.set_avoid_teammate_radius(mark_j.robot.shell_id(), 0.5)
Beispiel #23
0
    def execute_running(self):
        super().execute_running()
        # abort if we can't see the ball
        if not main.ball().valid:
            return

        ball_pos = main.ball().pos

        # the closest of their bots to the ball is their kicker
        their_kicker = min(main.their_robots(),
                           key=lambda opp: opp.pos.dist_to(ball_pos))

        # we build an array of (OpponentRobot, float distToClosestOfOurBots) tuples
        # we'll use these in a sec to assign our marking robots
        open_opps_and_dists = []
        for opp in main.their_robots():
            # ignore their kicker
            if opp == their_kicker: continue

            ball_dist = opp.pos.dist_to(ball_pos)

            # see if the opponent is close enough to the ball for us to care
            # if it is, we record the closest distance from one of our robots to it
            if ball_dist < 3.0:
                # which of our robots is closest to this opponent
                closest_self_dist = min(
                    [bot.pos.dist_to(opp.pos) for bot in main.our_robots()])
                open_opps_and_dists.append((opp, closest_self_dist))

        # Decide what each marking robot should do
        # @open_opps contains the robots we want to mark (if any)
        # any robot that isn't assigned a mark_robot will move towards the ball
        for i, mark_i in enumerate(self.marks):
            if mark_i.robot != None:
                if i < len(open_opps_and_dists):
                    # mark the opponent
                    mark_i.mark_robot = open_opps_and_dists[i][0]
                else:
                    pass
                    # NOTE: the old code ran these motion commands INSTEAD of running the mark command
                    # we could do that, but it'd require removing the subbehavior and re-adding a move or something...

                    # # move towards the ball and face it, but don't get within field center's radius
                    # pos = mark_i.robot.pos
                    # target = pos + (ball_pos - pos).normalized() * (ball_pos.dist_to(pos) - constants.Field.CenterRadius)

                    # mark_i.robot.move(target)
                    # mark_i.face(ball_pos)

                    # tell the marking robots to avoid eachother more than normal
        for i, mark_i in enumerate(self.marks):
            for j, mark_j in enumerate(self.marks):
                if i == j: continue
                if mark_i.robot != None and mark_j.robot != None:
                    mark_i.robot.set_avoid_teammate_radius(
                        mark_j.robot.shell_id(), 0.5)
 def execute_kicker_forbidden(self):
     bot = None
     for b in main.our_robots():
         if b.shell_id() == self.kicker_shell_id:
             bot = b
             break
     if self.kicker_shell_id and bot:
         main.system_state().draw_text(
             "Blocking double touch!", bot.pos,
             constants.Colors.Red, "Double Touches")
Beispiel #25
0
 def execute_kicker_forbidden(self):
     bot = None
     for b in main.our_robots():
         if b.shell_id() == self.kicker_shell_id:
             bot = b
             break
     if self.kicker_shell_id and bot:
         main.debug_drawer().draw_text("Blocking double touch!", bot.pos,
                                       constants.Colors.Red,
                                       "Double Touches")
Beispiel #26
0
 def other_robot_touching_ball(self):
     for bot in filter(lambda bot: bot.visible,
                       list(main.our_robots()) + list(main.their_robots())):
         if (bot.is_ours() and bot.has_ball()
                 and bot.shell_id() != self.kicker_shell_id):
             return True
         if ((bot.shell_id() != self.kicker_shell_id or not bot.is_ours())
                 and self._bot_in_radius(bot)):
             return True
     return False
Beispiel #27
0
 def score(cls):
     gs = main.game_state()
     if len(main.our_robots()) < 5:
         return float("inf")
     if (gs.is_ready_state() and gs.is_our_free_kick() and
             main.ball().pos.y > (constants.Field.Length - 1.2) and
             abs(main.ball().pos.x) > .6):
         return 0
     else:
         return 10000
 def other_robot_touching_ball(self):
     for bot in filter(lambda bot: bot.visible,
                       list(main.our_robots()) + list(main.their_robots())):
         if (bot.is_ours() and
             bot.has_ball() and
                 bot.shell_id() != self.kicker_shell_id):
             return True
         if ((bot.shell_id() != self.kicker_shell_id or
              not bot.is_ours()) and
                 self._bot_in_radius(bot)):
             return True
     return False
    def within_range(self):
        shortest_opp_dist = 10
        shortest_our_dist = 10
        # TODO: Do some sort of prediction as the ball moves
        target_pos = main.ball().pos

        # Find closest opponent robot
        for bot in main.their_robots():
            dist = self.estimate_path_length(bot.pos, target_pos,
                                             main.our_robots())
            if (dist < shortest_opp_dist):
                shortest_opp_dist = dist

        # Find closest robot on our team
        for bot in main.our_robots():
            dist = self.estimate_path_length(bot.pos, target_pos,
                                             main.their_robots())
            if (dist < shortest_our_dist):
                shortest_our_dist = dist

        # Greater than 1 when we are further away
        return shortest_our_dist < shortest_opp_dist * 1.05
    def on_enter_passing(self):
        self.remove_all_subbehaviors()
        #either pass to striker or distracter depending on shot chance        
        pass_to_distract_chance = evaluation.passing.eval_pass(
            main.ball().pos, self.Distraction_recieve_pass_point,
            main.our_robots())
        pass_to_striker_chance = evaluation.passing.eval_pass(
            main.ball().pos, self.striker_point, main.our_robots())
        shot_of_striker_chance = evaluation.shooting.eval_shot(
            self.striker_point, main.our_robots())

        if pass_to_distract_chance <= pass_to_striker_chance * shot_of_striker_chance:
            pass_striker_instead = True

        self.add_subbehavior(
            skills.move.Move(self.striker_point),
            'make striker stay again',
            required=True)
        self.add_subbehavior(
            tactics.coordinated_pass.CoordinatedPass(
                self.Distraction_recieve_pass_point),
            'distract pass',
            required=True)
Beispiel #31
0
    def on_enter_kick(self):
        OurFreeKick.Running = False
        kicker = skills.line_kick.LineKick()
        kicker.use_chipper = True
        kicker.min_chip_range = OurFreeKick.MinChipRange
        kicker.max_chip_range = OurFreeKick.MaxChipRange

        kicker.target = self.gap

        shooting_line = robocup.Line(main.ball().pos, self.gap)

        # If we are at their goal, shoot full power
        if shooting_line.segment_intersection(
                constants.Field.TheirGoalSegment) is not None:
            kicker.kick_power = self.FullKickPower
        # If we are aiming in the forward direction and not at one of the "endzones", shoot full power
        elif (shooting_line.line_intersection(constants.Field.FieldBorders[0])
              or
              shooting_line.line_intersection(constants.Field.FieldBorders[2])
              and self.gap.y - main.ball().pos.y > 0):
            kicker.kick_power = self.FullKickPower
        # If we are probably aiming down the field, slowly kick so we dont carpet
        else:
            kicker.kick_power = self.BumpKickPower

        # Try passing if we are doing an indirect kick
        if self.indirect:
            pass
            # Check for valid target pass position
            if self.receive_value != 0 and len(main.our_robots()) >= 5:
                self.remove_all_subbehaviors()
                pass_behavior = tactics.coordinated_pass.CoordinatedPass(
                    self.receive_pt,
                    None, (kicker, lambda x: True),
                    receiver_required=False,
                    kicker_required=False,
                    prekick_timeout=7,
                    use_chipper=True)
                # We don't need to manage this anymore
                self.add_subbehavior(pass_behavior, 'kicker')
            else:
                kicker.target = (self.pos_up_field)
                self.add_subbehavior(kicker,
                                     'kicker',
                                     required=False,
                                     priority=5)
        else:
            kicker.target = constants.Field.TheirGoalSegment
            self.add_subbehavior(kicker, 'kicker', required=False, priority=5)
Beispiel #32
0
    def on_enter_clearing(self):
        # Line kick with chip
        # Choose most open area / Best pass, weight forward
        # Decrease weight on sides of field due to complexity of settling
        self.pass_target, self.pass_score = evaluation.passing_positioning.eval_best_receive_point(
            main.ball().pos, main.our_robots(),
            AdaptiveFormation.FIELD_POS_WEIGHTS,
            AdaptiveFormation.NELDER_MEAD_ARGS,
            AdaptiveFormation.PASSING_WEIGHTS)

        clear = skills.pivot_kick.PivotKick()
        clear.target = self.pass_target
        clear.aim_params['desperate_timeout'] = 3
        clear.use_chipper = True
        self.add_subbehavior(clear, 'clear', required=False)
Beispiel #33
0
def our_robot_with_ball():
    closest_bot, closest_dist = None, float("inf")
    for bot in main.our_robots():
        if bot.visible:
            dist = (bot.pos - main.ball().pos).mag()
            if dist < closest_dist:
                closest_bot, closest_dist = bot, dist

    if closest_bot == None:
        return None
    else:
        if robot_has_ball(closest_bot):
            return closest_bot
        else:
            return None
Beispiel #34
0
    def on_enter_start(self):
        # if we have too many robots isolate one of the robots so they don't help in the play
        goalie = main.root_play(
        ).goalie_id  #.system_state().game_state.get_goalie_id()
        print(goalie)
        numRobots = len(main.our_robots()) - 4
        if (goalie != None):
            numRobots = numRobots - 1

        for i in range(numRobots):
            iso = skills.move.Move(
                robocup.Point(-constants.Field.Width / 2 + self.bot_buffer * i,
                              0))
            self.add_subbehavior(iso,
                                 'iso' + str(i),
                                 required=True,
                                 priority=1)
Beispiel #35
0
    def on_enter_move(self):
        self.move_pos = self.calc_move_pos()

        self.pos_up_field = robocup.Point(main.ball().pos.x,
                                          constants.Field.Length * .75)
        if (main.ball().pos.y > constants.Field.Length / 2):
            sign = (main.ball().pos.x) / abs(main.ball().pos.x) * -1
            x = sign * constants.Field.Width * 3 / 8
            y = max(constants.Field.Length * .75,
                    (main.ball().pos.y + constants.Field.Length) * 0.5)
            self.pos_up_field = robocup.Point(x, y)

        if self.indirect and (self.receive_value == 0
                              and len(main.our_robots()) >= 5):
            self.add_subbehavior(skills.move.Move(self.pos_up_field),
                                 'receiver',
                                 required=False,
                                 priority=5)
Beispiel #36
0
    def add_shot_obstacle(self, excluded_robots=[]):
        pt = self.aim_target_point
        if pt != None:
            # segment centered at the target point that's @width wide and perpendicular to the shot
            shot_perp = (main.ball().pos - pt).perp_ccw().normalized()
            width = 0.2
            a = pt + shot_perp * width / 2.0
            b = pt - shot_perp * width / 2.0

            # build the obstacle polygon
            obs = robocup.Polygon()
            obs.add_vertex(main.ball().pos)
            obs.add_vertex(a)
            obs.add_vertex(b)

            # tell the bots to not go there
            for bot in main.our_robots():
                if bot not in excluded_robots + [self.robot]:
                    bot.add_local_obstacle(obs)
Beispiel #37
0
    def add_shot_obstacle(self, excluded_robots=[]):
        pt = self.aim_target_point
        if pt != None:
            # segment centered at the target point that's @width wide and perpendicular to the shot
            shot_perp = (main.ball().pos - pt).perp_ccw().normalized()
            width = 0.2
            a = pt + shot_perp * width / 2.0
            b = pt - shot_perp * width / 2.0

            # build the obstacle polygon
            obs = robocup.Polygon()
            obs.add_vertex(main.ball().pos)
            obs.add_vertex(a)
            obs.add_vertex(b)

            # tell the bots to not go there
            for bot in main.our_robots():
                if bot not in excluded_robots + [self.robot]:
                    bot.add_local_obstacle(obs)
Beispiel #38
0
    def execute_shooting(self):
        kicker = skills.line_kick.LineKick()  #skills.pivot_kick.PivotKick()
        #aim for goal segmant
        win_eval = robocup.WindowEvaluator(main.context())

        for g in main.our_robots():
            win_eval.add_excluded_robot(g)

        windows, window = win_eval.eval_pt_to_opp_goal(main.ball().pos)
        if (window != None):
            kicker.target = window.segment.center()
        else:
            kicker.target = constants.Field.TheirGoalSegment

        kicker.aim_params['desperate_timeout'] = 8
        if (not self.has_subbehavior_with_name('kicker')
                or self.subbehavior_with_name('kicker').is_done_running()):
            self.remove_all_subbehaviors()
            self.add_subbehavior(kicker, 'kicker', required=False, priority=5)
Beispiel #39
0
        def recalculate_threat_shot(threat_index):
            if not isinstance(threat_index, int):
                raise TypeError("threat_index should be an int")

            # ignore all of our robots
            excluded_robots = list(main.our_robots())

            # behaviors before this threat are counted as obstacles in their TARGET position (where we've
            # assigned them to go, not where they are right now)
            hypothetical_obstacles = []
            for t in threats[0:threat_index]:
                hypothetical_obstacles.extend(map(lambda bhvr: bhvr.move_target, t.assigned_handlers))

            threat = threats[threat_index]
            threat.shot_chance, threat.best_shot_window = evaluation.shot.eval_shot(
                pos=threat.pos,
                target=constants.Field.OurGoalSegment,
                windowing_excludes=excluded_robots,
                hypothetical_robot_locations=[],
                debug=False)
Beispiel #40
0
        def recalculate_threat_shot(threat_index):
            if not isinstance(threat_index, int):
                raise TypeError("threat_index should be an int")

            # ignore all of our robots
            excluded_robots = list(main.our_robots())

            # behaviors before this threat are counted as obstacles in their TARGET position (where we've
            # assigned them to go, not where they are right now)
            hypothetical_obstacles = []
            for t in threats[0:threat_index]:
                hypothetical_obstacles.extend(
                    map(lambda bhvr: bhvr.move_target, t.assigned_handlers))

            threat = threats[threat_index]
            threat.shot_chance, threat.best_shot_window = evaluation.shot.eval_shot(
                pos=threat.pos,
                target=constants.Field.OurGoalSegment,
                windowing_excludes=excluded_robots,
                hypothetical_robot_locations=[],
                debug=False)
    def execute_running(self):
        super().execute_running()
        # abort if we can't see the ball
        if not main.ball().valid:
            return

        ball_pos = main.ball().pos

        # the closest of their bots to the ball is their kicker
        their_kicker = min(main.their_robots(),
                           key=lambda opp: opp.pos.dist_to(ball_pos))

        # we build an array of (OpponentRobot, float distToClosestOfOurBots) tuples
        # we'll use these in a sec to assign our marking robots
        open_opps_and_dists = []
        for opp in main.their_robots():
            # ignore their kicker
            if opp == their_kicker: continue

            ball_dist = opp.pos.dist_to(ball_pos)

            # see if the opponent is close enough to the ball for us to care
            # if it is, we record the closest distance from one of our robots to it
            if ball_dist < 3.0:
                # which of our robots is closest to this opponent
                closest_self_dist = min(
                    [bot.pos.dist_to(opp.pos) for bot in main.our_robots()])
                open_opps_and_dists.append((opp, closest_self_dist))

        # Decide what each marking robot should do
        # @open_opps contains the robots we want to mark (if any)
        # any robot that isn't assigned a mark_robot will move towards the ball
        for i, mark_i in enumerate(self.marks):
            if mark_i.robot != None:
                if i < len(open_opps_and_dists):
                    # mark the opponent
                    mark_i.mark_robot = open_opps_and_dists[i][0]
                else:
                    pass
Beispiel #42
0
        def recalculate_threat_shot(threat_index):
            if not isinstance(threat_index, int):
                raise TypeError("threat_index should be an int")

            # ignore all of our robots
            excluded_robots = list(main.our_robots())

            # behaviors before this threat are counted as obstacles in their TARGET position (where we've
            # assigned them to go, not where they are right now)
            hypothetical_obstacles = []
            for t in threats[0:threat_index]:
                hypothetical_obstacles.extend(map(lambda bhvr: bhvr.move_target, t.assigned_handlers))

            threat = threats[threat_index]
            self.win_eval.excluded_robots.clear()
            for r in excluded_robots:
                self.win_eval.add_excluded_robot(r)
            _, threat.best_shot_window = self.win_eval.eval_pt_to_our_goal(threat.pos)
            if threat.best_shot_window is not None:
                threat.shot_chance = threat.best_shot_window.shot_success
            else:
                threat.shot_chance = 0.0
    def on_enter_dribbling(self):
        self.dribbler = skills.dribble.Dribble()
        self.dribble_start_pt = main.ball().pos

        # Dribbles toward the best receive point

        self.dribbler.pos, _ = evaluation.passing_positioning.eval_best_receive_point(
            main.ball().pos,
            main.our_robots(), AdaptiveFormation.FIELD_POS_WEIGHTS,
            AdaptiveFormation.NELDER_MEAD_ARGS,
            AdaptiveFormation.DRIBBLING_WEIGHTS)

        self.add_subbehavior(self.dribbler, 'dribble', required=True)

        self.check_dribbling_timer = 0

        if (not self.has_subbehavior_with_name('midfielders')):
            self.midfielders = tactics.advance_zone_midfielder.AdvanceZoneMidfielder(
            )
            self.add_subbehavior(
                self.midfielders, 'midfielders', required=False, priority=10)
        self.midfielders.kick = False
    def execute_running(self):
        super().execute_running()
        # abort if we can't see the ball
        if not main.ball().valid:
            return

        ball_pos = main.ball().pos

        # the closest of their bots to the ball is their kicker
        their_kicker = min(main.their_robots(),
                           key=lambda opp: opp.pos.dist_to(ball_pos))

        # we build an array of (OpponentRobot, float distToClosestOfOurBots) tuples
        # we'll use these in a sec to assign our marking robots
        open_opps_and_dists = []
        for opp in main.their_robots():
            # ignore their kicker
            if opp == their_kicker: continue

            ball_dist = opp.pos.dist_to(ball_pos)

            # see if the opponent is close enough to the ball for us to care
            # if it is, we record the closest distance from one of our robots to it
            if ball_dist < 3.0:
                # which of our robots is closest to this opponent
                closest_self_dist = min([bot.pos.dist_to(opp.pos)
                                         for bot in main.our_robots()])
                open_opps_and_dists.append((opp, closest_self_dist))

        # Decide what each marking robot should do
        # @open_opps contains the robots we want to mark (if any)
        # any robot that isn't assigned a mark_robot will move towards the ball
        for i, mark_i in enumerate(self.marks):
            if mark_i.robot != None:
                if i < len(open_opps_and_dists):
                    # mark the opponent
                    mark_i.mark_robot = open_opps_and_dists[i][0]
                else:
                    pass
Beispiel #45
0
    def __init__(self):
        super().__init__(continuous=True)

        self.debug = False

        self.add_transition(behavior.Behavior.State.start,
                            behavior.Behavior.State.running, lambda: True,
                            'immediately')

        self.marks = []

        if (main.game_state().is_their_direct()):
            self.intercept = (constants.Field.OurGoalSegment.center() -
                              main.ball().pos) * 0.25 + main.ball().pos
            self.add_subbehavior(skills.move.Move(self.intercept),
                                 'intercept direct',
                                 required=False,
                                 priority=5)

        for i in range(3):
            mark_i = skills.mark.Mark()
            mark_i.ratio = 0.7
            self.add_subbehavior(mark_i,
                                 'mark' + str(i),
                                 required=False,
                                 priority=3 - i)
            self.marks.append(mark_i)

        self.kick_eval = robocup.KickEvaluator(main.system_state())
        self.kick_eval.debug = True
        for i, robot in enumerate(main.our_robots()):
            self.kick_eval.add_excluded_robot(robot)

        for i, robot in enumerate(main.their_robots()):
            self.kick_eval.add_excluded_robot(robot)

        their_kicker = min(main.their_robots(),
                           key=lambda opp: opp.pos.dist_to(main.ball().pos))
        self.kick_eval.add_excluded_robot(their_kicker)
Beispiel #46
0
    def on_enter_dribbling(self):
        self.dribbler = skills.dribble.Dribble()
        self.dribble_start_pt = main.ball().pos

        # Dribbles toward the best receive point

        self.dribbler.pos, _ = evaluation.passing_positioning.eval_best_receive_point(
            main.ball().pos, main.our_robots(),
            AdaptiveFormation.FIELD_POS_WEIGHTS,
            AdaptiveFormation.NELDER_MEAD_ARGS,
            AdaptiveFormation.DRIBBLING_WEIGHTS)

        self.add_subbehavior(self.dribbler, 'dribble', required=True)

        self.check_dribbling_timer = 0

        if (not self.has_subbehavior_with_name('midfielders')):
            self.midfielders = tactics.simple_zone_midfielder.SimpleZoneMidfielder(
            )
            self.add_subbehavior(self.midfielders,
                                 'midfielders',
                                 required=False,
                                 priority=10)
Beispiel #47
0
    def __init__(self):
        super().__init__(start_state=DoubleTouchTracker.State.start)

        for state in DoubleTouchTracker.State:
            self.add_state(state)

        # FIXME: is it only restart plays?
        self.add_transition(
            DoubleTouchTracker.State.start,
            DoubleTouchTracker.State.restart_play_began, lambda:
            (main.root_play().play is not None and main.root_play().play.
             __class__.is_restart() and main.game_state().is_our_restart()),
            'we start running an offensive restart play')

        self.add_transition(
            DoubleTouchTracker.State.restart_play_began,
            DoubleTouchTracker.State.kicking, lambda: (
                (any(self._touching_ball(bot)
                     for bot in main.our_robots())) or main.game_state(
                     ).is_playing()) and not main.game_state().is_placement(),
            'one of our bots has the ball or the ball was kicked')

        self.add_transition(
            DoubleTouchTracker.State.kicking,
            DoubleTouchTracker.State.kicker_forbidden,
            # The ball is no longer in restart, we have begun playing
            (
                lambda: main.game_state().is_playing() or
                # We aren't in a restart anymore
                main.root_play().play is None or not main.root_play().play.
                __class__.is_restart()),
            'ball has moved and is now in play')

        self.add_transition(DoubleTouchTracker.State.kicker_forbidden,
                            DoubleTouchTracker.State.other_robot_touched,
                            lambda: self.other_robot_touching_ball(),
                            'another robot has touched the ball')
Beispiel #48
0
    def get_threat_list(self, unused_threat_handlers):
        # List of (position, score, Robot/None)
        threats = []
        potential_threats = main.their_robots()

        # find the primary threat
        # if the ball is not moving OR it's moving towards our goal, it's the primary threat
        # if it's moving, but not towards our goal, the primary threat is the robot on their team most likely to catch it
        if (main.ball().vel.mag() > 0.4):
            if evaluation.ball.is_moving_towards_our_goal():
                # Add tuple of pos and score
                threats.append((main.ball().pos, 1, None))
            else:
                # Get all potential receivers
                potential_receivers = []
                for opp in potential_threats:
                    if self.estimate_potential_recievers_score(opp) == 1:
                        potential_receivers.append((opp.pos, 1, opp))

                if len(potential_receivers) > 0:
                    # Add best receiver to threats
                    # TODO Calc shot chance
                    best_tuple = min(potential_receivers,
                                     key=lambda rcrv_tuple: rcrv_tuple[1])
                    threats.append((best_tuple[0], .81, best_tuple[2]))
                else:
                    # Just deal with ball if no recievers
                    threats.append((main.ball().pos, .9, None))
        else:
            # Assume opp is dribbling ball
            if not constants.Field.OurGoalZoneShape.contains_point(
                    main.ball().pos):
                # TODO: Calc shot chance
                threats.append((main.ball().pos, 1, None))

        # if there are threats, check pass and shot chances
        # If the first item is not a ball, it is most likely a pass
        if len(threats) > 0 and threats[0][0] != main.ball().pos:
            for opp in potential_threats:

                # Exclude robots that have been assigned already
                excluded_bots = []
                for r in map(lambda bhvr: bhvr.robot, unused_threat_handlers):
                    excluded_bots.append(r)

                threats.append((opp.pos, self.estimate_risk_score(
                    opp, excluded_bots), opp))
        else:
            for opp in potential_threats:

                # Exclude all robots
                self.kick_eval.excluded_robots.clear()
                self.kick_eval.add_excluded_robot(opp)
                for r in main.our_robots():
                    self.kick_eval.add_excluded_robot(r)

                point, shotChance = self.kick_eval.eval_pt_to_our_goal(opp.pos)

                # Note: 0.5 is a bullshit value
                threats.append((opp.pos, 0.5 * shotChance, opp))

        # Prevent threats from being below our goal line (causes incorrect pos)
        def _adjust_pt(threat):
            pt = threat[0]
            pt.y = max(pt.y, 0.1)
            return (pt,) + threat[1:]

        threats = list(map(_adjust_pt, threats))

        return threats
    def __init__(self):
        super().__init__(continuous=False)

        for s in AdaptiveFormation.State:
            self.add_state(s, behavior.Behavior.State.running)

        # Dribbling skill
        self.dribbler = None
        # Dribble start point
        self.dribble_start_pt = robocup.Point(0, 0)

        # Kicker for a shot
        self.kick = None
        # Controls robots while passes are being set up
        self.midfielders = None

        # State Decision Variables
        self.shot_chance = 0
        self.pass_score = 0
        # Prev State Decision Variables
        self.prev_shot_chance = 0
        self.prev_pass_score = 0
        # Used to keep dribble within rules
        self.check_dribbling_timer = 0
        self.check_dribbling_timer_cutoff = 100

        self.kick_eval = robocup.KickEvaluator(main.system_state())

        for r in main.our_robots():
            self.kick_eval.add_excluded_robot(r)

        # Add transitions
        self.add_transition(behavior.Behavior.State.start,
                            AdaptiveFormation.State.collecting, lambda: True,
                            'immediately')

        self.add_transition(AdaptiveFormation.State.collecting,
                            AdaptiveFormation.State.dribbling, lambda: self.
                            subbehavior_with_name('defend').state == behavior.
                            Behavior.State.completed, 'Ball Collected')

        self.add_transition(
            AdaptiveFormation.State.dribbling, AdaptiveFormation.State.passing,
            lambda: self.dribbler_has_ball() and self.should_pass_from_dribble(
            ) and not self.should_shoot_from_dribble(), 'Passing')

        self.add_transition(
            AdaptiveFormation.State.dribbling,
            AdaptiveFormation.State.shooting, lambda: self.dribbler_has_ball(
            ) and self.should_shoot_from_dribble(), 'Shooting')

        self.add_transition(
            AdaptiveFormation.State.dribbling,
            AdaptiveFormation.State.clearing, lambda: self.dribbler_has_ball(
            ) and self.should_clear_from_dribble(
            ) and not self.should_pass_from_dribble(
            ) and not self.should_shoot_from_dribble(), 'Clearing')

        self.add_transition(
            AdaptiveFormation.State.passing, AdaptiveFormation.State.dribbling,
            lambda: self.subbehavior_with_name(
                'pass').state == behavior.Behavior.State.completed, 'Passed')

        # Reset to collecting when ball is lost at any stage
        self.add_transition(AdaptiveFormation.State.dribbling,
                            AdaptiveFormation.State.collecting, lambda:
                            not self.dribbler_has_ball(), 'Dribble: Ball Lost')
        self.add_transition(
            AdaptiveFormation.State.passing,
            AdaptiveFormation.State.collecting, lambda: self.
            subbehavior_with_name('pass').state == behavior.Behavior.State.
            cancelled or self.subbehavior_with_name('pass').state == behavior.
            Behavior.State.failed, 'Passing: Ball Lost')
        self.add_transition(AdaptiveFormation.State.shooting,
                            AdaptiveFormation.State.collecting, lambda: self.
                            subbehavior_with_name('kick').is_done_running(),
                            'Shooting: Ball Lost / Shot')
        self.add_transition(AdaptiveFormation.State.clearing,
                            AdaptiveFormation.State.collecting, lambda: self.
                            subbehavior_with_name('clear').is_done_running(),
                            'Clearing: Ball Lost')
def estimate_risk_score(pos, ignore_robots=[]):
    # Caches some kick eval functions
    max_time = 1
    max_ball_vel = 8  # m/s per the rules
    est_turn_vel = 8  # rad/s per a random dice roll (Over estimates oppnents abilities)

    kick_eval = robocup.KickEvaluator(main.system_state())

    for r in ignore_robots:
        kick_eval.add_excluded_robot(r)

    _, pass_score = kick_eval.eval_pt_to_robot(main.ball().pos, pos)
    shot_pt, shot_score = kick_eval.eval_pt_to_our_goal(pos)

    # Dist to ball
    ball_pos_vec = pos - main.ball().pos
    dist = ball_pos_vec.mag()
    max_dist = robocup.Point(constants.Field.Width,
                             constants.Field.Length).mag()

    # Closest opp robot
    closest_opp_bot = evaluation.opponent.get_closest_opponent(main.ball().pos)
    delta_angle = ball_pos_vec.angle() - \
                  predict_kick_direction(closest_opp_bot)
    delta_angle = math.atan2(math.sin(delta_angle), math.cos(delta_angle))

    # Underestimates max time to execute on ball
    # Assumes perfect opponent
    time = dist / max_ball_vel + math.fabs(delta_angle) / est_turn_vel
    # Limits to max time so we can invert it later on
    time = min(time, max_time)

    # Center, Dist, Angle
    pos_score = evaluation.field.field_pos_coeff_at_pos(pos, 0.05, 0.3, 0.05,
                                                        False)
    space_coeff = evaluation.field.space_coeff_at_pos(pos, ignore_robots,
                                                      main.our_robots())

    # Delta angle between pass recieve and shot
    delta_angle = ball_pos_vec.angle() - (shot_pt - pos).angle()
    delta_angle = math.atan2(math.sin(delta_angle), math.cos(delta_angle))
    angle_coeff = math.fabs(delta_angle) / math.pi

    # Shot only matters if its a good pass
    # Add pass back in for checking if pass is good (while shot is not)
    #
    # Add in time to weight closer points higher
    #
    # Pos is weighted higher to remove bad positions from calculations
    #
    # Space is weighted in so it is weighted towards lower density areas
    #
    # Delta angle for shot is weighted in so easier shots are weighted higher
    #
    # Distance to the ball squared

    #  Pass, Time, Pos, Space, Angle
    weights = [0.1, 0.1, 2, 0.4, 0.3, 1]
    score = weights[0] * (shot_score * pass_score + pass_score) / 2 + \
            weights[1] * (max_time - time) + \
            weights[2] * pos_score + \
            weights[3] * (1 - space_coeff) + \
            weights[4] * angle_coeff + \
            weights[5] * (1 - dist / max_dist)**2

    return score / sum(weights)
    def eval_pt_to_seg(self, origin, target):
        end = target.delta().magsq()

        # if target is a zero-length segment, there are no windows
        if end == 0:
            return [], None

        if self.debug:
            main.system_state().draw_line(target, constants.Colors.Blue, "Debug")

        windows = [Window(0, end)]

        # apply the obstacles
        bots = filter(lambda bot: bot not in self.excluded_robots and bot.visible, (list(main.our_robots()) + list(main.their_robots())))
        bot_locations = list(map(lambda bot: bot.pos, bots))
        bot_locations.extend(self.hypothetical_robot_locations)
        for pos in bot_locations:
            d = (pos - origin).mag()
            # whether or not we can chip over this bot
            chip_overable = (self.chip_enabled
                            and (d < self.max_chip_range - constants.Robot.Radius)
                            and (d > self.min_chip_range + constants.Robot.Radius))
            if not chip_overable:
                self.obstacle_robot(windows, origin, target, pos)

        # set the segment and angles for each window
        p0 = target.get_pt(0)
        delta = target.delta() / end

        for w in windows:
            w.segment = robocup.Segment(p0 + delta * w.t0, p0 + delta * w.t1)
            w.a0 = (w.segment.get_pt(0) - origin).angle() * constants.RadiansToDegrees
            w.a1 = (w.segment.get_pt(1) - origin).angle() * constants.RadiansToDegrees

        best = max(windows, key=lambda w: w.segment.delta().magsq()) if len(windows) > 0 else None

        if self.debug and best is not None:
            main.system_state().draw_line(best.segment, constants.Colors.Green, "Debug")
            main.system_state().draw_line(robocup.Line(origin, best.segment.center()), constants.Colors.Green, "Debug")

        # # draw the windows if we're in debug mode
        # if self.debug:
        #     for w in windows:
        #         pts = [origin, w.segment.get_pt(0), w.segment.get_pt(1)]
        #         color = (255, 0, 0) if w == best else (0, 255, 0)
        #         main.system_state().draw_polygon(pts, 3, color, "Windows")

        return windows, best
 def we_have_ball(self):
     return any(
         evaluation.ball.robot_has_ball(r) for r in main.our_robots())
 def on_exit_restart_play_began(self):
     for bot in main.our_robots():
         if bot.has_ball():
             self.kicker_shell_id = bot.shell_id()
             return
 def score(cls):
     if (not main.game_state().is_playing()):
         return float("inf")
     if len(main.our_robots()) < 5:
         return float("inf")
     return 10
 def dribbler_has_ball(self):
     return any(evaluation.ball.robot_has_ball(r)
                for r in main.our_robots())