点击查看代码
import random
from collections import defaultdict
import sys
class Team:
"""球队类"""
def __init__(self, name, strength):
"""
初始化球队
:param name: 球队名称
:param strength: 球队实力值(0-1之间)
"""
self.name = name
self.strength = strength
self.wins = 0 # 胜利场次
self.losses = 0 # 失败场次
self.points = 0 # 积分
self.games_won = 0 # 赢得的局数
self.games_lost = 0 # 输掉的局数
def reset_stats(self):
"""重置比赛统计"""
self.wins = 0
self.losses = 0
self.points = 0
self.games_won = 0
self.games_lost = 0
def __str__(self):
"""球队信息字符串表示"""
return (f"{self.name} (实力值: {self.strength:.2f}) - "
f"胜场: {self.wins}, 负场: {self.losses}, "
f"积分: {self.points}, 净胜局: {self.games_won - self.games_lost}")
class MatchSimulator:
"""比赛模拟器"""
@staticmethod
def simulate_point(prob):
"""
模拟一个球的胜负
:param prob: 获胜概率
:return: 获胜方 (True 或 False)
"""
return random.random() < prob
@staticmethod
def simulate_game(prob_a, prob_b):
"""
模拟一局比赛
:param prob_a: A队获胜概率
:param prob_b: B队获胜概率
:return: (A队得分, B队得分)
"""
score_a, score_b = 0, 0
while True:
# 计算当前球A队的获胜概率
current_prob = prob_a / (prob_a + prob_b)
if MatchSimulator.simulate_point(current_prob):
score_a += 1
else:
score_b += 1
# 检查比赛结束条件(常规结束)
if score_a >= 11 or score_b >= 11:
if abs(score_a - score_b) >= 2:
break
# 处理10平后的特殊情况
if score_a == 10 and score_b == 10:
while abs(score_a - score_b) < 2:
current_prob = prob_a / (prob_a + prob_b)
if MatchSimulator.simulate_point(current_prob):
score_a += 1
else:
score_b += 1
break
return score_a, score_b
@staticmethod
def simulate_match(team_a, team_b, required_wins=3):
"""
模拟一场比赛(五局三胜制)
:param team_a: A队
:param team_b: B队
:param required_wins: 获胜所需局数
:return: 获胜队, 比赛记录
"""
wins_a, wins_b = 0, 0
match_history = []
# 最多进行5局
for game_num in range(1, 6):
score_a, score_b = MatchSimulator.simulate_game(team_a.strength, team_b.strength)
match_history.append((game_num, score_a, score_b))
if score_a > score_b:
wins_a += 1
else:
wins_b += 1
# 检查比赛是否提前结束
if wins_a == required_wins or wins_b == required_wins:
break
# 更新球队统计数据
team_a.games_won += wins_a
team_a.games_lost += wins_b
team_b.games_won += wins_b
team_b.games_lost += wins_a
# 确定获胜方并更新积分
if wins_a > wins_b:
team_a.wins += 1
team_b.losses += 1
team_a.points += 3
return team_a, match_history
else:
team_b.wins += 1
team_a.losses += 1
team_b.points += 3
return team_b, match_history
class Tournament:
"""锦标赛类"""
def __init__(self, teams):
"""
初始化锦标赛
:param teams: 参赛队伍列表
"""
self.teams = teams
self.results = []
def reset_tournament(self):
"""重置锦标赛数据"""
for team in self.teams:
team.reset_stats()
self.results = []
def play_round_robin(self):
"""进行循环赛"""
n = len(self.teams)
self.reset_tournament()
print("\n===== 循环赛开始 =====")
for i in range(n):
for j in range(i + 1, n):
team_a = self.teams[i]
team_b = self.teams[j]
print(f"\n比赛: {team_a.name} vs {team_b.name}")
winner, match_history = MatchSimulator.simulate_match(team_a, team_b)
# 打印每局比分
print(f"{team_a.name} vs {team_b.name} 比赛结果:")
for game_num, score_a, score_b in match_history:
print(f" 第{game_num}局: {team_a.name} {score_a}-{score_b} {team_b.name}")
print(f">>> 胜者: {winner.name}\n")
self.results.append((team_a, team_b, winner))
print("===== 循环赛结束 =====")
def get_standings(self):
"""获取排名"""
# 按积分 > 净胜局 > 实力值排序
return sorted(self.teams, key=lambda x: (x.points, x.games_won - x.games_lost, x.strength), reverse=True)
def print_standings(self):
"""打印排名"""
standings = self.get_standings()
print("\n===== 最终排名 =====")
print("排名\t球队\t\t胜场\t负场\t积分\t净胜局")
print("-" * 50)
for i, team in enumerate(standings, 1):
print(f"{i}\t{team.name:10}\t{team.wins}\t{team.losses}\t{team.points}\t{team.games_won - team.games_lost}")
# 打印冠军
if standings:
print("\n🏆 冠军:", standings[0].name)
def print_intro():
"""打印介绍信息"""
print("=" * 70)
print("乒乓球比赛模拟系统 (学号后两位: 02)")
print("本程序模拟乒乓球团体赛(五局三胜制)的循环赛")
print("=" * 70)
print("操作说明:")
print("1. 输入参赛队伍数量")
print("2. 为每支队伍输入名称和实力值(0-1之间)")
print("3. 程序将模拟完整的循环赛")
print("4. 查看最终排名")
print("=" * 70)
def get_team_info():
"""获取球队信息"""
teams = []
try:
num_teams = int(input("\n请输入参赛队伍数量 (至少2支): "))
if num_teams < 2:
print("队伍数量至少为2!")
sys.exit(1)
for i in range(num_teams):
print(f"\n输入第 {i+1} 支队伍信息:")
name = input(" 队伍名称: ")
while True:
try:
strength = float(input(" 队伍实力值 (0.0-1.0): "))
if 0.0 <= strength <= 1.0:
break
else:
print(" 实力值必须在0.0到1.0之间!")
except ValueError:
print(" 请输入有效的数字!")
teams.append(Team(name, strength))
except ValueError:
print("输入无效!")
sys.exit(1)
return teams
def main():
"""主函数"""
# 1. 打印介绍信息
print_intro()
# 2. 获取输入
teams = get_team_info()
# 3. 创建锦标赛并进行循环赛
tournament = Tournament(teams)
tournament.play_round_robin()
# 4. 输出排名
tournament.print_standings()
# 5. 显示获胜概率
print("\n===== 各队获胜概率分析 =====")
total_matches = len(teams) * (len(teams) - 1) // 2
for team in tournament.get_standings():
win_rate = (team.wins / total_matches) * 100 if total_matches > 0 else 0
print(f"{team.name}: 胜率 {win_rate:.1f}% ({team.wins}/{total_matches} 场)")
if __name__ == "__main__":
main()
![]()