乒乓球比赛模拟分析程序

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

class TableTennisGame:
def init(self, player1, player2, win_games=4):
"""初始化乒乓球比赛"""
self.player1 = player1 # 选手1
self.player2 = player2 # 选手2
self.win_games = win_games # 赢得比赛需要的局数,默认为4(七局四胜)
self.player1_games = 0 # 选手1赢得的局数
self.player2_games = 0 # 选手2赢得的局数
self.match_history = [] # 比赛历史记录
self.set_history = [] # 每局比赛记录

def simulate_point(self, player1_skill, player2_skill):
    """
    模拟一次得分
    返回:得分的选手(1或2)
    """
    # 技能影响得分概率,skill值越高,得分概率越高
    probability = player1_skill / (player1_skill + player2_skill)
    return 1 if random.random() < probability else 2

def simulate_set(self, player1_skill, player2_skill):
    """
    模拟一局比赛
    返回:赢得该局的选手(1或2)和该局的得分记录
    """
    player1_score = 0
    player2_score = 0
    score_history = []  # 记录每得分后的比分
    
    while True:
        # 模拟一次得分
        point_winner = self.simulate_point(player1_skill, player2_skill)
        
        # 更新比分
        if point_winner == 1:
            player1_score += 1
        else:
            player2_score += 1
        
        # 记录当前比分
        score_history.append((player1_score, player2_score))
        
        # 检查是否有选手获胜
        if player1_score >= 11 or player2_score >= 11:
            # 10平后需要领先2分才能获胜
            if abs(player1_score - player2_score) >= 2:
                break
    
    return point_winner, score_history

def simulate_match(self, player1_skill=50, player2_skill=50, show_process=True):
    """
    模拟整场比赛
    返回:比赛结果统计
    """
    while self.player1_games < self.win_games and self.player2_games < self.win_games:
        # 模拟一局比赛
        set_winner, score_history = self.simulate_set(player1_skill, player2_skill)
        self.set_history.append(score_history)
        
        # 更新局数
        if set_winner == 1:
            self.player1_games += 1
        else:
            self.player2_games += 1
        
        # 记录比赛历史
        self.match_history.append({
            "set": len(self.set_history),
            "winner": set_winner,
            "score": score_history[-1]
        })
        
        if show_process:
            print(f"第{len(self.set_history)}局: {'{} {} - {} {}'.format(
                self.player1, score_history[-1][0], score_history[-1][1], self.player2)}")
            print(f"当前局数: {'{} {} - {} {}'.format(
                self.player1, self.player1_games, self.player2_games, self.player2)}")
            print()
    
    # 确定比赛获胜者
    match_winner = 1 if self.player1_games >= self.win_games else 2
    
    if show_process:
        print(f"比赛结束! {self.player1 if match_winner == 1 else self.player2}获胜!")
        print(f"最终局数: {'{} {} - {} {}'.format(
            self.player1, self.player1_games, self.player2_games, self.player2)}")
    
    return {
        "winner": match_winner,
        "player1_games": self.player1_games,
        "player2_games": self.player2_games,
        "set_details": self.set_history
    }

def visualize_match(self):
    """可视化比赛结果"""
    if not self.match_history:
        print("没有比赛历史记录可供可视化")
        return
    
    # 准备数据
    sets = list(range(1, len(self.match_history) + 1))
    player1_set_scores = [score[0] for score in [match["score"] for match in self.match_history]]
    player2_set_scores = [score[1] for score in [match["score"] for match in self.match_history]]
    
    # 绘制每局比分
    plt.figure(figsize=(10, 6))
    plt.bar(sets, player1_set_scores, label=self.player1, color='blue', alpha=0.7)
    plt.bar(sets, player2_set_scores, label=self.player2, color='red', alpha=0.7, bottom=player1_set_scores)
    plt.xlabel('局数')
    plt.ylabel('比分')
    plt.title('乒乓球比赛每局比分情况')
    plt.xticks(sets)
    plt.legend()
    plt.grid(True, linestyle='--', alpha=0.7)
    plt.tight_layout()
    
    # 显示比赛结果
    result_text = f"最终结果: {self.player1} {self.player1_games} - {self.player2_games} {self.player2}"
    plt.figtext(0.5, 0.01, result_text, ha="center", fontsize=12, bbox=dict(facecolor='yellow', alpha=0.5))
    
    plt.show()
    
    # 绘制关键局比分变化
    if len(self.set_history) > 0:
        plt.figure(figsize=(12, 8))
        for i, set_scores in enumerate(self.set_history):
            set_num = i + 1
            player1_scores = [score[0] for score in set_scores]
            player2_scores = [score[1] for score in set_scores]
            points = list(range(1, len(set_scores) + 1))
            
            plt.subplot(2, (len(self.set_history) + 1) // 2, set_num)
            plt.plot(points, player1_scores, 'b-', label=self.player1)
            plt.plot(points, player2_scores, 'r-', label=self.player2)
            plt.xlabel('得分回合')
            plt.ylabel('比分')
            plt.title(f'第{set_num}局比分变化')
            plt.legend()
            plt.grid(True, linestyle='--', alpha=0.7)
            plt.tight_layout()
        
        plt.show()

主函数:运行比赛模拟

def main():
# 创建比赛实例(七局四胜制)
game = TableTennisGame("马龙", "樊振东", win_games=4)

# 模拟比赛(假设马龙技能值55,樊振东技能值45)
result = game.simulate_match(player1_skill=55, player2_skill=45)

# 输出比赛统计信息
print("\n=== 比赛统计 ===")
print(f"获胜者: {game.player1 if result['winner'] == 1 else game.player2}")
print(f"{game.player1} 胜局数: {result['player1_games']}")
print(f"{game.player2} 胜局数: {result['player2_games']}")

# 可视化比赛结果
game.visualize_match()

if name == "main":
main()

posted @ 2025-06-21 15:21  你好book  阅读(15)  评论(0)    收藏  举报