1. 程式人生 > 其它 >模擬體育競技-羽毛球

模擬體育競技-羽毛球

模擬體育競技-羽毛球

# -*- encoding:utf-8 -*-
'''
模擬羽毛球競技
@author: bpf
'''

from random import random
from time import time
def printInfo():
    print("{:*^70}".format("模擬開始"))

def getInputs():
    '''
    function: 獲得使用者輸入的引數
    '''
    probA = eval(input("請輸入隊伍A的能力值(0~1):"))
    probB = eval(input("請輸入隊伍B的能力值(0~1):"))
    n = eval(input("請輸入需要模擬比賽的場次數:"))
    return probA, probB, n

def printResult(n, winsA, winsB):
    '''
    function: 輸出模擬比賽的結果
    '''
    print("{:*^70}".format("模擬結束"))
    print("競技分析開始,共模擬{}場比賽。".format(n))
    print(">>>隊伍A獲勝{}場比賽,佔比{:0.1%}".format(winsA,winsA/n))
    print(">>>隊伍B獲勝{}場比賽,佔比{:0.1%}".format(winsB,winsB/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: 代表本次比賽的局次
    '''
    winA, winB = 0, 0
    for N in range(3):
        scoreA, scoreB = simAGame(N, probA, probB)
        if scoreA > scoreB:
            winA += 1
        else:
            winB += 1
        if winA == 2 or winB == 2:
            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
        else:
            if random() > probB:
                scoreA += 1
                serving = 'A'
            else:
                scoreB += 1
    return scoreA, scoreB

def GameOver(N, scoreA, scoreB):
    '''
    function: 定義一局比賽的結束條件
    N: 代表當前局次(第五局為決勝局)
    return: 若比賽結束的條件成立返回真,否則為假
    '''
    if N <= 2:
        return (scoreA>=21 and abs(scoreA-scoreB)>=2) or (scoreB>=21 and abs(scoreA-scoreB)>=2)
    else:
        return (scoreA>=30 and abs(scoreA-scoreB)>=2) or (scoreB>=30 and abs(scoreA-scoreB)>=2)

if __name__ == "__main__":
    printInfo()
    probA, probB, n = getInputs()
    Time = time()
    winsA, winsB = simNGames(n, probA, probB)
    print("模擬用時: {:.1f}s".format(time()-Time))
    printResult(n, winsA, winsB)