本文尝试采用自顶向下的设计方法进行体育竞技分析。
基本规则:
两个球员,交替用球拍击球。一方首先具有发球权,双方连续击打,球落地则该回合结束。
如果输掉这一回合的是发球方,双方均不加分,但发球权要交给另一方。如果发球方赢得了这一回合,则发球方赢得1分,并继续拥有发球权。
首先到达15分的一方赢得本局比赛,比赛总共进行n 局。
使用python3编写程序,模拟比赛过程,统计在n 局比赛中2个球员各自赢了几局比赛并计算获胜的概率。。。
体育竞技分析的IPO模式:
输入I(input):两个球员的能力值,模拟比赛的次数(其中,运动员的能力值,可以通过发球方赢得本回合的概率来表示,
一个能力值为0.8的球员,在他发球时,有80%的可能性赢得1分)
处理P(process):模拟比赛过程
输出O(output):两个球员获胜的概率
该体育竞技程序,我们采用自顶向下的设计方法。
自顶向下的设计是一种解决复杂问题的行之有效的方法。其步骤如下:
自顶向下设计的基本思想,如下图:
python3的源代码如下:
#体育竞技分析程序
#顶层设计(第一阶段)
from random import *
def main():
printIntroduce()#打印程序的介绍信息
#通过getInputs()来获取
# 2个球员的能力值(每场比赛中每一回合获胜的可能性)和比赛次数
probabilityA,probabilityB,n=getInputs()
#通过simulateNGames()求得2个球员在n次比赛中获胜的次数
winsA,winsB=simulateNGames(n,probabilityA,probabilityB)
#通过printSummary()来输出比赛的结果信息
printSummary(winsA,winsB)
#第二阶段
def printIntroduce():
print('This program simulates a game between two players,A and B')
print('Probability (a number between 0 and 1) is used!')
def getInputs():
a=eval(input('What is the probability of player A wins?'))
b=eval(input('What is the probability of player B wins?'))
n=eval(input('How many games to simulate?'))
return a,b,n
def simulateNGames(n,probabilityA,probabilityB):
#定义球员A,B赢得比赛的次数,初始值为0
winsA=0
winsB=0
#通过for循环来模拟n场比赛
for i in range(n):
#simulateOneGame()用来模拟一场比赛
#输入为球员的能力值,即每场比赛中每一回合获胜的可能性
#返回的是本场比赛2个球员的得分
#根据返回的得分来确定本场比赛的胜负
scoreA,scoreB=simulateOneGame(probabilityA,probabilityB)
if scoreA>scoreB:
winsA+=1
else:
winsB=winsB+1
return winsA,winsB
def printSummary(winsA,winsB):
n=winsA+winsB
print('\nGames simulated:%d' % n)
print('Wins for A:{0}({1:.1%})'.format(winsA,winsA/n))
print('Wins for B:{0}({1:0.1%})'.format(winsB,winsB/n))
#第三阶段
def simulateOneGame(probabilityA,probabilityB):
#每场比赛,2个球员的得分初始为0
scoreA=0
scoreB=0
#本场比赛谁先发球(设定每场比赛总是球员A先发球)
starting='A'
while not gameOver(scoreA,scoreB):
if starting=='A':
#random()函数用来生成一个随机小数,范围在区间 [0,1)内
if random()<probabilityA:
scoreA+=1
else:
starting='B'
else:
if random()<probabilityB:
scoreB=scoreB+1
else:
starting='A'
return scoreA,scoreB
def gameOver(a,b):#任意一方得到15分就结束比赛
return a==15 or b==15
if __name__=='__main__':
main()
运行程序2次,第一次结果如下:
上图说明,2个球员的能力值相差很大时,比赛结果呈现出压倒性趋势,与现实中的实际比赛相符。
第二次结果如下:
生活中有这样一种现象,2个球员,尽管能力上只有很小的差距,但是能力稍差的球员经常被能力稍强的球员击败。
上图解释了这种现象,尽管能力差别小,但能力值稍小的球员,大概需要进行3局比赛,才能赢一局,可见,他赢得一场3局或5局的比赛可能性很小。。。
(完)