預測球隊比賽成績

今天我來學習如何經過python設計出一個用於預測比賽結果的代碼python

在預測結果以前,咱們須要進行周全的賽前分析,對於比賽中的各類做用因素進行有效分析dom

例如參賽選手的能力值,賽制規則等,這些都是做爲比賽的變量會左右比賽的結果,咱們經過自頂向下,從簡到難的方式進行一步步地分解,設計學習

下面是經過分析乒乓球比賽所設計出的代碼:spa

from random import random
def printIntro():
    print("這個程序模擬兩個選手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==11 or b==11
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獲勝{}場比賽,佔比{:.1%}".format(winsA,winsA/n))
    print("選手B獲勝{}場比賽,佔比{:.1%}".format(winsB,winsB/n))
def main():
    printIntro()
    probA,probB,n = getInputs()
    winsA,winsB = simNGames(n,probA,probB)
    printSummary(winsA,winsB)
main()

 根據以上的代碼咱們整理一下思路,這是一段經過「頂層設計」編寫出來的代碼,經過一些封裝,咱們對不一樣的動做進行解釋設計

咱們瞭解到一局乒乓球比賽的規則是,發球方發球,進行「兩球制」發球,即兩人固定輪流連續開兩球,不論勝負,誰分數先到達11分即勝利3d

因爲還有考慮最後平手時加球的狀況,但上述代碼暫不考慮,因此咱們來看看代碼的運算效果:
code

輸入兩個選手的能力值,我設置爲各0.5,但結果雖較接近但仍是有些許差距,排除random()的偏差,咱們知道這是比較符合現實的一種狀況!orm

咱們再試試能力值有細微差距的狀況:blog

 

wow!看來僅僅只是一點點的實力差距就會有天壤之別的比賽結果……get

咱們再深刻分析,加入更多的因素,咱們知道乒乓球的賽制時單打七局四勝制,雙打則是五局三勝制,因此咱們先用如下代碼預測單打狀況:

from random import random
def printIntro():
    print("這個程序模擬兩個選手A和B的某種比賽")
    print("程序運行須要A和B的能力值(0到1之間)")
def getInputs():
    a=eval(input("請輸入選手A的能力值(0-1):"))
    b=eval(input("請輸入選手B的能力值(0-1):"))
    return a,b
def simNGames(probA,probB):
    winsA,winsB=0,0
    for i in range(7):
        scoreA,scoreB=simOneGame(probA,probB)
        if scoreA>scoreB:
            winsA+=1
            if winsA==4:
                break
        else:
            winsB+=1
            if winsB==4:
                break
    return winsA,winsB
def gameOver(a,b):
    return a==11 or b==11
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獲勝{}場比賽,佔比{:.1%}".format(winsA,winsA/n))
    print("選手B獲勝{}場比賽,佔比{:.1%}".format(winsB,winsB/n))
def main():
    printIntro()
    probA,probB = getInputs()
    winsA,winsB = simNGames(probA,probB)
    printSummary(winsA,winsB)
main()

咱們再試試結果:

咱們看到,A選手最終以4-2擊敗B選手,即便他們能力幾乎至關,也許他當下更有手感吧~

接下來是雙打時,咱們將剛剛的A/B選手抽象爲A/B隊伍,能力值爲隊伍的平均能力值。

from random import random
def printIntro():
    print("這個程序模擬兩個選手A和B的某種比賽")
    print("程序運行須要A和B的能力值(0到1之間)")
def getInputs():
    a=eval(input("請輸入選手A的能力值(0-1):"))
    b=eval(input("請輸入選手B的能力值(0-1):"))
    return a,b
def simNGames(probA,probB):
    winsA,winsB=0,0
    for i in range(5):
        scoreA,scoreB=simOneGame(probA,probB)
        if scoreA>scoreB:
            winsA+=1
            if winsA==3:
                break
        else:
            winsB+=1
            if winsB==3:
                break
    return winsA,winsB
def gameOver(a,b):
    return a==11 or b==11
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獲勝{}場比賽,佔比{:.1%}".format(winsA,winsA/n))
    print("選手B獲勝{}場比賽,佔比{:.1%}".format(winsB,winsB/n))
def main():
    printIntro()
    probA,probB = getInputs()
    winsA,winsB = simNGames(probA,probB)
    printSummary(winsA,winsB)
main()

結果:A隊伍以3-2贏得雙打比賽~

接下來咱們分析籃球賽事,咱們知道籃球是一項團隊的運動,因此左右比賽的走向的的變量更加多首先是運動員的人數較多,場上每一隊應該有5名隊員在場,場下有4-5名替補隊員,這樣加起來雙方隊伍參賽隊員將在14-20個,同時能力值有不一樣,且若精確到每一次進攻,那麼就會有進攻成功及進攻失敗,或進攻一次伴隨着搶板以後再次補籃等多種複雜狀況……因爲現實的多變性,考慮到本次只是簡單的模擬,我對現實進行理想化,只討論場上每隊主力5名隊員的能力值,並經過各值推出該隊平均能力值,因爲籃球比賽以時間做爲指標,在指定時間內得到分數最高者勝,因此咱們將其簡化爲:在必定時間內,只能有有限次的進攻次數,根據現實狀況,咱們設置爲:200次(雙方進攻總數),因而有了下面的代碼:

from random import random
import time as T

def printIntro():
    print("這個程序模擬兩支球隊A和B的籃球比賽")
    print("程序運行須要A隊和B隊的能力值(0到1之間)")
def getInputs():
    print("如今請分別輸入A隊中上場的五位球員的能力值")
    a=eval(input("請輸入選手1的能力值(0-1):"))
    b=eval(input("請輸入選手2的能力值(0-1):"))
    c=eval(input("請輸入選手3的能力值(0-1):"))
    d=eval(input("請輸入選手4的能力值(0-1):"))
    e=eval(input("請輸入選手5的能力值(0-1):"))
    print("如今請分別輸入B隊中上場的五位球員的能力值")
    f=eval(input("請輸入選手6的能力值(0-1):"))
    g=eval(input("請輸入選手7的能力值(0-1):"))
    h=eval(input("請輸入選手8的能力值(0-1):"))
    i=eval(input("請輸入選手9的能力值(0-1):"))
    j=eval(input("請輸入選手10的能力值(0-1):"))
    meanA=(a+b+c+d+e)/5
    meanB=(f+g+h+i+j)/5
    print("A隊的平均能力值爲{0},B隊的平均能力值爲{1}".format(meanA,meanB))
    return meanA,meanB
def simOneAttack(probA,probB,):
    scoreA,scoreB = 0,0
    serving = 'A'
    for i in range(200):
        if serving == 'A':
            if random()<probA:
                scoreA+=2
            else:
                serving='B'
        else:
            if random()<probB:
                scoreB+=2
            else:
                serving='A'
    print("最終A隊得分爲{0},B隊爲{1}".format(scoreA,scoreB))
    print("隊伍A獲勝機率爲{:.1%}".format(scoreA/200))
    print("隊伍B獲勝機率爲{:.1%}".format(scoreB/200))
    print("平手機率(不加時):{:.1%}".format(1-(scoreA/200)-(scoreB/200)))
    return scoreA,scoreB 
def main():
    printIntro()
    probA,probB = getInputs()
    print("競技分析開始,共模擬200次進攻")

    simOneAttack(probA,probB)
main()

結果以下圖:

分別輸入各個隊伍主力球員的能力值,求出各隊伍平均能力值,並最終預測比賽得分爲:A:B=86:110

這是咱們預測了一次比賽的結果。

咱們繼續分析,在NBA的規則中,須要先在本土30支隊伍中經過進行82場常規賽決出8強,因而咱們對其進行變體來預測A/B兩支隊伍進行多場比賽後的結果:

from random import random
import time as T

def printIntro():
    print("這個程序模擬兩支球隊A和B的籃球比賽")
    print("程序運行須要A隊和B隊的能力值(0到1之間)")
def getInputs():
    print("如今請分別輸入A隊中上場的五位球員的能力值")
    a=eval(input("請輸入選手1的能力值(0-1):"))
    b=eval(input("請輸入選手2的能力值(0-1):"))
    c=eval(input("請輸入選手3的能力值(0-1):"))
    d=eval(input("請輸入選手4的能力值(0-1):"))
    e=eval(input("請輸入選手5的能力值(0-1):"))
    print("如今請分別輸入B隊中上場的五位球員的能力值")
    f=eval(input("請輸入選手6的能力值(0-1):"))
    g=eval(input("請輸入選手7的能力值(0-1):"))
    h=eval(input("請輸入選手8的能力值(0-1):"))
    i=eval(input("請輸入選手9的能力值(0-1):"))
    j=eval(input("請輸入選手10的能力值(0-1):"))
    meanA=(a+b+c+d+e)/5
    meanB=(f+g+h+i+j)/5
    print("A隊的平均能力值爲{0},B隊的平均能力值爲{1}".format(meanA,meanB))
    return meanA,meanB
def simNGames(probA,probB):
    winsA,winsB=0,0
    for i in range(82):
        scoreA,scoreB=simOneAttack(probA,probB)
        if scoreA>scoreB:
            winsA+=1
        else:
            winsB+=1
    print("最終A隊得分爲{0},B隊爲{1}".format(scoreA,scoreB))
    return winsA,winsB
def simOneAttack(probA,probB,):
    scoreA,scoreB = 0,0
    serving = 'A'
    for i in range(200):
        if serving == 'A':
            if random()<probA:
                scoreA+=2
            else:
                serving='B'
        else:
            if random()<probB:
                scoreB+=2
            else:
                serving='A'

    return scoreA,scoreB
def printSummary(winsA,winsB):
    n=winsA+winsB
    print("競技分析開始,共模擬{}場比賽".format(82))
    print("隊伍A獲勝{}場比賽,佔比{:.1%}".format(winsA,winsA/n))
    print("隊伍B獲勝{}場比賽,佔比{:.1%}".format(winsB,winsB/n))
def main():
    printIntro()
    probA,probB = getInputs()
    print("競技分析開始,共模擬200次進攻")
    simOneAttack(probA,probB)
    winsA,winsB = simNGames(probA,probB)
    printSummary(winsA,winsB)
main()

結果:

對30支隊伍進行簡化,只用44支隊伍相互角逐:

相關文章
相關標籤/搜索