def __init__(self, game_state: GameState, number_of_players: int = 4): super().__init__(game_state) self.number_of_players = number_of_players self.robots = [] ourgoal = Pose( Position(GameState().const["FIELD_OUR_GOAL_X_EXTERNAL"], 0), 0) self.theirgoal = Pose( Position(GameState().const["FIELD_THEIR_GOAL_X_EXTERNAL"], 0), 0) roles_to_consider = [ Role.FIRST_ATTACK, Role.SECOND_ATTACK, Role.MIDDLE, Role.FIRST_DEFENCE, Role.SECOND_DEFENCE ] goalkeeper = self.game_state.get_player_by_role(Role.GOALKEEPER) self.add_tactic(Role.GOALKEEPER, GoalKeeper(self.game_state, goalkeeper, ourgoal)) role_by_robots = [(i, self.game_state.get_player_by_role(i)) for i in roles_to_consider] self.robots = [ player for _, player in role_by_robots if player is not None ] for role, player in role_by_robots: if player: self.add_tactic( role, AlignToDefenseWall(self.game_state, player, self.robots))
def _change_tactic(self, cmd: STAChangeCommand): try: this_player = GameState().our_team.available_players[cmd.data['id']] except KeyError: self.logger.info('A tactic was assign to a player which is not on the field (id={}).'.format(cmd.data['id'])) this_player = GameState().our_team.players[cmd.data['id']] player_id = this_player.id tactic_name = cmd.data['tactic'] target = Position.from_list(cmd.data['target']) if config['GAME']['on_negative_side']: target = target.flip_x() target = Pose(target, this_player.orientation) args = cmd.data.get('args', '') try: tactic = self.play_state.get_new_tactic(tactic_name)(self.game_state, this_player, target, args) except: self.logger.exception('An error occurred.') self.logger.debug('The tactic was call with wrong arguments') raise if not isinstance(self.play_state.current_strategy, HumanControl): self.play_state.current_strategy = 'HumanControl' self.play_state.current_strategy.assign_tactic(tactic, player_id)
def best_passing_option(passing_player, passer_can_kick_in_goal=True): # Retourne l'ID du player ou le but le mieux placé pour une passe, NONE si but est la meilleure possibilité score_min = float("inf") goal = GameState().field.their_goal receiver = None for p in GameState().our_team.available_players.values(): try: is_goaler = p == GameState().get_player_by_role(Role.GOALKEEPER) except KeyError: is_goaler = False if p != passing_player and not is_goaler: # Calcul du score pour passeur vers receveur score = line_of_sight_clearance(passing_player, p.pose.position) # Calcul du score pour receveur vers but score += line_of_sight_clearance(p, goal) if score_min > score: score_min = score receiver = p if passer_can_kick_in_goal and not is_ball_our_side(): score = (line_of_sight_clearance(passing_player, goal)) if score_min > score: receiver = None return receiver
def __init__(self, p_game_state): super().__init__(p_game_state) our_goal = self.game_state.field.our_goal_pose role_to_positions = { Role.FIRST_ATTACK: Pose.from_values(our_goal.position.x / 8, GameState().field.top * 2 / 3), Role.SECOND_ATTACK: Pose.from_values(our_goal.position.x / 8, GameState().field.top / 3), Role.MIDDLE: Pose.from_values(our_goal.position.x / 8, 0), Role.FIRST_DEFENCE: Pose.from_values(our_goal.position.x / 8, GameState().field.bottom / 3), Role.SECOND_DEFENCE: Pose.from_values(our_goal.position.x / 8, GameState().field.bottom * 2 / 3) } goalkeeper = self.game_state.get_player_by_role(Role.GOALKEEPER) self.create_node( Role.GOALKEEPER, GoalKeeper(self.game_state, goalkeeper, penalty_kick=True)) self.assign_tactics(role_to_positions)
def best_passing_option(passing_player, consider_goal=True): # Retourne l'ID du player ou le but le mieux placé pour une passe, NONE si but est la meilleure possibilité score_min = float("inf") goal = Position(GameState().field.constant["FIELD_THEIR_GOAL_X_EXTERNAL"], 0) receiver_id = None for i in GameState().my_team.available_players.values(): if i.id != passing_player.id: # Calcul du score pour passeur vers receveur score = line_of_sight_clearance(passing_player, np.array(i.pose.position)) # Calcul du score pour receveur vers but score += line_of_sight_clearance(i, goal) if (score_min > score).any(): score_min = score receiver_id = i.id if consider_goal and not is_ball_our_side(): score = (line_of_sight_clearance(passing_player, np.array(goal))) if score_min > score: receiver_id = None return receiver_id
class PlayState: def __init__(self): self.strategy_book = StrategyBook() self.tactic_book = TacticBook() self.game_state = GameState() self._current_strategy = None self.logger = logging.getLogger(self.__class__.__name__) @property def current_strategy(self): return self._current_strategy @current_strategy.setter def current_strategy(self, strategy_name: str): self.change_strategy(strategy_name) def change_strategy(self, strategy_name: str, roles: Optional[Dict[Role, int]]=None): assert isinstance(strategy_name, str) self.logger.debug("Switching to strategy '{}'".format(strategy_name)) strategy_class = self.strategy_book.get_strategy(strategy_name) # Use default rule of the strategy if roles is None: self.game_state.map_players_for_strategy(strategy_class) elif not self._is_mapping_valid(roles): self.logger.error("Invalid mapping from UI-debug") return else: # Use roles mapping from UI-debug self.game_state.map_players_to_roles_by_player_id(roles) self._current_strategy = strategy_class(self.game_state) def _is_mapping_valid(self, roles): for player_id in roles.values(): if player_id not in self.game_state.our_team.available_players.keys(): self.logger.error("Robot id {} is not available".format(player_id)) return False return True @property def current_tactical_state(self) -> List[Tuple[Player, str, str, Role]]: """ Retourne le nom des tactics en cours dans la stratégie en cours :return: List[Tuple[int, str, str, str]] les informations actuelles des tactiques courantes """ return self.current_strategy.get_current_state() def get_new_tactic(self, tactic_name: str) -> Callable: """ Retourne un callable sur la tactic spécifiée par le tactic_name. :param tactic_name: (str) le nom de la stratégie à retourner :return: Callable[[*args], Tactic] une Tactic non initialisé (non créer) """ return self.tactic_book.get_tactic(tactic_name)
def best_goal_score_option(passing_player): # Retourne la meilleure position dans le but pour kick goalA = Position(GameState().field.constant["FIELD_THEIR_GOAL_X_EXTERNAL"], GameState().field.constant["FIELD_GOAL_WIDTH"]/2) goalB = Position(GameState().field.constant["FIELD_THEIR_GOAL_X_EXTERNAL"], -GameState().field.constant["FIELD_GOAL_WIDTH"] / 2) best_position = best_position_option(passing_player, goalA, goalB) return best_position
def _create_mock_teams(self, allies, opponents): team1 = create_autospec(Team) team1.available_players = allies GameState().my_team = team1 team2 = create_autospec(Team) team2.available_players = opponents GameState().other_team = team2
def create_mock_teams(allies, opponents): team1 = create_autospec(Team) team1.available_players = allies GameState()._our_team = team1 print(GameState().our_team.available_players.values()) team2 = create_autospec(Team) team2.available_players = opponents GameState()._enemy_team = team2
def setUp(self): self.game_state = GameState() self.game_state._update_player(0, Pose(Position(-4450, 0), 0)) self.tactic1 = GoalKeeper(self.game_state, 0) self.tactic2 = Stop(self.game_state, 1) self.node1 = Node(self.tactic1) self.node2 = Node(self.tactic2) self.vertex1 = Vertex(0, foo) self.vertex2 = Vertex(1, foo2)
def setUp(self): # ToDo : Use mock instead of actual objects self.game_state = GameState() self.game = Game() self.game.set_referee(Referee()) game_world = ReferenceTransferObject(self.game) game_world.set_team_color_svc(TeamColorService(TeamColor.YELLOW)) self.game_state.set_reference(game_world) self.a_player = OurPlayer(TeamColor.YELLOW, A_PLAYER_ID)
def setUp(self): config_service = ConfigService().load_file("config/sim_standard.cfg") self.game_state = GameState() self.game = Game() self.game.set_referee(Referee()) self.game.ball = Ball() game_world = ReferenceTransferObject(self.game) game_world.set_team_color_svc(TeamColorService(TeamColor.YELLOW_TEAM)) self.game_state.set_reference(game_world) self.game_state.game.ball.set_position(Position(100, 0), 0)
def _exec_state(self): # We use the ball's mobility for detecting a kick and change state if self.current_state in self.NORMAL_STATE and GameState().ball.is_immobile(): return self._decide_between_normal_play() elif self.current_state in self.FREE_KICK_STATE and GameState().ball.is_mobile(): return self._decide_between_normal_play() elif self.current_state in self.KICKOFF_STATE and GameState().ball.is_mobile(): return self._decide_between_normal_play() return self.current_state
def player_covered_from_goal(player: Player): shooting_angle = angle_between_three_points(GameState().field.their_goal_line.p1, player.position, GameState().field.their_goal_line.p2) vec_player_to_goal = GameState().field.their_goal - player.position our_team = [other_player for other_player in GameState().our_team.available_players.values() if other_player is not player] enemy_team = [other_player for other_player in GameState().enemy_team.available_players.values()] pertinent_collisions = [] for other_player in our_team + enemy_team: if object_pointing_toward_point(player.position, vec_player_to_goal.angle, other_player.position, wrap_to_pi(shooting_angle + 5 * np.pi / 180)): pertinent_collisions.append(Obstacle(other_player.position.array, avoid_distance=90)) if not any(pertinent_collisions): return GameState().field.their_goal pertinent_collisions_positions = np.array([obs.position for obs in pertinent_collisions]) pertinent_collisions_avoid_radius = np.array([obs.avoid_distance for obs in pertinent_collisions]) results = [] for i in range(0, 15 + 1): # discretisation de la ligne de but goal_point = GameState().field.their_goal_line.p1 + GameState().field.their_goal_line.direction * \ (GameState().field.their_goal_line.length * i / 15) is_colliding = is_path_colliding(pertinent_collisions, pertinent_collisions_positions, pertinent_collisions_avoid_radius, player.position.array, goal_point.array) results.append((is_colliding, goal_point)) max_len_seg, indexend = find_max_consecutive_bool(results) if max_len_seg == 0 and indexend == 0: return None return results[int(indexend-1 - np.math.ceil(max_len_seg / 2))][1]
def __init__(self, game_state): super().__init__(game_state) # Attribution des joueurs center_offset = game_state.field.center_circle_radius # Positions objectifs des joueurs # FIXME: This is bad, the orientation of the player will always be the same, # independently of if we are in a positive or negative x attack_top_position = Pose.from_values(GameState().field.our_goal_x / 10, GameState().field.bottom * 3 / 5, 0) attack_bottom_position = Pose.from_values(GameState().field.our_goal_x / 10, GameState().field.top * 3 / 5, 0) middle_position = Pose.from_values(center_offset + GameState().field.our_goal_x / 10, 0, 0) defense_top_position = Pose.from_values(GameState().field.our_goal_x / 2, GameState().field.top / 10, 0) defense_bottom_position = Pose.from_values(GameState().field.our_goal_x / 2, GameState().field.bottom / 10, 0) goalkeeper = self.assigned_roles[Role.GOALKEEPER] self.create_node(Role.GOALKEEPER, GoalKeeper(game_state, goalkeeper)) role_to_positions = {Role.FIRST_ATTACK: attack_top_position, Role.SECOND_ATTACK: attack_bottom_position, Role.MIDDLE: middle_position, Role.FIRST_DEFENCE: defense_top_position, Role.SECOND_DEFENCE: defense_bottom_position} self.assign_tactics(role_to_positions)
def _find_best_passing_option(self): assignation_delay = (time.time() - self.target_assignation_last_time) if assignation_delay > TARGET_ASSIGNATION_DELAY: tentative_target_id = best_passing_option(self.player) if tentative_target_id is None: self.target = Pose.from_values(GameState().field.their_goal_x, 0, 0) else: self.target = Pose(GameState().get_player_position(tentative_target_id)) self.target_assignation_last_time = time.time()
def setUp(self): # ToDo : Use mock instead of actual objects self.game_state = GameState() self.game = Game() self.game.set_referee(Referee()) self.game.ball = Ball() game_world = ReferenceTransferObject(self.game) game_world.set_team_color_svc(TeamColorService(TeamColor.YELLOW_TEAM)) self.game.set_our_team_color(TeamColor.YELLOW_TEAM) self.game_state.set_reference(game_world) self.player_id = 1 # random integer
def setUp(self): self.game = Game() self.referee = Referee self.game.set_referee(self.referee) self.tcsvc = TeamColorService(TeamColor.BLUE) self.game_world_OK = ReferenceTransferObject(self.game) self.game_world_OK.set_team_color_svc(self.tcsvc) self.GameStateManager1 = GameState() self.GameStateManager2 = GameState() self.GameStateManager1.set_reference(self.game_world_OK)
def __init__(self, mode_debug_active: bool = True): """ initialisation du worldstate :param mode_debug_active: (bool) indique si le mode debug est activé """ self.module_state = ModuleState() self.play_state = PlayState() self.game_state = GameState() # pour passer une interface de debug deja recuperer self.debug_interface = DebugInterface()
class TestRaycast(unittest.TestCase): def setUp(self): self.game_state = GameState() self.game_state._update_ball_position(Position(100, 0)) def test_raycast(self): self.assertTrue( raycast(self.game_state, Position(100, 100), 200, -pi / 2, BALL_RADIUS, [], [], False)) def test_raycast2(self): pass
def setUp(self): self.game = Game() self.referee = Referee self.game.set_referee(self.referee) self.tcsvc = TeamColorService(TeamColor.YELLOW_TEAM) self.game.set_our_team_color(self.tcsvc.OUR_TEAM_COLOR) self.game_world_OK = GameWorld(self.game) self.game_world_OK.set_team_color_svc(self.tcsvc) self.GameStateManager1 = GameState() self.GameStateManager2 = GameState() self.GameStateManager1.set_reference(self.game_world_OK)
def line_of_sight_clearance(player, target): # Retourne un score en fonction du dégagement de la trajectoire (plus c'est dégagé plus le score est petit) score = (player.pose.position - target).norm for p in GameState().our_team.available_players.values(): # Obstacle : les players friends if not (p.id == player.id): if target is not p.pose.position: score *= trajectory_score(player.pose.position, target, p.pose.position) for p in GameState().enemy_team.available_players.values(): # Obstacle : les players ennemis score *= trajectory_score(player.pose.position, target, p.pose.position) return score
def setUp(self): config_service = ConfigService().load_file("config/sim_standard.cfg") self.game = Game() self.referee = Referee self.game.set_referee(self.referee) self.tcsvc = TeamColorService(TeamColor.BLUE_TEAM) self.game.set_our_team_color(self.tcsvc.OUR_TEAM_COLOR) self.game_world_OK = ReferenceTransferObject(self.game) self.game_world_OK.set_team_color_svc(self.tcsvc) self.GameStateManager1 = GameState() self.GameStateManager2 = GameState() self.GameStateManager1.set_reference(self.game_world_OK)
def is_closest_not_goalkeeper(self, player): if self.game_state.ball.is_mobile(): self.has_ball_move = True role = GameState().get_role_by_player_id(player.id) if not self.has_ball_move: return role == self.closest_role closest_players = closest_players_to_point(GameState().ball_position, our_team=True) if player == closest_players[0].player: return True return closest_players[0].player == self.game_state.get_player_by_role(Role.GOALKEEPER) \ and player == closest_players[1].player
def line_of_sight_clearance_ball_legacy(player, target: Position): # Retourne un score en fonction du dégagement de la trajectoire de la target vers la ball excluant le robot actuel # (plus c'est dégagé plus le score est petit) score = np.linalg.norm(GameState().get_ball_position() - target) # for j in GameState().my_team.available_players.values(): # # Obstacle : les players friends # if not (j.id == player.id or j.pose.position == target): # score *= trajectory_score(GameState().get_ball_position(), target, j.pose.position) for j in GameState().other_team.available_players.values(): # Obstacle : les players ennemis score *= trajectory_score(GameState().get_ball_position(), target, j.pose.position) return score
def _find_best_passing_option(self): assignation_delay = (time.time() - self.target_assignation_last_time) if assignation_delay > TARGET_ASSIGNATION_DELAY: tentative_target_id = best_passing_option(self.player) if tentative_target_id is None: self.target = Pose( GameState().const["FIELD_THEIR_GOAL_X_EXTERNAL"], 0, 0) else: self.target = Pose( GameState().get_player_position(tentative_target_id)) self.target_assignation_last_time = time.time()
class RoleMapperTests(TestCase): def setUp(self): self.state = GameState() self.role_mapper = RoleMapper() def test_givenNoMapping_whenMapById_thenMapsAllPlayers(self): self.state.map_players_to_roles_by_player(basic_roles) self.assertDictEqual(self.state.role_mapping, basic_roles) def test_givenBasicMapping_whenMapOtherwise_thenMapsPlayersProperly(self): self.state.map_players_to_roles_by_player(basic_roles) self.state.map_players_to_roles_by_player(inverted_roles_no_goal) self.assertDictEqual(self.state.role_mapping, inverted_roles_no_goal) def test_givenBasicMapping_whenMapFewerRobots_thenRemovesUnasignedOnes( self): self.state.map_players_to_roles_by_player(basic_roles) self.state.map_players_to_roles_by_player(missing_middle) self.assertDictEqual(self.state.role_mapping, missing_middle_expected) def test_whenMapRuleWithDuplicateRole_thenAssertError(self): A_ROLE_RULE = {Role.GOALKEEPER: None} with pytest.raises(AssertionError): self.role_mapper.map_with_rules([], A_ROLE_RULE, A_ROLE_RULE) def test_whenMappingWithMoreOptionalRoleThenPlayers_thenOnlyMapTheNumberOfPlayer( self): A_SET_AVAILABLE_PLAYER = { 1: Player(1, TeamColorService.BLUE), 2: Player(2, TeamColorService.BLUE) } LESS_ROLE_THEN_PLAYER = [ Role.GOALKEEPER, Role.MIDDLE, Role.SECOND_ATTACK ] mapping = self.role_mapper.map_with_rules(A_SET_AVAILABLE_PLAYER, {}, LESS_ROLE_THEN_PLAYER) assert len(A_SET_AVAILABLE_PLAYER) == len(mapping) def test_whenMappingWithMoreRequiredRoleThenPlayers_thenAssert(self): A_SET_AVAILABLE_PLAYER = { 1: Player(1, TeamColorService.BLUE), 2: Player(2, TeamColorService.BLUE) } LESS_ROLE_THEN_PLAYER = [ Role.GOALKEEPER, Role.MIDDLE, Role.SECOND_ATTACK ] with self.assertRaises(AssertionError): self.role_mapper.map_with_rules(A_SET_AVAILABLE_PLAYER, LESS_ROLE_THEN_PLAYER, {})
def line_of_sight_clearance(player, targets): # Retourne un score en fonction du dégagement de la trajectoire (plus c'est dégagé plus le score est petit) score = np.linalg.norm(player.pose.position - targets) for j in GameState().my_team.available_players.values(): # Obstacle : les players friends condition = [] if not (j.id == player.id): condition += [target is not j.pose.position for target in targets] if any(condition): score *= trajectory_score(player.pose.position, targets[condition], j.pose.position) for j in GameState().other_team.available_players.values(): # Obstacle : les players ennemis score *= trajectory_score(player.pose.position, targets, j.pose.position) return score
def __init__(self, p_game_state): super().__init__(p_game_state, keep_roles=False) # TODO: HARDCODED ID FOR QUALIFICATION, REMOVE LATER self.roles_graph = {r: Graph() for r in Role} role_mapping = { Role.GOALKEEPER: 2, Role.MIDDLE: 4, Role.FIRST_ATTACK: 6 } self.game_state.map_players_to_roles_by_player_id(role_mapping) ourgoal = Pose( Position(GameState().const["FIELD_OUR_GOAL_X_EXTERNAL"], 0), 0) self.theirgoal = Pose( Position(GameState().const["FIELD_THEIR_GOAL_X_EXTERNAL"], 0), 0) roles_to_consider = [Role.MIDDLE, Role.FIRST_ATTACK, Role.GOALKEEPER] role_by_robots = [(i, self.game_state.get_player_by_role(i)) for i in roles_to_consider] self.robots = [ player for _, player in role_by_robots if player is not None ] goalkeeper = self.game_state.get_player_by_role(Role.GOALKEEPER) self.add_tactic( Role.GOALKEEPER, GoalKeeper(self.game_state, goalkeeper, ourgoal, penalty_kick=True)) for index, player in role_by_robots: if player: self.add_tactic( index, PositionForPass(self.game_state, player, auto_position=True, robots_in_formation=self.robots)) self.add_tactic( index, GoKick(self.game_state, player, target=self.theirgoal)) self.add_condition(index, 0, 1, partial(self.is_closest, player)) self.add_condition(index, 1, 0, partial(self.is_not_closest, player)) self.add_condition(index, 1, 1, partial(self.has_kicked, player))
class TestGameStateManager(unittest.TestCase): """ Teste les différentes fonctionnalités du GameStateManager """ def setUp(self): self.game = Game() self.referee = Referee self.game.set_referee(self.referee) self.tcsvc = TeamColorService(TeamColor.BLUE) self.game_world_OK = ReferenceTransferObject(self.game) self.game_world_OK.set_team_color_svc(self.tcsvc) self.GameStateManager1 = GameState() self.GameStateManager2 = GameState() self.GameStateManager1.set_reference(self.game_world_OK) def test_singleton(self): """ Teste si le Manager est un singleton, i.e. s'il ne peut y avoir qu'une seule instance du manager """ self.assertTrue(self.GameStateManager1 is self.GameStateManager2) self.assertIs(self.GameStateManager1, self.GameStateManager2) def test_set_reference(self): self.GameStateManager1.set_reference(self.game_world_OK) self.assertIs(self.GameStateManager1.game.referee, self.game_world_OK.game.referee) self.assertIs(self.GameStateManager1.field, self.game_world_OK.game.field) self.assertIs(self.GameStateManager1.game.our_team_color, self.game.our_team_color) game_state_manager = GameState() self.assertRaises(AssertionError, game_state_manager.set_reference, None) game = Game() game_world_nok = ReferenceTransferObject(game) self.assertRaises(AssertionError, game_state_manager.set_reference, game_world_nok) game_world_nok.game.set_referee(self.referee) self.assertRaises(AssertionError, game_state_manager.set_reference, game_world_nok) game = Game() game_world_nok = ReferenceTransferObject(game) game_world_nok.set_team_color_svc(self.tcsvc) self.assertRaises(AssertionError, game_state_manager.set_reference, game_world_nok)
def has_kicked(self, player): role = GameState().get_role_by_player_id(player.id) if self.roles_graph[role].get_current_tactic_name() == 'GoKick': return self.roles_graph[role].get_current_tactic( ).status_flag == Flags.SUCCESS else: return False
def setUp(self): # ToDo : Use mock instead of actual objects self.game_state = GameState() self.game = Game() self.game.set_referee(Referee()) self.game.ball = Ball() game_world = GameWorld(self.game) game_world.set_team_color_svc(TeamColorService(TeamColor.YELLOW_TEAM)) self.game.set_our_team_color(TeamColor.YELLOW_TEAM) self.game_state.set_reference(game_world) self.player_id = 1 # random integer
def setUp(self): self.game_state = GameState() self.game = Game() self.game.set_referee(Referee()) self.game.ball = Ball() game_world = GameWorld(self.game) game_world.set_team_color_svc(TeamColorService(TeamColor.YELLOW_TEAM)) self.game.set_our_team_color(TeamColor.YELLOW_TEAM) self.game_state.set_reference(game_world) self.game_state = GameState() self.empty_graph = Graph() self.graph1 = Graph() self.tactic1 = Stop(self.game_state, 1) self.tactic2 = GoToPositionNoPathfinder(self.game_state, 0, Pose(Position(500, 0), 0)) self.node1 = Node(self.tactic1) self.node2 = Node(self.tactic2) self.vertex1 = Vertex(1, foo) self.graph1.add_node(self.node1) self.graph1.add_node(self.node2) self.graph1.add_vertex(0, 1, foo)
def __init__(self, mode_debug_active: bool=True): """ initialisation du worldstate :param mode_debug_active: (bool) indique si le mode debug est activé """ self.module_state = ModuleState() self.play_state = PlayState() self.game_state = GameState() # pour passer une interface de debug deja recuperer self.debug_interface = DebugInterface()
class WorldState: def __init__(self, mode_debug_active: bool=True): """ initialisation du worldstate :param mode_debug_active: (bool) indique si le mode debug est activé """ self.module_state = ModuleState() self.play_state = PlayState() self.game_state = GameState() # pour passer une interface de debug deja recuperer self.debug_interface = DebugInterface() def set_reference(self, world_reference: GameWorld) -> None: """ Passe le data transfert object GameWorld au game state pour qu'il prenne ses références. :param world_reference: GameWorld instance avec les références dedans :return: None """ self.game_state.set_reference(world_reference)
def setUp(self): self.game_state = GameState() self.game = Game() self.game.set_referee(Referee()) self.game.ball = Ball() game_world = GameWorld(self.game) game_world.set_team_color_svc(TeamColorService(TeamColor.YELLOW_TEAM)) self.game.set_our_team_color(TeamColor.YELLOW_TEAM) self.game_state.set_reference(game_world) self.game_state.game.friends.players[0].update(Pose(Position(-4450, 0), 0)) self.tactic1 = GoalKeeper(self.game_state, 0) self.tactic2 = Stop(self.game_state, 1) self.node1 = Node(self.tactic1) self.node2 = Node(self.tactic2) self.vertex1 = Vertex(0, foo) self.vertex2 = Vertex(1, foo2)
def __init__(self, tactic_obj): assert not isinstance(tactic_obj, Tactic), "You must pass the class, not an instance of the class. (ex: 'GoToPosition', not 'GoToPosition()')" self.logger = logging.getLogger(self.__class__.__name__) self.tactic_obj = tactic_obj self.tactic = None self.hero_robot = None self.game_state = GameState() # Singleton are a pain in the ass, there state must be reset self.game_state.reset() # Variable for assertion self.last_ia_cmd = None self.has_charge_kick = False self.has_hit_ball = False
def __init__(self, framework): super().__init__(name=__name__) self.framework = framework self.logger = logging.getLogger(self.__class__.__name__) # Managers for shared memory between process self.engine_game_state = self.framework.game_state self.field = self.framework.field # Queues for process communication self.ai_queue = self.framework.ai_queue self.referee_queue = self.framework.referee_queue self.ui_send_queue = self.framework.ui_send_queue self.ui_recv_queue = self.framework.ui_recv_queue # States self.game_state = GameState() self.play_state = PlayState() # Executors self.play_executor = PlayExecutor(self.play_state, self.ui_send_queue, self.referee_queue) self.debug_executor = DebugExecutor(self.play_state, self.play_executor, self.ui_send_queue, self.ui_recv_queue) # fps and limitation self.fps = config['GAME']['fps'] self.frame_count = 0 self.last_frame_count = 0 self.dt = 0.0 self.last_time = 0.0 def callback(excess_time): if excess_time > Coach.MAX_EXCESS_TIME: self.logger.debug('Overloaded (%.1f ms behind schedule)', 1000*excess_time) self.fps_sleep = create_fps_timer(self.fps, on_miss_callback=callback) # profiling self.profiler = None
class Coach(Process): MAX_EXCESS_TIME = 0.05 def __init__(self, framework): super().__init__(name=__name__) self.framework = framework self.logger = logging.getLogger(self.__class__.__name__) # Managers for shared memory between process self.engine_game_state = self.framework.game_state self.field = self.framework.field # Queues for process communication self.ai_queue = self.framework.ai_queue self.referee_queue = self.framework.referee_queue self.ui_send_queue = self.framework.ui_send_queue self.ui_recv_queue = self.framework.ui_recv_queue # States self.game_state = GameState() self.play_state = PlayState() # Executors self.play_executor = PlayExecutor(self.play_state, self.ui_send_queue, self.referee_queue) self.debug_executor = DebugExecutor(self.play_state, self.play_executor, self.ui_send_queue, self.ui_recv_queue) # fps and limitation self.fps = config['GAME']['fps'] self.frame_count = 0 self.last_frame_count = 0 self.dt = 0.0 self.last_time = 0.0 def callback(excess_time): if excess_time > Coach.MAX_EXCESS_TIME: self.logger.debug('Overloaded (%.1f ms behind schedule)', 1000*excess_time) self.fps_sleep = create_fps_timer(self.fps, on_miss_callback=callback) # profiling self.profiler = None def wait_for_geometry(self): self.logger.debug('Waiting for field\'s geometry from the Engine.') start = time() while not self.field: self.fps_sleep() self.game_state.const = self.field self.logger.debug('Geometry received from the Engine in {:0.2f} seconds.'.format(time() - start)) def wait_for_referee(self): if Config()['GAME']['competition_mode']: self.logger.debug('Waiting for commands from the referee') while self.referee_queue.qsize() == 0: self.logger.debug('Referee is not active or port is set incorrectly, current port is {})'.format( Config()['COMMUNICATION']['referee_port'])) sleep(1) self.logger.debug('Referee command detected') def run(self): try: self.logger.debug('Running with process ID {} at {} fps.'.format(os.getpid(), self.fps)) # profiling self.profiler = cProfile.Profile() if self.framework.profiling: self.profiler.enable() self.wait_for_geometry() self.wait_for_referee() while True: self.frame_count += 1 self.update_time() self.main_loop() self.fps_sleep() self.framework.coach_watchdog.value = time() except KeyboardInterrupt: self.logger.debug('Interrupted.') except BrokenPipeError: self.logger.exception('A connection was broken.') except: self.logger.exception('An error occurred.') finally: self.stop() def main_loop(self): self.game_state.update(self.engine_game_state) self.debug_executor.exec() engine_commands = self.play_executor.exec() try: self.ai_queue.put_nowait(engine_commands) except Full: self.logger.critical('The Engine queue is full.') def update_time(self): current_time = time() self.dt = current_time - self.last_time self.last_time = current_time def dump_profiling_stats(self): if self.framework.profiling: self.profiler.dump_stats(config['GAME']['profiling_filename']) self.logger.debug('Profiling data written to {}.'.format(config['GAME']['profiling_filename'])) def is_alive(self): if config['GAME']['competition_mode']: if time() - self.framework.coach_watchdog.value > self.framework.MAX_HANGING_TIME: self.logger.critical('Process is hanging. Shutting down.') return False return super().is_alive() def stop(self): self.dump_profiling_stats() self.logger.info('Stopped.')
class TestNode(unittest.TestCase): def setUp(self): self.game_state = GameState() self.game = Game() self.game.set_referee(Referee()) self.game.ball = Ball() game_world = GameWorld(self.game) game_world.set_team_color_svc(TeamColorService(TeamColor.YELLOW_TEAM)) self.game.set_our_team_color(TeamColor.YELLOW_TEAM) self.game_state.set_reference(game_world) self.game_state.game.friends.players[0].update(Pose(Position(-4450, 0), 0)) self.tactic1 = GoalKeeper(self.game_state, 0) self.tactic2 = Stop(self.game_state, 1) self.node1 = Node(self.tactic1) self.node2 = Node(self.tactic2) self.vertex1 = Vertex(0, foo) self.vertex2 = Vertex(1, foo2) def test_init(self): self.assertRaises(AssertionError, Node, "not a tactic") self.assertIsInstance(self.node2.tactic, Tactic) self.assertEqual(len(self.node2.vertices), 0) def test_add_vertex(self): self.assertRaises(AssertionError, self.node1.add_vertex, "not a vertex") self.node1.add_vertex(self.vertex1) self.assertEqual(len(self.node1.vertices), 1) self.node1.add_vertex(self.vertex1) self.assertEqual(len(self.node1.vertices), 1) # il ne peut y avoir qu'un vertex entre deux noeuds dans un sens self.node1.add_vertex(self.vertex2) self.assertEqual(len(self.node1.vertices), 2) def test_remove_vertex(self): self.assertRaises(AssertionError, self.node1.remove_vertex, "not an int") self.assertRaises(AssertionError, self.node1.remove_vertex, -1) self.node1.add_vertex(self.vertex1) self.node1.remove_vertex(420) self.assertEqual(len(self.node1.vertices), 1) self.node1.remove_vertex(0) self.assertEqual(len(self.node1.vertices), 0) @unittest.skip("thinkin we should have generic tactic for test purpose, this is infuriating") def test_exec(self): self.node1.add_vertex(self.vertex1) self.node1.add_vertex(self.vertex2) next_ai_command, next_node = self.node1.exec() self.assertEqual(next_node, 0) expected_aicmd = AICommand(0, AICommandType.MOVE, **{"pose_goal": Pose(Position(-4000, 0), 0)}) self.assertEqual(next_ai_command, expected_aicmd) self.node2.add_vertex(self.vertex2) expected_aicmd = AICommand(0, AICommandType.STOP)#, **{"pose_goal": Pose(Position(-4000, 0), 0)}) next_ai_command, next_node = self.node2.exec() self.assertEqual(next_ai_command, expected_aicmd) self.assertEqual(next_node, -1) def test_str(self): self.node1.add_vertex(self.vertex1) self.node1.add_vertex(self.vertex2) expected_string = "Tactic: GoalKeeper Vertices: " for vertex in self.node1.vertices: expected_string += "\n " + str(vertex) self.assertEqual(str(self.node1), expected_string) def test_set_flag(self): self.assertRaises(AssertionError, self.node1.set_flag, "not a flag") self.node1.set_flag(Flags.SUCCESS) self.assertEqual(self.node1.tactic.status_flag, Flags.SUCCESS)
class TestGameStateManager(unittest.TestCase): """ Teste les différentes fonctionnalités du GameStateManager """ def setUp(self): self.game = Game() self.referee = Referee self.game.set_referee(self.referee) self.tcsvc = TeamColorService(TeamColor.YELLOW_TEAM) self.game.set_our_team_color(self.tcsvc.OUR_TEAM_COLOR) self.game_world_OK = GameWorld(self.game) self.game_world_OK.set_team_color_svc(self.tcsvc) self.GameStateManager1 = GameState() self.GameStateManager2 = GameState() self.GameStateManager1.set_reference(self.game_world_OK) def test_singleton(self): """ Teste si le Manager est un singleton, i.e. s'il ne peut y avoir qu'une seule instance du manager """ self.assertTrue(self.GameStateManager1 is self.GameStateManager2) self.assertIs(self.GameStateManager1, self.GameStateManager2) def test_set_reference(self): self.GameStateManager1.set_reference(self.game_world_OK) self.assertIs(self.GameStateManager1.game.referee, self.game_world_OK.game.referee) self.assertIs(self.GameStateManager1.field, self.game_world_OK.game.field) self.assertIs(self.GameStateManager2.our_team_color, self.game.our_team_color) game_state_manager = GameState() self.assertRaises(AssertionError, game_state_manager.set_reference, None) game = Game() game_world_nok = GameWorld(game) self.assertRaises(AssertionError, game_state_manager.set_reference, game_world_nok) game_world_nok.game.set_referee(self.referee) self.assertRaises(AssertionError, game_state_manager.set_reference, game_world_nok) game = Game() game_world_nok = GameWorld(game) game_world_nok.set_team_color_svc(self.tcsvc) self.assertRaises(AssertionError, game_state_manager.set_reference, game_world_nok) def test_get_player_pose(self): self.assertIs(self.GameStateManager1.get_player_pose(0, True), self.game.friends.players[0].pose) self.assertIs(self.GameStateManager2.get_player_pose(0, False), self.game.enemies.players[0].pose) self.assertIsNot(self.GameStateManager1.get_player_pose(0, True), self.game.friends.players[1].pose) self.assertIsNot(self.GameStateManager2.get_player_pose(0, False), self.game.enemies.players[1].pose) self.assertIsNot(self.GameStateManager1.get_player_pose(0, True), self.game.enemies.players[0].pose) self.assertIsNot(self.GameStateManager2.get_player_pose(0, False), self.game.friends.players[0].pose) def test_get_player_position(self): self.assertIs(self.GameStateManager1.get_player_position(0, True), self.game.friends.players[0].pose.position) self.assertIs(self.GameStateManager2.get_player_position(0, False), self.game.enemies.players[0].pose.position)
class PerfectSim: def __init__(self, tactic_obj): assert not isinstance(tactic_obj, Tactic), "You must pass the class, not an instance of the class. (ex: 'GoToPosition', not 'GoToPosition()')" self.logger = logging.getLogger(self.__class__.__name__) self.tactic_obj = tactic_obj self.tactic = None self.hero_robot = None self.game_state = GameState() # Singleton are a pain in the ass, there state must be reset self.game_state.reset() # Variable for assertion self.last_ia_cmd = None self.has_charge_kick = False self.has_hit_ball = False def add_robot(self, robot_id, pose: Pose): self.game_state.our_team.players[robot_id].pose = pose def add_enemy_robot(self, robot_id, pose: Pose): self.game_state.enemy_team.players[robot_id].pose = pose def move_ball(self, position: Position): self.game_state.ball.position = position def start(self, robot_id, target: Pose): self.hero_robot = GameState().our_team.players[robot_id] self.tactic = self.tactic_obj(GameState(), self.hero_robot, target) def tick(self): if not self.tactic: raise RuntimeError("You must call start() to initialize the simulation") print("====== Executing {} ======".format(str(self.tactic.current_state.__func__))) ia_cmd = self.tactic.exec() self._apply_cmd(ia_cmd) def has_kick(self): return self.last_ia_cmd.kick_force != KickForce.NONE def _apply_cmd(self, ia_cmd): self.last_ia_cmd = ia_cmd if ia_cmd.target: print("Hero Robot moved to {}".format(ia_cmd.target)) self.hero_robot.pose = ia_cmd.target if ia_cmd.kick_force != KickForce.NONE: if self._robot_can_hit_ball(self.hero_robot): print("Hero Robot has kick and hit the ball") self.has_hit_ball = True else: print("Hero Robot has kick, but didn't hit the ball") if ia_cmd.charge_kick: self.has_charge_kick = True def _robot_can_hit_ball(self, robot): KICK_DISTANCE_MIN = ROBOT_CENTER_TO_KICKER - BALL_RADIUS * 0.5 KICK_DISTANCE_MAX = ROBOT_CENTER_TO_KICKER + BALL_RADIUS * 1.5 MAX_ANGLE_FOR_KICK = 15 ball_position = self.game_state.ball.position robot_to_ball = robot.pose.position - ball_position return KICK_DISTANCE_MIN < robot_to_ball.norm < KICK_DISTANCE_MAX \ and compare_angle(robot.pose.orientation, robot_to_ball.angle, abs_tol=MAX_ANGLE_FOR_KICK)
def __init__(self): self.strategy_book = StrategyBook() self.tactic_book = TacticBook() self.game_state = GameState() self._current_strategy = None self.logger = logging.getLogger(self.__class__.__name__)
class TestGraph(unittest.TestCase): def setUp(self): self.game_state = GameState() self.game = Game() self.game.set_referee(Referee()) self.game.ball = Ball() game_world = GameWorld(self.game) game_world.set_team_color_svc(TeamColorService(TeamColor.YELLOW_TEAM)) self.game.set_our_team_color(TeamColor.YELLOW_TEAM) self.game_state.set_reference(game_world) self.game_state = GameState() self.empty_graph = Graph() self.graph1 = Graph() self.tactic1 = Stop(self.game_state, 1) self.tactic2 = GoToPositionNoPathfinder(self.game_state, 0, Pose(Position(500, 0), 0)) self.node1 = Node(self.tactic1) self.node2 = Node(self.tactic2) self.vertex1 = Vertex(1, foo) self.graph1.add_node(self.node1) self.graph1.add_node(self.node2) self.graph1.add_vertex(0, 1, foo) def test_init(self): self.assertEqual(self.empty_graph.current_node, 0) self.assertEqual(len(self.empty_graph.nodes), 0) def test_get_current_tactic_name(self): self.assertEqual(self.graph1.get_current_tactic_name(), "Stop") self.assertEqual(self.empty_graph.get_current_tactic_name(), None) self.empty_graph.add_node(self.node2) self.assertEqual(self.empty_graph.get_current_tactic_name(), "GoToPositionNoPathfinder") def test_get_current_tactic(self): self.assertIsInstance(self.graph1.get_current_tactic(), Stop) self.assertEqual(self.empty_graph.get_current_tactic(), None) self.empty_graph.add_node(self.node2) self.assertIsInstance(self.empty_graph.get_current_tactic(), GoToPositionNoPathfinder) def test_add_node(self): self.assertEqual(len(self.graph1.nodes), 2) self.assertRaises(AssertionError, self.graph1.add_node, "not a node") def test_remove_node(self): self.assertRaises(AssertionError, self.graph1.remove_node, "not an int") self.assertRaises(AssertionError, self.graph1.remove_node, -1) self.assertRaises(AssertionError, self.graph1.remove_node, 420) self.graph1.remove_node(1) self.assertEqual(len(self.graph1.nodes), 1) self.assertEqual(len(self.graph1.nodes[0].vertices), 0) def test_add_vertex(self): self.assertEqual(len(self.graph1.nodes[0].vertices), 1) self.assertRaises(AssertionError, self.graph1.add_vertex, "not an int", 1, foo) self.assertRaises(AssertionError, self.graph1.add_vertex, -1, 1, foo) self.assertRaises(AssertionError, self.graph1.add_vertex, 420, 1, foo) self.assertRaises(AssertionError, self.graph1.add_vertex, 0, "not an int", foo) self.assertRaises(AssertionError, self.graph1.add_vertex, 0, -1, foo) self.assertRaises(AssertionError, self.graph1.add_vertex, 0, 420, foo) self.assertRaises(AssertionError, self.graph1.add_vertex, 0, 1, "not a callable") self.graph1.add_vertex(0, 1, foo) self.assertEqual(len(self.graph1.nodes[0].vertices), 1) def test_remove_vertex(self): self.assertRaises(AssertionError, self.graph1.remove_vertex, "not an int", 1) self.assertRaises(AssertionError, self.graph1.remove_vertex, -1, 1) self.assertRaises(AssertionError, self.graph1.remove_vertex, 420, 1) self.assertRaises(AssertionError, self.graph1.remove_vertex, 0, "not an int") self.assertRaises(AssertionError, self.graph1.remove_vertex, 0, -1) self.assertRaises(AssertionError, self.graph1.remove_vertex, 0, 420) self.graph1.add_node(self.node2) self.graph1.remove_vertex(0, 2) self.assertEqual(len(self.graph1.nodes[0].vertices), 1) self.graph1.remove_vertex(0, 1) self.assertEqual(len(self.graph1.nodes[0].vertices), 0) @unittest.skip("I don't know whuy the f**k it is broken here.") def test_exec(self): next_ai_command = self.graph1.exec() expected_ai_command = AICommand(1, AICommandType.STOP) self.assertEqual(self.graph1.current_node, 1) self.assertEqual(next_ai_command, expected_ai_command) self.assertRaises(EmptyGraphException, self.empty_graph.exec) self.empty_graph.add_node(self.node2) self.empty_graph.add_node(self.node1) self.empty_graph.add_vertex(0, 1, foo2) next_ai_command = self.empty_graph.exec() expected_ai_command = AICommand(0, AICommandType.MOVE, **{"pose_goal": Pose(Position(500, 0))}) self.assertEqual(self.empty_graph.current_node, 0) self.assertEqual(next_ai_command, expected_ai_command) next_ai_command = self.empty_graph.exec() expected_ai_command = AICommand(0, AICommandType.MOVE, **{"pose_goal": Pose(Position(500, 0))}) self.assertEqual(self.empty_graph.current_node, 0) self.assertEqual(next_ai_command, expected_ai_command) def test_set_current_node(self): self.assertRaises(AssertionError, self.graph1.set_current_node, "not an int") self.assertRaises(AssertionError, self.graph1.set_current_node, -1) self.assertRaises(AssertionError, self.graph1.set_current_node, 420) self.graph1.nodes[0].set_flag(Flags.WIP) self.graph1.set_current_node(1) self.assertEqual(self.graph1.current_node, 1) self.assertEqual(self.graph1.nodes[0].tactic.status_flag, Flags.INIT) def test_str(self): expected_string = "" for i in range(len(self.graph1.nodes)): expected_string += "Node " + str(i) + ": " + str(self.graph1.nodes[i]) + "\n" self.assertEqual(str(self.graph1), expected_string)
class TestActions(unittest.TestCase): def setUp(self): # ToDo : Use mock instead of actual objects self.game_state = GameState() self.game = Game() self.game.set_referee(Referee()) self.game.ball = Ball() game_world = GameWorld(self.game) game_world.set_team_color_svc(TeamColorService(TeamColor.YELLOW_TEAM)) self.game.set_our_team_color(TeamColor.YELLOW_TEAM) self.game_state.set_reference(game_world) self.player_id = 1 # random integer @unittest.skip("I don't know whuy the f**k it is broken here.") def test_move_to(self): self.pose = Pose(Position(0, 0, 0), orientation=0.0) self.move = MoveToPosition(self.game_state, self.player_id, self.pose) self.assertEqual(self.move.exec(), AICommand(1, AICommandType.MOVE, **{"pose_goal": self.pose})) self.pose = Pose(Position(0.5, 0.3, 0.2), orientation=3.2) self.move = MoveToPosition(self.game_state, self.player_id, self.pose) self.assertEqual(MoveToPosition.exec(self.move), AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": self.pose})) @unittest.skip("I don't know whuy the f**k it is broken here.") def test_idle(self): self.idle = Idle(self.game_state, self.player_id) current_pose = None current_pose_string = AICommand(self.player_id, AICommandType.STOP) self.assertEqual(Idle.exec(self.idle), current_pose_string) @unittest.skip("I don't know what the f**k is happening here.") def test_GrabBall(self): self.grab_ball = GetBall(self.game_state, self.player_id) self.game_state.game.ball.set_position(Position(5, 0), 0) ai_cmd = self.grab_ball.exec() ball_position = self.game_state.get_ball_position() destination_orientation = get_angle(self.game_state.get_player_pose(self.player_id).position, ball_position) destination_pose = {"pose_goal": Pose(ball_position, destination_orientation)} ai_cmd_expected = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": destination_pose}) self.assertEqual(ai_cmd, ai_cmd_expected) self.game_state.game.ball.set_position(Position(-5, 5), 0) ai_cmd = self.grab_ball.exec() ai_cmd_expected = AICommand(Pose(Position(-5, 5), 3*pi/4), 0) self.assertEqual(ai_cmd, ai_cmd_expected) @unittest.skip("LAZY ME OH HELL") def test_MoveWithBall(self): self.move_with_ball = MoveToDribblingBall(self.game_state, self.player_id, Position(100, 0)) self.game_state.game.ball.set_position(Position(5, 0), 0) ai_cmd = self.move_with_ball.exec() ai_cmd_expected = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(100, 0), 0)}) self.assertEqual(ai_cmd, ai_cmd_expected) self.game_state.game.ball.set_position(Position(5, 2), 0) ai_cmd = self.move_with_ball.exec() ai_cmd_expected = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(100, 0), atan(2/5))}) self.assertEqual(ai_cmd, ai_cmd_expected) @unittest.skip("I don't know whuy the f**k it is broken here.") def test_GoBetween(self): # test avec une droite verticale self.go_between = GoBetween(self.game_state, self.player_id, Position(100, 100), Position(100, -100), Position(200, 0)) ai_cmd = self.go_between.exec() ai_cmd_expected = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(100, 0), 0)}) self.assertEqual(ai_cmd, ai_cmd_expected) # test avec une droite horizontale self.go_between = GoBetween(self.game_state, self.player_id, Position(100, 100), Position(-100, 100), Position(0, 200)) ai_cmd = self.go_between.exec() ai_cmd_expected = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(0, 100), pi/2)}) self.assertEqual(ai_cmd, ai_cmd_expected) # test avec une droite quelconque self.go_between = GoBetween(self.game_state, self.player_id, Position(0, 500), Position(500, 0), Position(-300, -300)) ai_cmd = self.go_between.exec() ai_cmd_expected = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(250, 250), -3*pi/4)}) self.assertEqual(ai_cmd, ai_cmd_expected) # test destination calculée derrière position1 self.go_between = GoBetween(self.game_state, self.player_id, Position(1000, 75), Position(1500, -250), Position(0, 0), 180) ai_cmd = self.go_between.exec() ai_cmd_expected = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(1150, -23), 3.1215)}) self.assertEqual(ai_cmd, ai_cmd_expected) # test destination calculée derrière position2 self.go_between = GoBetween(self.game_state, self.player_id, Position(-100, 50), Position(-50, 50), Position(-60.0 + sqrt(3), 51.0), 10) ai_cmd = self.go_between.exec() ai_cmd_expected = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(-60, 50), 0.5235)}) self.assertEqual(ai_cmd, ai_cmd_expected) # test correction pour respecter la distance minimale self.go_between = GoBetween(self.game_state, self.player_id, Position(-500, 25), Position(1, 25), Position(-179, 0), 180) ai_cmd = self.go_between.exec() ai_cmd_expected = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(-179, 25), -pi/2)}) self.assertEqual(ai_cmd, ai_cmd_expected) # test distance entre les positions insuffisantes self.assertRaises(AssertionError, GoBetween, self.game_state, self.player_id, Position(1, 1), Position(-1, -1), 50) @unittest.skip("I don't know whuy the f**k it is broken here.") def test_GoBehind(self): # TODO: faire davantage de cas de test distance_behind = 500 # test avec une droite quelconque self.go_behind = GoBehind(self.game_state, self.player_id, Position(1.5, 2.3), Position(18.3, 27.8), distance_behind) aicmd_obtenu = GoBehind.exec(self.go_behind) aicmd_cible = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(-273, -415), 0.9882)}) # AICommand(Pose(Position(-273, -415), 0.9882), 0) self.assertEqual(aicmd_obtenu, aicmd_cible) # test avec une droite verticale self.go_behind = GoBehind(self.game_state, self.player_id, Position(1000, 250.3), Position(1000, 725.8), distance_behind) aicmd_obtenu = GoBehind.exec(self.go_behind) aicmd_cible = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(1000, -249), 1.5707)}) # AICommand(Pose(Position(1000, -249), 1.5707), 0) self.assertEqual(aicmd_obtenu, aicmd_cible) # test avec une droite horizontale self.go_behind = GoBehind(self.game_state, self.player_id, Position(175.8, -200.34), Position(-276.8, -200.34), distance_behind) aicmd_obtenu = GoBehind.exec(self.go_behind) aicmd_cible = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(675, -200), -3.1415)}) self.assertEqual(aicmd_obtenu, aicmd_cible) @unittest.skip("I don't know whuy the f**k it is broken here.") def test_kick(self): # test avec la valeur 0 (nulle) self.kick = Kick(self.game_state, self.player_id, 0) current_pose = self.game_state.get_player_pose(self.player_id) current_pose_string = AICommand(self.player_id, AICommandType.KICK, **{"pose_goal": current_pose}) self.assertEqual(Kick.exec(self.kick), current_pose_string) # test avec la valeur 1 (force maximale) self.kick = Kick(self.game_state, self.player_id, 1) current_pose = self.game_state.get_player_pose(self.player_id) self.assertEqual(Kick.exec(self.kick), AICommand(self.player_id, AICommandType.KICK, **{"pose_goal": current_pose})) # test avec la valeur 0.3 (force intermediaire) self.kick = Kick(self.game_state, self.player_id, 0.3) current_pose = self.game_state.get_player_pose(self.player_id) self.assertEqual(Kick.exec(self.kick), AICommand(self.player_id, AICommandType.KICK, **{"pose_goal": current_pose})) @unittest.skip("I got lazy, didn't want to review all of the protectgoal.") def test_ProtectGoal(self): # test de base self.game_state.game.friends.players[0].update(Pose(Position(4450, 10))) self.game_state.game.ball.set_position(Position(0, 0), 0) self.protectGoal = ProtectGoal(self.game_state, 0) aicmd_obtenu = self.protectGoal.exec() aicmd_cible = AICommand(self.player_id, AICommandType.MOVE, **{"pose_goal": Pose(Position(4000, 0), -pi)}) self.assertEqual(aicmd_obtenu, aicmd_cible) # test distance max < distance min self.assertRaises(AssertionError, ProtectGoal, self.game_state, 0, True, 50, 40)