예제 #1
0
class TestGameStateManager(unittest.TestCase):
    """
        Teste les différentes fonctionnalités du GameStateManager
    """
    def setUp(self):
        self.field = Field.Field(Ball.Ball())
        self.my_team = Team.Team(True)
        self.other_team = Team.Team(False)
        self.GameStateManager1 = GameState()
        self.GameStateManager2 = GameState()

    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)

    def test_update_ball_position(self):
        new_ball_position = Position.Position(1500, 1500, 0)
        self.GameStateManager2._update_ball_position(new_ball_position)
        self.assertEqual(new_ball_position,
                         self.GameStateManager1.get_ball_position())

    def test_update_field(self):
        new_ball_position = Position.Position(2500, 2500, 0)
        self.field.move_ball(new_ball_position, 5)
        self.GameStateManager2._update_field(self.field)
        self.assertEqual(self.GameStateManager1.get_ball_position(),
                         new_ball_position)

    def test_update_player(self):
        new_player_pose = Pose.Pose(Position.Position(1700, 1700, 0), 25)
        self.GameStateManager2._update_player(3, new_player_pose, True)
        self.assertEqual(new_player_pose,
                         self.GameStateManager1.get_player_pose(3, True))
        self.GameStateManager2._update_player(3, new_player_pose, False)
        self.assertEqual(new_player_pose,
                         self.GameStateManager1.get_player_pose(3, False))

    def test_update_team(self):
        new_player_pose = Pose.Pose(Position.Position(1000, 1000, 0), 25)
        for i in range(PLAYER_PER_TEAM):
            self.my_team.move_and_rotate_player(i, new_player_pose)
            new_player_pose.position += 200
        self.GameStateManager2._update_team(self.my_team, True)
        for i in range(PLAYER_PER_TEAM):
            self.assertEqual(self.GameStateManager1.get_player_pose(i, True),
                             self.my_team.players[i].pose)

        new_player_pose = Pose.Pose(Position.Position(1000, 1000, 0), 25)
        for i in range(PLAYER_PER_TEAM):
            self.other_team.move_and_rotate_player(i, new_player_pose)
            new_player_pose.position += 100
        self.GameStateManager2._update_team(self.other_team, False)
        for i in range(PLAYER_PER_TEAM):
            self.assertEqual(self.GameStateManager1.get_player_pose(i, False),
                             self.other_team.players[i].pose)

    def test_update_timestamp(self):
        new_timestamp = 123.25
        self.GameStateManager2._update_timestamp(new_timestamp)
        self.assertEqual(self.GameStateManager1.timestamp, new_timestamp)

    def test_update(self):
        new_timestamp = 145.36
        new_ball_position = Position.Position(500, 500, 0)
        self.field.move_ball(new_ball_position, 5)

        new_player_pose = Pose.Pose(Position.Position(1000, 1000, 0), 25)
        for i in range(PLAYER_PER_TEAM):
            self.my_team.move_and_rotate_player(i, new_player_pose)
            new_player_pose.position += 200

        new_player_pose = Pose.Pose(Position.Position(1000, 1000, 0), 25)
        for i in range(PLAYER_PER_TEAM):
            self.other_team.move_and_rotate_player(i, new_player_pose)
            new_player_pose.position += 100

        new_game_state = r_GameState(field=self.field,
                                     referee=Referee.Referee(),
                                     friends=self.my_team,
                                     enemies=self.other_team,
                                     timestamp=new_timestamp,
                                     debug='Test')

        self.GameStateManager2.update(new_game_state)
        self.assertEqual(new_game_state.field.ball.position,
                         self.GameStateManager1.get_ball_position())
        for i in range(PLAYER_PER_TEAM):
            self.assertEqual(self.GameStateManager1.get_player_pose(i, False),
                             self.other_team.players[i].pose)
            self.assertEqual(self.GameStateManager1.get_player_pose(i, False),
                             self.other_team.players[i].pose)
        self.assertEqual(new_game_state.timestamp,
                         self.GameStateManager1.timestamp)
예제 #2
0
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.')