python自顶向下的设计方法进行体育竞技分析

时间:2022-11-09 23:38:50

本文尝试采用自顶向下的设计方法进行体育竞技分析。

基本规则:

两个球员,交替用球拍击球。一方首先具有发球权,双方连续击打,球落地则该回合结束。

如果输掉这一回合的是发球方,双方均不加分,但发球权要交给另一方。如果发球方赢得了这一回合,则发球方赢得1分,并继续拥有发球权。

首先到达15分的一方赢得本局比赛,比赛总共进行n 局。

使用python3编写程序,模拟比赛过程,统计在n 局比赛中2个球员各自赢了几局比赛并计算获胜的概率。。。

 

体育竞技分析的IPO模式:

输入I(input):两个球员的能力值,模拟比赛的次数(其中,运动员的能力值,可以通过发球方赢得本回合的概率来表示,

            一个能力值为0.8的球员,在他发球时,有80%的可能性赢得1分)

处理P(process):模拟比赛过程

输出O(output):两个球员获胜的概率

 

该体育竞技程序,我们采用自顶向下的设计方法。

自顶向下的设计是一种解决复杂问题的行之有效的方法。其步骤如下:

python自顶向下的设计方法进行体育竞技分析

自顶向下设计的基本思想,如下图:

python自顶向下的设计方法进行体育竞技分析


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次,第一次结果如下:

python自顶向下的设计方法进行体育竞技分析

上图说明,2个球员的能力值相差很大时,比赛结果呈现出压倒性趋势,与现实中的实际比赛相符。

第二次结果如下:

python自顶向下的设计方法进行体育竞技分析

生活中有这样一种现象,2个球员,尽管能力上只有很小的差距,但是能力稍差的球员经常被能力稍强的球员击败。

上图解释了这种现象,尽管能力差别小,但能力值稍小的球员,大概需要进行3局比赛,才能赢一局,可见,他赢得一场3局或5局的比赛可能性很小。。。

(完)