体育竞技分析

import random
import pandas as pd
import matplotlib.pyplot as plt
from collections import defaultdict

class TableTennisMatch:
def init(self, player_a, player_b, best_of=7):
"""
初始化比赛
:param player_a: 选手A名称
:param player_b: 选手B名称
:param best_of: 总局数 (7表示七局四胜,5表示五局三胜)
"""
self.players = (player_a, player_b)
self.best_of = best_of
self.max_wins = (best_of // 2) + 1
self.results = {
'match_winner': None,
'games': [],
'score': {player_a: 0, player_b: 0}
}

    # 选手能力值 (可调整)
    self.skill = {
        player_a: random.uniform(0.4, 0.7),
        player_b: random.uniform(0.4, 0.7)
    }

def play_point(self, server):
    """
    模拟一分的争夺
    :param server: 发球方
    :return: 得分方
    """
    receiver = self.players[1] if server == self.players[0] else self.players[0]
    
    # 发球方优势 (发球方有60%概率得分)
    if random.random() < 0.6 * self.skill[server] / (self.skill[server] + self.skill[receiver]):
        return server
    return receiver

def play_game(self):
    """
    模拟一局比赛 (先得11分胜,10平后需赢2分)
    :return: 胜者
    """
    scores = {self.players[0]: 0, self.players[1]: 0}
    server = random.choice(self.players)  # 随机选择首局发球方
    
    while True:
        point_winner = self.play_point(server)
        scores[point_winner] += 1
        
        # 判断是否达到局点
        if scores[point_winner] >= 11 and abs(scores[self.players[0]] - scores[self.players[1]]) >= 2:
            return point_winner
        
        # 交换发球权 (每2分交换一次)
        if sum(scores.values()) % 2 == 0:
            server = self.players[1] if server == self.players[0] else self.players[0]

def play_match(self):
    """
    模拟整场比赛 (七局四胜或五局三胜)
    """
    while max(self.results['score'].values()) < self.max_wins:
        game_winner = self.play_game()
        self.results['score'][game_winner] += 1
        self.results['games'].append(game_winner)
    
    self.results['match_winner'] = max(self.results['score'].items(), key=lambda x: x[1])[0]
    return self.results

class TournamentSimulator:
def init(self, players, is_team=False):
"""
初始化锦标赛
:param players: 选手列表
:param is_team: 是否为团体/双打比赛
"""
self.players = players
self.is_team = is_team
self.best_of = 5 if is_team else 7 # 团体/双打五局三胜,单打七局四胜
self.stats = defaultdict(lambda: {'matches_won': 0, 'games_won': 0, 'points_diff': 0})

def simulate_round(self, remaining_players):
    """
    模拟一轮比赛
    :param remaining_players: 当前轮次选手
    :return: 晋级选手
    """
    winners = []
    for i in range(0, len(remaining_players), 2):
        if i+1 >= len(remaining_players):
            winners.append(remaining_players[i])  # 轮空
            continue
        
        player_a, player_b = remaining_players[i], remaining_players[i+1]
        match = TableTennisMatch(player_a, player_b, self.best_of)
        result = match.play_match()
        
        # 更新统计数据
        winner = result['match_winner']
        loser = player_b if winner == player_a else player_a
        self.stats[winner]['matches_won'] += 1
        self.stats[winner]['games_won'] += result['score'][winner]
        self.stats[winner]['points_diff'] += (result['score'][winner] - result['score'][loser])
        
        self.stats[loser]['games_won'] += result['score'][loser]
        self.stats[loser]['points_diff'] += (result['score'][loser] - result['score'][winner])
        
        winners.append(winner)
    
    return winners

def simulate_tournament(self):
    """
    模拟整个淘汰赛
    :return: 冠军
    """
    remaining_players = self.players.copy()
    round_num = 1
    
    while len(remaining_players) > 1:
        print(f"\nRound {round_num}: {', '.join(remaining_players)}")
        remaining_players = self.simulate_round(remaining_players)
        round_num += 1
    
    champion = remaining_players[0]
    print(f"\n冠军是: {champion}!")
    return champion, self.stats

def analyze_performance(self):
    """
    分析比赛数据并生成报告
    """
    df = pd.DataFrame.from_dict(self.stats, orient='index')
    df['win_rate'] = df['matches_won'] / (len(self.players)-1) * 100  # 每场比赛都是淘汰赛
    
    print("\n选手表现分析:")
    print(df.sort_values(by='matches_won', ascending=False))
    
    # 可视化
    df['matches_won'].sort_values().plot(kind='barh', title='比赛胜利次数')
    plt.xlabel('胜利次数')
    plt.ylabel('选手')
    plt.show()

示例使用

if name == "main":
# 单打比赛示例
print("=== 乒乓球单打淘汰赛模拟 ===")
singles_players = [f"选手{i+1}" for i in range(16)] # 16位选手
singles_simulator = TournamentSimulator(singles_players, is_team=False)
champion, stats = singles_simulator.simulate_tournament()
singles_simulator.analyze_performance()

# 团体/双打比赛示例
print("\n=== 乒乓球团体/双打淘汰赛模拟 ===")
teams = [f"队伍{i+1}" for i in range(8)]  # 8支队伍
team_simulator = TournamentSimulator(teams, is_team=True)
team_champion, team_stats = team_simulator.simulate_tournament()
team_simulator.analyze_performance()
posted @ 2025-06-23 14:04  cchb  阅读(15)  评论(0)    收藏  举报