1.体育竞技分析:

体育竞技分析:模拟N场比赛
计算思维:抽象 + 自动化
模拟:抽象比赛过程,自动模拟N场比赛,当N越大时,比赛结果分析越科学。


2.比赛规则:(以排球为例)

赛制规定:

排球前4局比赛采用25分制,每队只有赢得至少25分,并同时超过对方2分时 ,才胜1局。
正式比赛采用5局3胜制,决胜局的比赛采用15分制,一队先得8分后,两队交换场区,按原位置顺序继续比赛到结束。
在决胜局(第五局)之比赛,先获15分并领先对方2分为胜。

 

3.思维方式:

自顶向下即将一个复杂问题分解成几个问题,再细分成一个个具体的小问题,从而来解决复杂问题。自底向上为自顶向下的逆过程,即在解决复杂问题的方法,逐步解决一个个小问题,来达成目的。

4.体育竞技分析:

程序结构图:(顶层设计)

(1)打印程序的介绍性信息式

输出一些介绍信息,针对提升用户体验十分有益。其中,printIntro()函数打印一些必要的说明

输入代码为:

 

def main()
      printIntro()

 

(2)输入I(input):两个球员(球队)的能力值,模拟比赛次数(n)

获得用户输入利用函数将输入的语句及输入格式等细节进行封装或隐藏,调用getInput()函数,取变量probA,probB和n的值,输入代码为:

 

def main()
      printIntro()
probA,probB,n=getInput()

 

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

使用probA,probB模拟n场的比赛。设计一个simNGames()函数来模拟n场比赛,并返回结果。程序的代码为:

 

def main():
      printIntro()
      probA,probB,n=getInputs()
      winsA,winsB=simNGames(n,probA,probB)

 

(4)输出(output):两个球员(球队)获胜的概率,代码如下:

 

def main():
      printIntro()
      probA,probB,n=getInputs()
      winsA,winsB=simNGames(n,probA,probB)
      printSummary(winsA,winsB)

 

上面的每层函数进行设计,这个过程有益于我们进行编程。。。。

 

下面以常规比赛规则为例,假设选手A的能力值为0.6,选手B的能力值为0.4,模拟比赛的场次为n=1000。

输入代码为:

 

#e15.1MatchAnalysis.py
from random import random
def printIntro():
    print("25号模拟两个选手A和B的排球竞技比赛")
    print("程序运行需要A和B的能力值(以0到1之间的小数表示)")
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==15 or b==15
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)


(2)

(3)

 

..............................................

通过上面的学习,我们以排球比赛规则为例,输入代码为:

 

# -*- encoding:utf-8 -*-
'''
模拟排球竞技
@author: bpf
'''
# 比赛规则:
# 1. 采用5局3胜制
# 2. 前四局采用25分制,每个队只有在赢得至少25分,且同时超过对方2分时才胜一局
# 3. 决胜局(第五局)采用15分制,先获得15分,且同时超过对方2分为胜

from random import random
def printInfo():
    '''
    function: 打印程序的介绍信息
    '''
    print(" 排球竞技模拟分析器")
    print("  25号小棠裁判")

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 = simAGame(N, probA, probB)
        if scoreA > scoreB:
            winA += 1
        else:
            winB += 1
        N += 1
        if winA == 3 or winB == 3:
            break
    return winA, winB

def simAGame(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 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))

if __name__ == "__main__":
    printInfo()
    probA, probB, n = getInputs()
    winsA, winsB = simNGames(n, probA, probB)
    printResult(n, winsA, winsB)

 

其结果显示为:

 ,,,,,,,,,,,,,,,,,,,

(5)运用pyinstaller打包可以执行的文件。

 pyinstaller 是一个十分有用的第三方库,它能够在Windows、Linux、等操作系统下将python 原文件打包,因为python脚本如果在没有安装python的电脑上,其代码不能运行,所以要将脚本打包成exe文件,使降低脚本对环境的依赖性,同时运行会更加迅速。

安装方法:在电脑的控制台上用pip工具安装,代码如下:

:\>pip install pyisntaller

:\>pip3 install pyisntaller


再或者可以通过 pyinstaller的官网进行下载。

利用 pyinstaller进行文件打包,该文件名为wenji.py.打包输入代码为:

:\>pip pyisntaller -F D:\codes\wenji.py

此次的python经验交流结束啦!!!