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
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)
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
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
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)