def _find_best_next_target(self, area: Area, old_target_position, player_position: Position, target_to_position: Line): intersections = area.intersect(target_to_position) if intersections: return intersections[0] elif old_target_position == player_position: return area.closest_border_point(old_target_position) else: # The player is already in the forbidden area, so it must go in the opposite direction than the target intersections = area.intersect_with_line(target_to_position) if (intersections[0] - self.player.position).norm < (intersections[1] - self.player.position).norm: return intersections[0] else: return intersections[1]
def _find_best_next_target(self, area: Area, old_target_position, player_position: Position, target_to_position: Line): intersections = area.intersect(target_to_position) if intersections: return intersections[0] elif old_target_position == player_position: return area.closest_border_point(old_target_position) else: # The player is already in the forbidden area, so it must go in the opposite direction than the target intersections = area.intersect_with_line(target_to_position) if (intersections[0] - self.player.position).norm < ( intersections[1] - self.player.position).norm: return intersections[0] else: return intersections[1]
def __init__(self, game_state: GameState, player: Player, target: Optional[Pose]=None, args: Optional[List[Any]]=None, forbidden_areas: Optional[List[Area]]=None): self.logger = logging.getLogger(self.__class__.__name__) assert isinstance(player, Player), "Le player doit être un Player, non un '{}'".format(player) assert target is None or isinstance(target, Pose), "La target devrait être une Pose" self.game_state = game_state self.player = player self.player_id = player.id if args is None: self.args = [] else: self.args = args self.current_state = self.halt self.next_state = self.halt self.status_flag = Flags.INIT self.target = target if forbidden_areas is None: field = self.game_state.field # Those limits are for ulaval local only areas = field.border_limits areas += [ self.field.behind_our_goal_line, self.field.behind_their_goal_line] #areas = [] self.forbidden_areas = [Area.pad(area, KEEPOUT_DISTANCE_FROM_GOAL) for area in areas] self.forbidden_areas += [self.game_state.field.their_goal_forbidden_area, self.game_state.field.our_goal_forbidden_area] else: self.forbidden_areas = forbidden_areas
def __init__( self, game_state: GameState, player: Player, target: Pose = Pose(), penalty_kick=False, args: List[str] = None, ): forbidden_area = [ Area.pad(game_state.field.their_goal_area, KEEPOUT_DISTANCE_FROM_GOAL) ] super().__init__(game_state, player, target, args, forbidden_areas=forbidden_area) self.current_state = self.defense self.next_state = self.defense self.target = Pose( self.game_state.field.our_goal, np.pi) # Ignore target argument, always go for our goal self.go_kick_tactic = None # Used by clear self.last_intersection = None # For debug self.OFFSET_FROM_GOAL_LINE = Position(ROBOT_RADIUS + 10, 0) self.GOAL_LINE = self.game_state.field.our_goal_line
def _update_field_const(self): self.our_goal = Position(self.our_goal_x, 0) self.our_goal_pose = Pose(self.our_goal, 0) self.their_goal = Position(self.their_goal_x, 0) self.their_goal_pose = Pose(self.their_goal, 0) p1 = self.field_lines["RightPenaltyStretch"].p1 p2 = self.field_lines["RightPenaltyStretch"].p2 p3 = self.field_lines["RightFieldLeftPenaltyStretch"].p1 p4 = self.field_lines["RightFieldLeftPenaltyStretch"].p2 self.our_goal_area = Area.from_4_point(p1, p2, p3, p4) self.their_goal_area = Area.flip_x(self.our_goal_area) self.goal_line = Line(p1=Position(self.our_goal_x, +self.goal_width / 2), p2=Position(self.our_goal_x, -self.goal_width / 2)) self.our_goal_line = Line(p1=Position(self.our_goal_x, +self.goal_width / 2), p2=Position(self.our_goal_x, -self.goal_width / 2)) self.their_goal_line = Line(p1=Position(self.their_goal_x, +self.goal_width / 2), p2=Position(self.their_goal_x, -self.goal_width / 2)) self.behind_our_goal_line = Area.from_limits(self.our_goal_area.top, self.our_goal_area.bottom, self.our_goal_area.right + 50 * self.goal_depth, self.our_goal_area.left) self.behind_their_goal_line = Area.flip_x(self.behind_our_goal_line) self.free_kick_avoid_area = Area.pad(self.their_goal_area, INDIRECT_KICK_OFFSET + KEEPOUT_DISTANCE_FROM_GOAL) self.our_goal_forbidden_area = Area.pad(self.our_goal_area, KEEPOUT_DISTANCE_FROM_GOAL) self.their_goal_forbidden_area = Area.pad(self.their_goal_area, KEEPOUT_DISTANCE_FROM_GOAL) self.center = Position(0, 0)
def _is_ball_safe_to_kick(self): # Since defender can not kick the ball while inside the goal there are position where the ball is unreachable # The goalee must leave the goal area and kick the ball goal_area = self.game_state.field.our_goal_area width = KEEPOUT_DISTANCE_FROM_GOAL + ROBOT_DIAMETER area_in_front_of_goal = Area.from_limits(goal_area.top, goal_area.bottom, goal_area.left, goal_area.left - width) return self.game_state.field.is_ball_in_our_goal_area() or \ area_in_front_of_goal.point_inside(self.game_state.ball.position) and self._no_enemy_around_ball()
def border_limits(self): top_area = Area.from_limits(self.top + 100 * self.boundary_width, self.top + self.boundary_width, self.right + 100 * self.boundary_width, self.left - 100 * self.boundary_width) bottom_area = Area.from_limits(self.bottom - self.boundary_width, self.bottom - 100 * self.boundary_width, self.right + 100 * self.boundary_width, self.left - 100 * self.boundary_width) right_area = Area.from_limits(self.top + 100 * self.boundary_width, self.bottom - 100 * self.boundary_width, self.right + 100 * self.boundary_width, self.right + self.boundary_width) left_area = Area.from_limits(self.top + 100 * self.boundary_width, self.bottom - 100 * self.boundary_width, self.left - self.boundary_width, self.left - 100 * self.boundary_width) return [top_area, bottom_area, right_area, left_area]
def __init__(self, game_state: GameState, player: Player, target: Pose=Pose(), penalty_kick=False, args: List[str]=None,): forbidden_area = [Area.pad(game_state.field.their_goal_area, KEEPOUT_DISTANCE_FROM_GOAL)] super().__init__(game_state, player, target, args, forbidden_areas=forbidden_area) self.current_state = self.defense self.next_state = self.defense self.target = Pose(self.game_state.field.our_goal, np.pi) # Ignore target argument, always go for our goal self.go_kick_tactic = None # Used by clear self.last_intersection = None # For debug self.OFFSET_FROM_GOAL_LINE = Position(ROBOT_RADIUS + 10, 0) self.GOAL_LINE = self.game_state.field.our_goal_line
def __init__(self, game_state: GameState, player: Player, target: Optional[Pose] = None, args: Optional[List[Any]] = None, forbidden_areas: Optional[List[Area]] = None): self.logger = logging.getLogger(self.__class__.__name__) assert isinstance( player, Player), "Le player doit être un Player, non un '{}'".format( player) assert target is None or isinstance( target, Pose), "La target devrait être une Pose" self.game_state = game_state self.player = player self.player_id = player.id if args is None: self.args = [] else: self.args = args self.current_state = self.halt self.next_state = self.halt self.status_flag = Flags.INIT self.target = target if forbidden_areas is None: field = self.game_state.field # Those limits are for ulaval local only areas = field.border_limits areas += [ self.field.behind_our_goal_line, self.field.behind_their_goal_line ] #areas = [] self.forbidden_areas = [ Area.pad(area, KEEPOUT_DISTANCE_FROM_GOAL) for area in areas ] self.forbidden_areas += [ self.game_state.field.their_goal_forbidden_area, self.game_state.field.our_goal_forbidden_area ] else: self.forbidden_areas = forbidden_areas
def _find_best_player_position(self): if not self.auto_position: return self.target.position if self.is_offense: ball_offset = clamp(self.game_state.ball.position.x, 0, 1000) left = self.game_state.field.their_goal_area.right + ball_offset right = ball_offset else: ball_offset = clamp(self.game_state.ball.position.x, -1000, 0) left = self.game_state.field.our_goal_area.left + ball_offset right = ball_offset idx = self.idx_in_formation len_formation = len(self.robots_in_formation) PADDING = 300 # Add buffer zone between area and the field limit area_height = self.game_state.field.field_width - 2 * PADDING individual_area_size = area_height / len_formation top = idx * individual_area_size - area_height / 2 bot = top + individual_area_size self.area = Area.from_limits(top, bot, right, left) center = self.area.center # Act as if each enemy robot was creating a repulsive force v = Position(0, 0) for enemy in self.game_state.enemy_team.available_players.values(): d = enemy.position - center # Clamp distance norm d = MIN_DIST_FROM_CENTER * normalize(d) if d.norm < MIN_DIST_FROM_CENTER else d # Square of the inverse of the distance, a bit like Newton's law of universal gravitation v -= ATTENUATION * d / (d.norm ** 3) if self.area.point_inside(center + v): return center + v offset_from_center = Line(center, center + v) # The position must stay inside the area limits, so let's find the intersection between our vector and the area area_inter = self.area.intersect(offset_from_center) if area_inter: return area_inter[0] # First intersection return center + v
def _update_field_const(self): self.our_goal = Position(self.our_goal_x, 0) self.our_goal_pose = Pose(self.our_goal, 0) self.their_goal = Position(self.their_goal_x, 0) self.their_goal_pose = Pose(self.their_goal, 0) p1 = self.field_lines["RightPenaltyStretch"].p1 p2 = self.field_lines["RightPenaltyStretch"].p2 p3 = self.field_lines["RightFieldLeftPenaltyStretch"].p1 p4 = self.field_lines["RightFieldLeftPenaltyStretch"].p2 self.our_goal_area = Area.from_4_point(p1, p2, p3, p4) self.their_goal_area = Area.flip_x(self.our_goal_area) self.goal_line = Line(p1=Position(self.our_goal_x, +self.goal_width / 2), p2=Position(self.our_goal_x, -self.goal_width / 2)) self.our_goal_line = Line(p1=Position(self.our_goal_x, +self.goal_width / 2), p2=Position(self.our_goal_x, -self.goal_width / 2)) self.their_goal_line = Line(p1=Position(self.their_goal_x, +self.goal_width / 2), p2=Position(self.their_goal_x, -self.goal_width / 2)) self.behind_our_goal_line = Area.from_limits( self.our_goal_area.top, self.our_goal_area.bottom, self.our_goal_area.right + 50 * self.goal_depth, self.our_goal_area.left) self.behind_their_goal_line = Area.flip_x(self.behind_our_goal_line) self.free_kick_avoid_area = Area.pad( self.their_goal_area, INDIRECT_KICK_OFFSET + KEEPOUT_DISTANCE_FROM_GOAL) self.our_goal_forbidden_area = Area.pad(self.our_goal_area, KEEPOUT_DISTANCE_FROM_GOAL) self.their_goal_forbidden_area = Area.pad(self.their_goal_area, KEEPOUT_DISTANCE_FROM_GOAL) self.center = Position(0, 0)
def test_area_contain_point(): assert Position(100, 300) in Area(Position(0, 500), Position(500, 0))