乒乓球比赛模拟分析程序
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()