python初體驗 ——>>> 模擬體育競技

python初體驗 ——>>> 模擬體育競技python

1、排球訓練營app

1. 簡介: 模擬不一樣的兩個隊伍進行排球的模擬比賽。dom

2. 模擬原理: 經過輸入各自的能力值(Ⅰ),模擬比賽的進行( P ),最後輸出模擬的結果( O )。函數

P 簡介:經過產生隨機數獲得每局比賽的難度,若小於能力值則表示贏得本局比賽,反之輸掉本局比賽。學習

3. 規則簡介:編碼

① 每場比賽採用 5局3勝制spa

② 前四局採用25分制,每一個隊只有在贏得至少25分,且同時超過對方2分時才勝一局。.net

③ 決勝局(第五局)採用15分制,先得到15分,且同時超過對方2分爲勝。code

4. 準備就緒,就差代碼來實現了orm

插入代碼以前,先對代碼作個簡單的介紹:

函數名稱 函數說明
printInfo()
打印程序的介紹信息
getInputs()
得到用戶輸入的參數
printResult(n, winsA, winsB)
輸出模擬比賽的結果
simNGames(n, probA, probB)
模擬 n場比賽
simOneGame(probA, probB)
模擬 一場比賽,包括五局,採起五局三勝制
simAGame(N, probA, probB)
模擬 一局比賽
GameOver(N, scoreA, scoreB)
定義 一局比賽的結束條件

好了,看看代碼吧,雖然有點長,但應該能夠看懂 ^_^

  1 # -*- encoding:utf-8 -*-
  2 '''
  3 模擬排球競技
  4 @author: bpf
  5 '''
  6 # 比賽規則:
  7 # 1. 採用5局3勝制
  8 # 2. 前四局採用25分制,每一個隊只有在贏得至少25分,且同時超過對方2分時才勝一局
  9 # 3. 決勝局(第五局)採用15分制,先得到15分,且同時超過對方2分爲勝
 10 
 11 from random import random
 12 from time import time
 13 def printInfo():
 14     '''
 15     function: 打印程序的介紹信息
 16     '''
 17     print("{:*^70}".format("產品簡介"))
 18     print("產品名稱: 排球競技模擬分析器")
 19     print("產品概述: 經過輸入2個隊伍A和B的能力值(0到1之間的小數表示),可以模擬屢次2個隊伍A和B的排球競技比賽,從而得出各自的勝率!")
 20     print("產品做者: 步平凡 - 04")
 21     print("{:*^70}".format("模擬開始"))
 22 
 23 def getInputs():
 24     '''
 25     function: 得到用戶輸入的參數
 26     '''
 27     probA = eval(input("請輸入隊伍A的能力值(0~1):"))
 28     probB = eval(input("請輸入隊伍B的能力值(0~1):"))
 29     n = eval(input("請輸入須要模擬比賽的場次數:"))
 30     return probA, probB, n
 31 
 32 def printResult(n, winsA, winsB):
 33     '''
 34     function: 輸出模擬比賽的結果
 35     '''
 36     print("{:*^70}".format("模擬結束"))
 37     print("競技分析開始,共模擬{}場比賽。".format(n))
 38     print(">>>隊伍A獲勝{}場比賽,佔比{:0.1%}".format(winsA,winsA/n))
 39     print(">>>隊伍B獲勝{}場比賽,佔比{:0.1%}".format(winsB,winsB/n))
 40 
 41 def simNGames(n, probA, probB):
 42     '''
 43     function: 模擬n場比賽
 44     n: 模擬n場比賽
 45     probA, probB: 分別爲隊伍A和B的能力值
 46     winA, winB: 隊伍A和B在一場比賽中獲勝的局數
 47     winsA, winsB: 隊伍A和B贏得比賽的場數,總共n場
 48     '''
 49     winsA, winsB = 0, 0
 50     for _ in range(n):
 51         winA, winB = simOneGame(probA, probB)
 52         if winA > winB:
 53             winsA += 1
 54         else:
 55             winsB += 1
 56     return winsA, winsB
 57 
 58 def simOneGame(probA, probB):
 59     '''
 60     function: 模擬一場比賽,包括五局,採起五局三勝制
 61     probA, probB: 分別爲隊伍A和B的能力值
 62     return: 返回隊伍A和B在本場比賽中獲勝的局數
 63     scoreA, scoreB: 分別爲隊伍A和B一局比賽得到的分數
 64     winA, winB: 分別爲隊伍A和B一場比賽獲勝的局數
 65     N: 表明本次比賽的局次
 66     '''
 67     winA, winB = 0, 0
 68     for N in range(5):
 69         scoreA, scoreB = simAGame(N, probA, probB)
 70         if scoreA > scoreB:
 71             winA += 1
 72         else:
 73             winB += 1
 74         if winA == 3 or winB == 3:
 75             break
 76     return winA, winB
 77 
 78 def simAGame(N, probA, probB):
 79     '''
 80     function: 模擬一局比賽
 81     N: 表明本次比賽的局次
 82     probA, probB: 分別爲隊伍A和B的能力值
 83     return: 返回隊伍A和B在本局比賽中得到的分數
 84     '''
 85     scoreA, scoreB = 0, 0    # 分別爲隊伍A和B一局比賽得到的分數
 86     serving = 'A'            # 發球方
 87     while not GameOver(N, scoreA, scoreB):
 88         if serving == 'A':
 89             if random() > probA:
 90                 scoreB += 1
 91                 serving = 'B'
 92             else:
 93                 scoreA += 1
 94         else:
 95             if random() > probB:
 96                 scoreA += 1
 97                 serving = 'A'
 98             else:
 99                 scoreB += 1
100     return scoreA, scoreB
101 
102 def GameOver(N, scoreA, scoreB):
103     '''
104     function: 定義一局比賽的結束條件
105     N: 表明當前局次(第五局爲決勝局)
106     return: 若比賽結束的條件成立返回真,不然爲假
107     '''
108     if N <= 4:
109         return (scoreA>=25 and abs(scoreA-scoreB)>=2) or (scoreB>=25 and abs(scoreA-scoreB)>=2)
110     else:
111         return (scoreA>=15 and abs(scoreA-scoreB)>=2) or (scoreB>=15 and abs(scoreA-scoreB)>=2)
112 
113 if __name__ == "__main__":
114     printInfo()
115     probA, probB, n = getInputs()
116     Time = time()
117     winsA, winsB = simNGames(n, probA, probB)
118     print("模擬用時: {:.1f}s".format(time()-Time))
119     printResult(n, winsA, winsB)

 

 

5. 運行結果展現,爲了查看方便,我在cmd中運行代碼

 

2、足球訓練基地

1. 簡介: 模擬不一樣的兩個隊伍進行足球的模擬比賽。

2. 模擬原理: 經過輸入各自的能力值(Ⅰ),模擬比賽的進行( P ),最後輸出模擬的結果( O )。

P 簡介:經過產生隨機數獲得半場比賽的回合數,再經過產生隨機數獲得每回合比賽的難度,若小於能力值則表示贏得本局比賽,反之輸掉本場比賽。

3. 規則簡介:

① 比賽分爲兩半場,每場爲45分鐘。

  上半場: 一方挑選進攻的球門,另外一方得到開球權;

  下半場: 互換攻守方向,上半場沒得到開球權的一方得到開球權。

②在進球后開球時,開球方爲失球一方。

③ 比賽結束時得分多的球隊獲勝,若是兩隊得分相同或均未得分,比賽爲平局。

4. 代碼實現

By the way, 此代碼與上述主要不一樣之處在於: GameOver(),其餘函數都相似

函數名稱 函數說明
printInfo() 打印程序的介紹信息
getInputs() 得到用戶輸入的參數
printResult(n, winsA, winsB) 輸出模擬比賽的結果
simNGames(n, probA, probB) 模擬n場比賽
simOneGame(probA, probB) 模擬一場比賽,包括上半場和下半場
simAGame(N, probA, probB) 模擬半場比賽
GameOver(N, scoreA, scoreB) 定義半場比賽的結束條件

 

  1 # -*- encoding:utf-8 -*-
  2 '''
  3 模擬足球競技
  4 @author: bpf
  5 '''
  6 # 比賽規則:
  7 # 1. 比賽分爲兩場,每場爲45分鐘
  8 #       上半場: 一方挑選進攻的球門,另外一方得到開球權
  9 #       下半場: 互換攻守方向,上半場沒得到開球權的一方得到開球權
 10 # 2. 在進球后開球時,開球方爲失球一方
 11 # 3. 在沒有違反任何比賽規則時,進攻球隊得分。
 12 # 4. 比賽結束時得分多的球隊獲勝,若是兩隊得分相同或均未得分,比賽爲平局。
 13 
 14 from random import random, randint
 15 from time import time
 16 def printInfo():
 17     '''
 18     function: 打印程序的介紹信息
 19     '''
 20     print("{:*^70}".format("產品簡介"))
 21     print("產品名稱: 足球競技模擬分析器")
 22     print("產品概述: 經過輸入2個隊伍A和B的能力值(0到1之間的小數表示),可以模擬屢次2個隊伍A和B的排球競技比賽,從而得出各自的勝率!")
 23     print("產品做者: 步平凡 - 04")
 24     print("{:*^70}".format("模擬開始"))
 25 
 26 def getInputs():
 27     '''
 28     function: 得到用戶輸入的參數
 29     '''
 30     probA = eval(input("請輸入隊伍A的能力值(0~1):"))
 31     probB = eval(input("請輸入隊伍B的能力值(0~1):"))
 32     n = eval(input("請輸入須要模擬比賽的場次數:"))
 33     return probA, probB, n
 34 
 35 def printResult(n, via, winsA, winsB):
 36     '''
 37     function: 輸出模擬比賽的結果
 38     '''
 39     print("{:*^70}".format("模擬結束"))
 40     print("競技分析開始,共模擬{}場比賽。".format(n))
 41     print(">>>隊伍A獲勝{}場比賽,佔比{:0.1%}".format(winsA,winsA/n))
 42     print(">>>隊伍B獲勝{}場比賽,佔比{:0.1%}".format(winsB,winsB/n))
 43     print(">>>兩隊平局{}場,佔比{:0.1%}".format(via,via/n))
 44 
 45 def simNGames(n, probA, probB):
 46     '''
 47     function: 模擬n場比賽
 48     n: 模擬n場比賽
 49     probA, probB: 分別爲隊伍A和B的能力值
 50     winsA, winsB: 隊伍A和B贏得比賽的場數,總共n場
 51     '''
 52     via, winsA, winsB = 0, 0, 0
 53     for _ in range(n):
 54         scoreA, scoreB = simOneGame(probA, probB)
 55         if scoreA == scoreB:
 56             via += 1
 57         elif scoreA > scoreB:
 58             winsA += 1
 59         else:
 60             winsB += 1
 61     return via, winsA, winsB
 62 
 63 def simOneGame(probA, probB):
 64     '''
 65     function: 模擬一場比賽, 分上半場和下半場
 66     probA, probB: 分別爲隊伍A和B的能力值
 67     scoreA, scoreB: 分別爲隊伍A和B一場比賽的分數
 68     return: 返回隊伍A和B在本場比賽中得到的分數
 69     '''
 70     winA, winB = 0, 0
 71     for N in range(2):
 72         scoreA, scoreB = simAGame(N, probA, probB)
 73         winA += scoreA
 74         winB += scoreB
 75     return winA, winB
 76 
 77 def simAGame(N, probA, probB):
 78     '''
 79     function: 模擬半場比賽
 80     probA, probB: 分別爲隊伍A和B的能力值
 81     scoreA, scoreB: 分別爲隊伍A和B半場比賽的分數
 82     return: 返回隊伍A和B在本半場比賽中得到的分數
 83     '''
 84     scoreA, scoreB = 0, 0
 85     if N == 0:
 86         serving = 'A'            # 發球方
 87     else:
 88         serving = 'B'
 89     for _ in range(gameOver()):
 90         if serving == 'A':
 91             if random() < probA:
 92                 scoreA += 1
 93                 serving = 'B'
 94         else:
 95             if random() < probB:
 96                 scoreB += 1
 97                 serving = 'A'
 98     return scoreA, scoreB
 99 
100 def gameOver():
101     '''
102     function: 定義半場比賽的結束條件
103     經過randint產生一個隨機數做爲半場比賽的回合數, 若達到半場比賽的回合數則結束比賽
104     return: 若比賽結束的條件成立返回真,不然爲假
105     '''
106     return randint(3, 10)
107 
108 if __name__ == "__main__":
109     printInfo()
110     probA, probB, n = getInputs()
111     Time = time()
112     via, winsA, winsB = simNGames(n, probA, probB)
113     print("模擬用時: {:.1f}s".format(time()-Time))
114     printResult(n, via, winsA, winsB)

 

5. 運行結果展現,爲了查看方便,我仍在cmd中運行代碼

 

3、晉級模擬

1. 簡介: 前2次分別對於排球和足球的模擬比賽分析,比賽規則的差距 體現 在代碼上的不一樣,因此本次模擬分析多支隊伍進行乒乓球比賽。

2. 模擬原理: 經過輸入各自的能力值(Ⅰ),模擬比賽的進行( P ),最後輸出模擬的結果( O )。

P 簡介:經過產生隨機數獲得每局比賽的難度,若小於能力值則表示贏得本局比賽,反之輸掉本局比賽。當有多個隊伍時,採起兩兩配對,但只遍歷一次,所以,本代碼功能不完善,僅供參考。

3. 規則簡介:

①  一場比賽: 單打:採用七局四勝制; 雙打淘汰賽、團體賽:採用五局三勝制。

② 一局比賽: 先得11分爲勝,10平後,多得2分爲勝

③ 一局比賽: 每隊發球2次後,接發球方即成爲發球方,依此類推,直至該局比賽結束 或者 到雙方比分都達到10分時,發球和接發次序仍然不變,但每隊只輪發一次球

4. 代碼實現

  本次代碼與上述不一樣,本次採用類的方法來實現,不過基於本人對於乒乓球不熟悉及python用法有限,本次代碼的功能有所限制,只能模擬數量爲偶數的隊伍進行比賽。待技術提高,會對代碼進行改善和增強。

  1 # -*- encoding:utf-8 -*-
  2 '''
  3 模擬乒乓球競技
  4 @author: bpf
  5 '''
  6 # 比賽規則:
  7 # 1. 一場比賽: 單打:採用七局四勝制
  8 #              雙打淘汰賽、團體賽:採用五局三勝制
  9 # 2. 一局比賽: 先得11分爲勝,10平後,多得2分爲勝
 10 # 3. 一局比賽: 每隊發球2次後,接發球方即成爲發球方,依此類推,直至該局比賽結束
 11 #            或者到雙方比分都達到10分時,發球和接發次序仍然不變,但每隊只輪發一次球
 12 
 13 from random import random
 14 from pandas import DataFrame
 15 from time import time
 16 class SportCompetitionAnalyze:
 17 
 18     def PrintInfo(self):
 19         '''
 20         function: 打印程序的介紹信息
 21         '''
 22         print("{:*^70}".format("產品簡介"))
 23         print("產品名稱: 乒乓球競技模擬分析器(採起單打淘汰賽制)")
 24         print("產品概述: 經過輸入多個隊伍的能力值(0到1之間的小數表示),可以模擬屢次多個隊伍的乒乓球競技比賽,從而得出各自的勝率!")
 25         print("產品做者: 步平凡 - 04")
 26         print("{:*^70}".format("模擬開始"))
 27     
 28     def GetInputs_for_Singal(self):
 29         '''
 30         function: 得到用戶輸入的參數 得到單打各隊員的能力值
 31         '''
 32         self.n = eval(input("請輸入須要模擬比賽的場數:"))
 33         self.probAbilityList_Original = list(map(eval, input("(注:經過輸入的次序進行兩兩配對, 即前兩個分別爲隊員A和B;以此類推。)\n\
 34             請輸入各隊員的能力值(0~1), 請用英文逗號隔開(輸入個數爲2的倍數): ").split(',')))
 35         self.probAbilityList = self.probAbilityList_Original
 36         self.probNum = len(self.probAbilityList)
 37     
 38     def GetInputs_for_Double(self):
 39         '''
 40         function: 得到用戶輸入的參數 得到雙打各隊伍各隊員的能力值
 41         probAbilityList: 使用各隊伍中兩隊員的平均能力值做爲該隊伍的能力值 --- 雙打
 42         probAbilityList_Original: 存儲原生的各隊員能力值, 後續可用
 43         '''
 44         self.probAbilityList, self.probAbilityList_Original = [], []
 45         self.n = eval(input("請輸入須要模擬比賽的場數:"))
 46         Original = list(map(eval, input("(注:經過輸入的次序進行四四配對, 即前四個爲隊伍A和B;以此類推。)\n\
 47             請輸入各隊員的能力值(0~1), 請用英文逗號隔開(輸入個數爲4的倍數): ").split(',')))
 48         for i in range(0, len(Original), 2):
 49             self.probAbilityList.append((Original[i] + Original[i+1])/2)
 50             self.probAbilityList_Original.append(list([Original[i], Original[i+1]]))
 51         self.probNum = len(self.probAbilityList)
 52     
 53     def PrintResult(self):
 54         '''
 55         function: 輸出模擬比賽的結果
 56         data: 存儲每支的比賽信息
 57         '''
 58         print("{:*^70}".format("模擬結束"))
 59         print("競技分析結束,每組共模擬{}場比賽。".format(self.n))
 60         data = []
 61         for i in range(self.probNum):
 62             tmplist = []
 63             tmplist.append(self.probAbilityList_Original[i])  # 存儲能力值
 64             tmplist.append(self.probwinsList[i])              # 存儲獲勝的場數
 65             tmplist.append(self.probwinsList[i]/self.n)       # 存儲勝率
 66             data.append(tmplist)
 67         dataSheet = DataFrame(data , index=list(range(1, self.probNum+1)), columns=list(["Ability", "wins", "rate"]))
 68         #dataSheet.sort_values(by="wins", inplace=True)       # 對比賽勝率rate進行排序, 會混亂比賽隊伍的關係, 所以不採用
 69         print(dataSheet)
 70 
 71     def simNGames(self, GAMES, WINS):
 72         '''
 73         function: 模擬n場比賽
 74         probwinsList: 存儲每支隊伍贏得比賽的場數 的列表
 75         winA, winB: 隊伍A和B在一場比賽中獲勝的局數
 76         winsA, winsB: 隊伍A和B贏得比賽的場數,總共n場
 77         '''
 78         self.probwinsList = []
 79         for i in range(0, self.probNum, 2):
 80             print("隊員:", i+1, 'VS' ,i+2, "比賽中...")
 81             winsA, winsB = 0, 0
 82             for _ in range(self.n):
 83                 winA, winB = self.simOneGame(self.probAbilityList[i], self.probAbilityList[i+1], GAMES, WINS)
 84                 if winA > winB:
 85                     winsA += 1
 86                 else:
 87                     winsB += 1
 88             self.probwinsList.append(winsA)
 89             self.probwinsList.append(winsB)
 90 
 91     def simOneGame(self, probA, probB, GAMES, WINS):
 92         '''
 93         function: 模擬一場比賽  》》》 GAMES局 WINS勝
 94                 單打比賽,包括七局,採起七局四勝制
 95                 雙打比賽,包括五局,採起五局三勝制
 96         scoreA, scoreB: 分別爲隊伍A和B一局比賽的分數
 97         winA, winB: 分別爲隊伍A和B一場比賽贏的局數
 98         return: 返回雙方贏的局數
 99         '''
100         winA, winB = 0, 0
101         for _ in range(GAMES):
102             scoreA, scoreB = self.simAGame(probA, probB)
103             if scoreA > scoreB:
104                 winA += 1
105             else:
106                 winB += 1
107             if winA >=WINS or winB >= WINS:
108                 break
109         return winA, winB
110 
111     def simAGame(self, probA, probB):
112         '''
113         function: 模擬一局比賽
114         probA, probB: 分別爲隊伍A和B的能力值
115         return: 返回隊伍A和B在本局比賽中得到的分數
116         '''
117         scoreA, scoreB = 0, 0
118         serving = 'A'              # 發球方
119         servingNum = 2             # 每方的發球次數
120         while not self.GameOver(scoreA, scoreB):
121             if scoreA >= 10 and scoreB >= 10:
122                 servingNum = 1
123             for _ in range(servingNum):
124                 if random() > probA:
125                     scoreB += 1
126                 else:
127                     scoreA += 1
128             serving = 'B'
129             for _ in range(servingNum):
130                 if random() > probB:
131                     scoreA += 1
132                 else:
133                     scoreB += 1
134             serving = 'A'
135         return scoreA, scoreB
136 
137     def GameOver(self, scoreA, scoreB):
138         '''
139         function: 定義贏得一局的條件: 先得11分爲勝,10平後,多得2分爲勝
140         '''
141         if scoreA >= 11 or scoreB >= 11:
142             return (abs(scoreA-scoreB)>=2)
143         elif (scoreA == 10 and scoreB > 11) or (scoreB == 10 and scoreA > 11):
144             return (abs(scoreA-scoreB)>=2)
145         else:
146             return 0
147     
148 def print_MENU():
149     print("程序簡介:模擬乒乓球競技")
150     print("程序功能:\n\t1. 模擬多隊員進行單打比賽\n\t2. 模擬多隊伍多隊員進行雙打比賽")
151     while 1:
152         choose = input("功能選擇:NO.")
153         if choose in ['1', '2']:
154             return eval(choose)
155         else:
156             print("輸入有誤, 請從新輸入!")
157     
158 def simGameMenu():
159     choose = print_MENU()
160     if choose == 1:
161         pingpong = SportCompetitionAnalyze()
162         pingpong.PrintInfo()
163         pingpong.GetInputs_for_Singal()
164         Time = time()
165         pingpong.simNGames(7, 4)
166         print("模擬用時: {:.1f}s".format(time()-Time))
167         pingpong.PrintResult()
168     else:
169         pingpong = SportCompetitionAnalyze()
170         pingpong.PrintInfo()
171         pingpong.GetInputs_for_Double()
172         Time = time()
173         pingpong.simNGames(5, 3)
174         print("模擬用時: {:.1f}s".format(time()-Time))
175         pingpong.PrintResult()
176 
177 if __name__ == "__main__":
178     simGameMenu()

 

5. 代碼寫好了,看一下運行效果怎麼樣唄 ^v^

Tips:爲了使用方便,能夠使用python的第三方庫pyinstaller進行打包,生成exe文件,能夠方便運行。

接下來,咱們試一下吧~~~

① 首先要安裝pyinstaller庫

在cmd中輸入下面一句代碼,詳情就不介紹了。

pip install pyinstaller

② 使用方法: pyinstaller  <文件名>    》具體使用方法

注: 使用pyinstaller時,路徑不能出現中文不然出現編碼出錯;最好在上述代碼的main函數的最後加上 input() 語句防止程序一運行完就自動退出

以後雙擊運行exe文件便可 ↓↓↓

 

 

好了,今天就分享到這裏,學習去咯~~~

相關文章
相關標籤/搜索