體育競技分析的IPO模式:
輸入I(input):兩個球員的能力值,模擬比賽的次數(其中,運動員的能力值,可以通過發球方贏得本回合的概率來表示,一個能力值為0.8的球員,在他發球時,有80%的可能性贏得1分)
處理P(process):模擬比賽過程
輸出O(output):兩個球員獲勝的概率
該體育競技程序,我們采用自頂向下的設計方法。
一、排球比賽的模擬
模擬不同的兩個隊伍進行排球的模擬比賽。
2. 模擬原理: 通過輸入各自的能力值(Ⅰ),模擬比賽的進行( P ),最后輸出模擬的結果( O )。
P 簡介:通過產生隨機數得到每局比賽的難度,若小於能力值則表示贏得本局比賽,反之輸掉本局比賽。
3. 規則簡介:
① 每場比賽采用 5局3勝制。
② 前四局采用25分制,每個隊只有在贏得至少25分,且同時超過對方2分時才勝一局。
③ 決勝局(第五局)采用15分制,先獲得15分,且同時超過對方2分為勝。
插入代碼之前,先對代碼做個簡單的介紹:
函數名稱 | 函數說明 |
printInfo() | 打印程序的介紹信息 |
getInputs() | 獲得用戶輸入的參數 |
printResult(n, winsA, winsB) | 輸出模擬比賽的結果 |
simNGames(n, probA, probB) | 模擬n場比賽 |
simOneGame(probA, probB) | 模擬一場比賽,包括五局,采取五局三勝制 |
simAGame(N, probA, probB) | 模擬一局比賽 |
GameOver(N, scoreA, scoreB) | 定義一局比賽的結束條件 |
# -*- encoding:utf-8 -*- from random import random def printInfo(): ''' function: 打印程序的介紹信息 ''' print("產品名稱: 排球比賽模擬分析器") print("產品概述: 通過輸入2個隊伍A和B的能力值(0到1之間的小數表示),能夠模擬多次2個隊伍A和B的排球競技比賽,從而得出各自的勝率!") print("產品作者: 林崇宇 - 14\n") def getInputs(): ''' function: 獲得用戶輸入的參數 ''' probA = eval(input("請輸入隊伍A的能力值(0~1):")) probB = eval(input("請輸入隊伍B的能力值(0~1):")) n = eval(input("請輸入需要模擬比賽的場次數:")) return probA, probB, n def simNGames(n, probA, probB): ''' function: 模擬n場比賽 n: 模擬n場比賽 probA, probB: 分別為隊伍A和B的能力值 winA, winB: 隊伍A和B在一場比賽中獲勝的局數 winsA, winsB: 隊伍A和B贏得比賽的場數,總共n場 ''' winsA, winsB = 0, 0 for _ in range(n): winA, winB = simOneGame(probA, probB) if winA > winB: winsA += 1 else: winsB += 1 return winsA, winsB def simOneGame(probA, probB): ''' function: 模擬一場比賽,包括五局,采取五局三勝制 probA, probB: 分別為隊伍A和B的能力值 return: 返回隊伍A和B在本場比賽中獲勝的局數 scoreA, scoreB: 分別為隊伍A和B一局比賽獲得的分數 winA, winB: 分別為隊伍A和B一場比賽獲勝的局數 ''' n = 1 # 代表本次比賽的局次 winA, winB = 0, 0 for _ in range(5): scoreA, scoreB = simNGame(n, probA, probB) if scoreA > scoreB: winA += 1 else: winB += 1 n += 1 if winA == 3 or winB == 3: break return winA, winB def simNGame(n, probA, probB): ''' function: 模擬一局比賽 N: 代表本次比賽的局次 probA, probB: 分別為隊伍A和B的能力值 return: 返回隊伍A和B在本局比賽中獲得的分數 ''' scoreA, scoreB = 0, 0 # 分別為隊伍A和B一局比賽獲得的分數 serving = 'A' # 發球方 while not GameOver(n, scoreA, scoreB): if serving == 'A': if random() > probA: scoreB += 1 serving = 'B' else: scoreA += 1 if serving == 'B': if random() > probB: scoreA += 1 serving = 'A' else: scoreB += 1 return scoreA, scoreB def GameOver(n, scoreA, scoreB): ''' function: 定義一局比賽的結束條件 N: 代表當前局次(第五局為決勝局) return: 若比賽結束的條件成立返回真,否則為假 ''' if n <= 4: return (scoreA>=25 and abs(scoreA-scoreB)>=2) or (scoreB>=25 and abs(scoreA-scoreB)>=2) else: return (scoreA>=15 and abs(scoreA-scoreB)>=2) or (scoreB>=15 and abs(scoreA-scoreB)>=2) def printResult(n, winsA, winsB): ''' function: 輸出模擬比賽的結果 ''' print("競技分析開始,共模擬{}場比賽。".format(n)) print(">>>隊伍A獲勝{}場比賽,占比{:0.1%}".format(winsA,winsA/n)) print(">>>隊伍B獲勝{}場比賽,占比{:0.1%}".format(winsB,winsB/n)) def main(): printInfo() probA,probB,n=getInputs() winsA,winsB=simNGames(n,probA,probB) printResult(n,winsA,winsB) main()
二、籃球賽事的模擬
賽事規則:
1.1 籃球比賽
籃球比賽由兩個隊參加,每隊出場5名隊員。每隊目標是在對方球籃得分,並阻止對方隊在本方球籃得分。
籃球比賽由裁判員、記錄台人員和技術代表(如到場)管理。
1.2 球籃:本方/對方
被某隊進攻的球籃是對方的球籃,由某隊防守的球籃是本方的球籃。
1.3 比賽的勝者
在比賽時間結束時得分較多的隊,將是比賽的勝者。
代碼解釋:
函數名 | 函數說明 |
printIntro | 打印程序的介紹信息 |
getInputs | 輸入選手的能力值 |
simNGame(n,proA,proB) | n場比賽 |
gameOver(a,b) | 比賽的結束約束條件 |
simOneGame(proA,proB) | 一局比賽 |
printsummary(winsA,winsB) | 比賽結果 |
# -*- coding: utf-8 -*- """ Created on Mon May 13 19:46:23 2019 @author: 18 EliO FanG """ from math import fabs from random import random def printIntro(): ''' function: 打印程序的介紹信息 ''' print("模擬籃球比賽的代碼分析") print("這個程序模擬兩支隊伍A和B的籃球比賽") print("程序運行需要A和B的能力值(以0到1之間的小數表示)") print("作者:18 EliO FanG\n") def getInputs(): a = eval(input("請輸入A隊的能力值(0-1): ")) b = eval(input("請輸入B隊的能力值(0-1): ")) n = eval(input("模擬比賽的場次: ")) return a, b, n def simNGames(n, probA, probB): winsA, winsB = 0, 0 for i in range(n): scoreA, scoreB = simOneGame(probA, probB) if scoreA > scoreB: winsA += 1 else: winsB += 1 return winsA, winsB def gameOver(a,b): return a>b or b>a def simOneGame(probA, probB): scoreA, scoreB = 0, 0 serving = "A" while not gameOver(scoreA, scoreB): if serving == "A": if random() < probA: scoreA += 1 else: serving="B" else: if random() < probB: scoreB += 1 else: serving="A" return scoreA, scoreB def printSummary(winsA, winsB): n = winsA + winsB print("籃球比賽分析開始,共模擬{}場比賽".format(n)) print("A隊獲勝{}場比賽,占比{:0.1%}".format(winsA, winsA/n)) print("B隊獲勝{}場比賽,占比{:0.1%}".format(winsB, winsB/n)) def main(): printIntro() probA, probB, n = getInputs() winsA, winsB = simNGames(n, probA, probB) printSummary(winsA, winsB) main()
關鍵是誰先發球
三、羽毛球比賽模擬
賽事規則:
1. 21 分制,3局2勝為佳
2. 每球得分制
3. 每回合中,取勝的一方加 1 分
4. 當雙方均為 20 分時,領先對方 2 分的一方贏得該局比賽
5. 當雙方均為 29 分時,先取得 30 分的一方贏得該局比賽
6. 一局比賽的獲勝方在下一局率先發球
# -*- coding: utf-8 -*- """ Created on Mon May 13 19:46:23 2019 @author: 18 EliO FanG """ from math import fabs from random import random def printIntro(): ''' function: 打印程序的介紹信息 ''' print("模擬羽毛球比賽的代碼分析") print("這個程序模擬兩個選手A和B的羽毛球比賽") print("程序運行需要A和B的能力值(以0到1之間的小數表示)") print("作者:18 EliO FanG\n") def getInputs(): a = eval(input("請輸入選手A的能力值(0-1): ")) b = eval(input("請輸入選手B的能力值(0-1): ")) n = eval(input("模擬比賽的場次: ")) return a, b, n def simNGames(n, probA, probB): winsA, winsB = 0, 0 for i in range(n): scoreA, scoreB = simOneGame(probA, probB) if scoreA > scoreB: winsA += 1 else: winsB += 1 return winsA, winsB def gameOver(a,b): if (a==20 and b==20): return a==22 or b==22 if(a==29 and b==29): return a==30 or b==30 else: return a==21 or b==21 def simOneGame(probA, probB): scoreA, scoreB = 0, 0 serving = "A" while not gameOver(scoreA, scoreB): if serving == "A": if random() < probA: scoreA += 1 else: serving="B" else: if random() < probB: scoreB += 1 else: serving="A" return scoreA, scoreB def printSummary(winsA, winsB): n = winsA + winsB print("羽毛球比賽分析開始,共模擬{}場比賽".format(n)) print("選手A獲勝{}場比賽,占比{:0.1%}".format(winsA, winsA/n)) print("選手B獲勝{}場比賽,占比{:0.1%}".format(winsB, winsB/n)) def main(): printIntro() probA, probB, n = getInputs() winsA, winsB = simNGames(n, probA, probB) printSummary(winsA, winsB) main()
# -*- coding: utf-8 -*- """ Created on Mon May 13 19:46:23 2019 @author: 18 EliO FanG """ from math import fabs from random import random def printIntro(): ''' function: 打印程序的介紹信息 ''' print("模擬羽毛球比賽的代碼分析") print("這個程序模擬兩個選手A和B的羽毛球比賽") print("程序運行需要A和B的能力值(以0到1之間的小數表示)") print("作者:18 EliO FanG\n") def getInputs(): a = eval(input("請輸入選手A的能力值(0-1): ")) b = eval(input("請輸入選手B的能力值(0-1): ")) n = eval(input("模擬比賽的場次: ")) return a, b, n def simNGames(n, probA, probB): winsA, winsB = 0, 0 for i in range(n): scoreA, scoreB = simOneGame(probA, probB) if scoreA > scoreB: winsA += 1 else: winsB += 1 return winsA, winsB def gameOver(a,b): if (a==20 and b==20): return a==22 or b==22 if(a==29 and b==29): return a==30 or b==30 else: return a==21 or b==21 def simOneGame(probA, probB): scoreA, scoreB = 0, 0 serving = "A" while not gameOver(scoreA, scoreB): if serving == "A": if random() < probA: scoreA += 1 else: serving="B" else: if random() < probB: scoreB += 1 else: serving="A" return scoreA, scoreB def printSummary(winsA, winsB): n = winsA + winsB print("羽毛球比賽分析開始,共模擬{}場比賽".format(n)) print("選手A獲勝{}場比賽,占比{:0.1%}".format(winsA, winsA/n)) print("選手B獲勝{}場比賽,占比{:0.1%}".format(winsB, winsB/n)) def main(): printIntro() probA, probB, n = getInputs() winsA, winsB = simNGames(n, probA, probB) printSummary(winsA, winsB) main()
四、在python中,為了更加方便的顯示出結果,則可以用里面的pyinstaller打包可以執行的文件,生成exe文件,則可以直接運行結果。
1.首先要安裝pyinstaller庫
在cmd中輸入下面一句代碼:
pip install pyinstaller
2.使用pyinstaller時;在上述代碼的main函數的最后加上 input() 語句,防止程序一運行完就自動退出。
3.運行結果在pyinstaller中的顯示:
記得結尾加input()