예제 #1
0
    def calculate_stat(self, proto_stat, game: Game, proto_game: game_pb2.Game,
                       player_map: Dict[str,
                                        Player], data_frame: pd.DataFrame):
        if not is_dropshot(game):
            return

        tile_stats = {}
        damaged = 0
        destroyed = 0

        for event in game.dropshot['damage_events']:
            for tile_damage in event['tiles']:
                tile_id = tile_damage[0]
                if tile_id not in tile_stats:
                    tile_stats[tile_id] = 1
                else:
                    tile_stats[tile_id] += 1

                if tile_damage[1] == 1:
                    damaged += 1
                elif tile_damage[1] == 2:
                    destroyed += 1

        for tile_id, total_damage in tile_stats.items():
            damage_stat_proto = proto_game.game_stats.dropshot_stats.tile_stats.damage_stats.add(
            )
            damage_stat_proto.id = tile_id
            damage_stat_proto.total_damage = total_damage

        proto_game.game_stats.dropshot_stats.tile_stats.damaged_tiles = damaged
        proto_game.game_stats.dropshot_stats.tile_stats.destroyed_tiles = destroyed
예제 #2
0
    def calculate_player_stat(self, player_stat_map: Dict[str, PlayerStats],
                              game: Game, proto_game: game_pb2.Game,
                              player_map: Dict[str, Player],
                              data_frame: pd.DataFrame):
        if not is_dropshot(game):
            return

        player_stats = {}

        for key, val in player_map.items():
            player_stats[key] = {'total': 0, 'max': 0}

        for event in game.dropshot['damage_events']:
            ball_phase = data_frame['ball',
                                    'dropshot_phase'].loc[event['frame_number']
                                                          - 1]
            max_dmg = 1
            if ball_phase == 1:
                max_dmg = 7
            elif ball_phase == 2:
                max_dmg = 19
            player_id = event['player'].online_id
            player_stats[player_id]['total'] += len(event['tiles'])
            player_stats[player_id]['max'] += max_dmg

        self.apply_damage_stats(player_stat_map, player_stats)
예제 #3
0
    def calculate_stat(self, proto_stat, game: Game, proto_game: game_pb2.Game, player_map: Dict[str, Player],
                       data_frame: pd.DataFrame):
        if not is_dropshot(game):
            return

        tile_positions = get_tile_positions(game.map)

        if tile_positions is None:
            log.warning(f'Unsupported dropshot map: {game.map}')
            return

        for goal in proto_game.game_metadata.goals:
            frame = goal.frame_number

            # get the ball position at goal
            ball_pos = data_frame['ball'].loc[frame].loc[['pos_x', 'pos_y', 'pos_z']]

            # get the closest tile
            team = player_map[goal.player_id.id].is_orange
            closest_distance = TILE_DIAMETER
            closest_id = -1

            opponent_tile_ids = get_team_tiles(game.map, team ^ 1)
            opponent_tiles = [tile_positions[i] for i in opponent_tile_ids]

            for tile_id, tile in enumerate(opponent_tiles):

                d = math.sqrt(
                    math.pow(ball_pos['pos_x'] - tile[0], 2) +
                    math.pow(ball_pos['pos_y'] - tile[1], 2) +
                    math.pow(ball_pos['pos_z'] - tile[2], 2)
                )

                if d < closest_distance:
                    closest_distance = d
                    closest_id = tile_id if team == 1 else tile_id + 70

            if closest_id != -1:
                goal.extra_mode_info.dropshot_tile.id = closest_id

            # find the previous damage frame
            damage_frame = max(filter(lambda x: x <= frame, game.dropshot['tile_frames'].keys()))

            # get the team tile states
            tile_states = {k: v for (k, v) in game.dropshot['tile_frames'][damage_frame].items() if k in opponent_tile_ids}

            # get number of damaged tiles
            damaged_tiles = sum(1 for _ in filter(lambda x: x == 1, tile_states.values()))
            destroyed_tiles = sum(1 for _ in filter(lambda x: x == 2, tile_states.values()))

            goal.extra_mode_info.phase_1_tiles = damaged_tiles
            goal.extra_mode_info.phase_2_tiles = destroyed_tiles
예제 #4
0
    def calculate_stat(self, proto_stat, game: Game, proto_game: game_pb2.Game,
                       player_map: Dict[str,
                                        Player], data_frame: pd.DataFrame):
        if not is_dropshot(game):
            return

        phase_air_times = [[], [], []]

        all_events = list(
            map(lambda x: (x['frame_number'], x['state']),
                game.dropshot['ball_events']))
        all_events.extend(
            map(lambda x: (x['frame_number'], 0),
                game.dropshot['damage_events']))
        all_events.sort(key=lambda x: x[0])

        current_frame = data_frame['ball'].index[0]
        current_phase = 0

        for ball_event in all_events:
            if ball_event[1] == current_phase:
                continue

            phase_time = data_frame['game', 'time'].loc[
                ball_event[0]] - data_frame['game', 'time'].loc[current_frame]
            phase_air_times[current_phase].append(phase_time)

            current_frame = ball_event[0]
            current_phase = ball_event[1]

        # last phase
        phase_time = data_frame['game', 'time'].iloc[-1] - data_frame[
            'game', 'time'].loc[current_frame]
        phase_air_times[current_phase].append(phase_time)

        for phase, times in enumerate(phase_air_times):
            phase_stat_proto = proto_game.game_stats.ball_stats.extra_mode.dropshot_phase_stats.add(
            )
            phase_stat_proto.phase = phase
            if len(times) > 0:
                phase_stat_proto.average = np.mean(times)
                phase_stat_proto.max = max(times)
                phase_stat_proto.total = sum(times)
            else:
                phase_stat_proto.average = 0
                phase_stat_proto.max = 0
                phase_stat_proto.total = 0
예제 #5
0
    def calculate_team_stat(self, team_stat_list: Dict[int, TeamStats],
                            game: Game, proto_game: game_pb2.Game,
                            player_map: Dict[str, Player],
                            data_frame: pd.DataFrame):
        if not is_dropshot(game):
            return

        team_stats = {0: {'total': 0, 'max': 0}, 1: {'total': 0, 'max': 0}}

        for event in game.dropshot['damage_events']:
            ball_phase = data_frame['ball',
                                    'dropshot_phase'].loc[event['frame_number']
                                                          - 1]
            max_dmg = 1
            if ball_phase == 1:
                max_dmg = 7
            elif ball_phase == 2:
                max_dmg = 19

            team = player_map[event['player'].online_id].is_orange
            team_stats[team]['total'] += len(event['tiles'])
            team_stats[team]['max'] += max_dmg

        self.apply_damage_stats(team_stat_list, team_stats)