乒乓球比赛
from random import random
from pandas import DataFramefrom time import timeclass SportCompetitionAnalyze: def PrintInfo(self): ''' function: 打印程序的介绍信息 ''' print("{:*^70}".format("产品简介")) print("产品名称: 乒乓球竞技模拟分析器(采取单打淘汰赛制)") print("产品概述: 通过输入多个队伍的能力值(0到1之间的小数表示),能够模拟多次多个队伍的乒乓球竞技比赛,从而得出各自的胜率!") print("产品作者: 步平凡 - 04") print("{:*^70}".format("模拟开始")) def GetInputs_for_Singal(self): ''' function: 获得用户输入的参数 获得单打各队员的能力值 ''' self.n = eval(input("请输入需要模拟比赛的场数:")) self.probAbilityList_Original = list(map(eval, input("(注:通过输入的次序进行两两配对, 即前两个分别为队员A和B;以此类推。)\n\ 请输入各队员的能力值(0~1), 请用英文逗号隔开(输入个数为2的倍数): ").split(','))) self.probAbilityList = self.probAbilityList_Original self.probNum = len(self.probAbilityList) def GetInputs_for_Double(self): ''' function: 获得用户输入的参数 获得双打各队伍各队员的能力值 probAbilityList: 使用各队伍中两队员的平均能力值作为该队伍的能力值 --- 双打 probAbilityList_Original: 存储原生的各队员能力值, 后续可用 ''' self.probAbilityList, self.probAbilityList_Original = [], [] self.n = eval(input("请输入需要模拟比赛的场数:")) Original = list(map(eval, input("(注:通过输入的次序进行四四配对, 即前四个为队伍A和B;以此类推。)\n\ 请输入各队员的能力值(0~1), 请用英文逗号隔开(输入个数为4的倍数): ").split(','))) for i in range(0, len(Original), 2): self.probAbilityList.append((Original[i] + Original[i+1])/2) self.probAbilityList_Original.append(list([Original[i], Original[i+1]])) self.probNum = len(self.probAbilityList) def PrintResult(self): ''' function: 输出模拟比赛的结果 data: 存储每支的比赛信息 ''' print("{:*^70}".format("模拟结束")) print("竞技分析结束,每组共模拟{}场比赛。".format(self.n)) data = [] for i in range(self.probNum): tmplist = [] tmplist.append(self.probAbilityList_Original[i]) # 存储能力值 tmplist.append(self.probwinsList[i]) # 存储获胜的场数 tmplist.append(self.probwinsList[i]/self.n) # 存储胜率 data.append(tmplist) dataSheet = DataFrame(data , index=list(range(1, self.probNum+1)), columns=list(["Ability", "wins", "rate"])) #dataSheet.sort_values(by="wins", inplace=True) # 对比赛胜率rate进行排序, 会混乱比赛队伍的关系, 因此不采用 print(dataSheet) def simNGames(self, GAMES, WINS): ''' function: 模拟n场比赛 probwinsList: 存储每支队伍赢得比赛的场数 的列表 winA, winB: 队伍A和B在一场比赛中获胜的局数 winsA, winsB: 队伍A和B赢得比赛的场数,总共n场 ''' self.probwinsList = [] for i in range(0, self.probNum, 2): print("队员:", i+1, 'VS' ,i+2, "比赛中...") winsA, winsB = 0, 0 for _ in range(self.n): winA, winB = self.simOneGame(self.probAbilityList[i], self.probAbilityList[i+1], GAMES, WINS) if winA > winB: winsA += 1 else: winsB += 1 self.probwinsList.append(winsA) self.probwinsList.append(winsB) def simOneGame(self, probA, probB, GAMES, WINS): ''' function: 模拟一场比赛 》》》 GAMES局 WINS胜 单打比赛,包括七局,采取七局四胜制 双打比赛,包括五局,采取五局三胜制 scoreA, scoreB: 分别为队伍A和B一局比赛的分数 winA, winB: 分别为队伍A和B一场比赛赢的局数 return: 返回双方赢的局数 ''' winA, winB = 0, 0 for _ in range(GAMES): scoreA, scoreB = self.simAGame(probA, probB) if scoreA > scoreB: winA += 1 else: winB += 1 if winA >=WINS or winB >= WINS: break return winA, winB def simAGame(self, probA, probB): ''' function: 模拟一局比赛 probA, probB: 分别为队伍A和B的能力值 return: 返回队伍A和B在本局比赛中获得的分数 ''' scoreA, scoreB = 0, 0 serving = 'A' # 发球方 servingNum = 2 # 每方的发球次数 while not self.GameOver(scoreA, scoreB): if scoreA >= 10 and scoreB >= 10: servingNum = 1 for _ in range(servingNum): if random() > probA: scoreB += 1 else: scoreA += 1 serving = 'B' for _ in range(servingNum): if random() > probB: scoreA += 1 else: scoreB += 1 serving = 'A' return scoreA, scoreB def GameOver(self, scoreA, scoreB): ''' function: 定义赢得一局的条件: 先得11分为胜,10平后,多得2分为胜 ''' if scoreA >= 11 or scoreB >= 11: return (abs(scoreA-scoreB)>=2) elif (scoreA == 10 and scoreB > 11) or (scoreB == 10 and scoreA > 11): return (abs(scoreA-scoreB)>=2) else: return 0def print_MENU(): print("程序简介:模拟乒乓球竞技") print("程序功能:\n\t1. 模拟多队员进行单打比赛\n\t2. 模拟多队伍多队员进行双打比赛") while 1: choose = input("功能选择:NO.") if choose in ['1', '2']: return eval(choose) else: print("输入有误, 请重新输入!")def simGameMenu(): choose = print_MENU() if choose == 1: pingpong = SportCompetitionAnalyze() pingpong.PrintInfo() pingpong.GetInputs_for_Singal() Time = time() pingpong.simNGames(7, 4) print("模拟用时: {:.1f}s".format(time()-Time)) pingpong.PrintResult() else: pingpong = SportCompetitionAnalyze() pingpong.PrintInfo() pingpong.GetInputs_for_Double() Time = time() pingpong.simNGames(5, 3) print("模拟用时: {:.1f}s".format(time()-Time)) pingpong.PrintResult()if __name__ == "__main__": simGameMenu()
浙公网安备 33010602011771号