乒乓竞技模拟比赛的规则为:
一局比赛:
在一局比赛中,先得11分的一方为胜方;10平后,先多得2分的一方为胜方。
一场比赛:
单打的淘汰赛采用七局四胜制,双打淘汰赛和团体赛采用五局三胜制。
该问题的IPO描述如下:
输入:两个球员:A和B的得分的概率,比赛的次数
处理:模拟比赛过程
输出:A和B分别赢的概率
自顶向下的设计如下:
def main(): printIntro() probA,probB,n=getInputs() winsA,winsB=simNGames(n,probA,probB) printSummary(winsA,winsB,n)
其中 printIntro()为程序的介绍性信息,getInputs()为程序运行需要的参数,simNGames(n,probA,probB)依据proA,proB进行n次比赛,printSummary(winsA,winsB,n)输出A和B的赢的概率。
它们分别为:
def printIntro(): print("这个程序模拟两个选手A和B的乒乓比赛") print("这个程序需要A和B的能力值(0-1)") print("分析员:01")
def getInputs(): a=eval(input('A的能力值为:')) b=eval(input("B的能力值为:")) n=eval(input("比赛的场次为:")) return a,b,n
def simNGames(n,probA,probB): a,b=0,0 for i in range(n): x,y=ones(probA,probB) if x>y: a+=1 else: b+=1 return a,b
def printSummary(a,b,n): print("A赢{} B赢{} 共{}".format(a,b,n)) print("A赢的概率为{:0.1%} B赢的概率为{:0.1%}".format(a/n,b/n))
想要算出n场的A和B赢的次数,需要求出一场比赛A和B分别赢了几局,由ones(probA,probB)求得
def ones(probA,probB): wa,wb=0,0 for j in range(7): xa,xb=one(probA,probB) if xa>xb: wa+=1 else: wb+=1 return wa,wb
求A和B在一场比赛中的赢的局数,需要求出一局中A和B的得分,由one(probA,probB)求得
def one(a,b): scorea,scoreb=0,0 x='A' while not gameover(scorea,scoreb): if x=='A': if random()<a: scorea+=1 else: x='B' else: if random()<b: scoreb+=1 else: x='A' return scorea,scoreb
在其中需要有结束的条件gameover(scorea,scoreb)
def gameover(a,b): if a>=10 and b>=10 and abs(a-b)==2: return True if (a>=11 and b<11) or (a<11 and b>=11): return True return False
完整的代码如下:
from random import random def printIntro(): print("这个程序模拟两个选手A和B的乒乓比赛") print("这个程序需要A和B的能力值(0-1)") print("分析员:01") def getInputs(): a=eval(input('A的能力值为:')) b=eval(input("B的能力值为:")) n=eval(input("比赛的场次为:")) return a,b,n def gameover(a,b): if a>=10 and b>=10 and abs(a-b)==2: return True if (a>=11 and b<11) or (a<11 and b>=11): return True return False def one(a,b): scorea,scoreb=0,0 x='A' while not gameover(scorea,scoreb): if x=='A': if random()<a: scorea+=1 else: x='B' else: if random()<b: scoreb+=1 else: x='A' return scorea,scoreb def ones(probA,probB): wa,wb=0,0 for j in range(7): xa,xb=one(probA,probB) if xa>xb: wa+=1 else: wb+=1 return wa,wb def simNGames(n,probA,probB): a,b=0,0 for i in range(n): x,y=ones(probA,probB) if x>y: a+=1 else: b+=1 return a,b def printSummary(a,b,n): print("A赢{} B赢{} 共{}".format(a,b,n)) print("A赢的概率为{:0.1%} B赢的概率为{:0.1%}".format(a/n,b/n)) def main(): printIntro() probA,probB,n=getInputs() winsA,winsB=simNGames(n,probA,probB) printSummary(winsA,winsB,n) main()
输入0.55 0.54 500的结果为
这个程序模拟两个选手A和B的乒乓比赛
这个程序需要A和B的能力值(0-1)
分析员:01
A的能力值为:0.55
B的能力值为:0.54
比赛的场次为:500
A赢347 B赢153 共500
A赢的概率为69.4% B赢的概率为30.6%
运用pyinstaller打包可以执行的程序,并用cmd执行
将上面乒乓的模拟比赛进行修改,套用篮球比赛规则,其中时间不好表达,用random.randint(a,b)生成一局比赛中投篮的总次数,且只算概率较大的2分。
代码为:
from random import *
def printIntro():
print("这个程序模拟两个队伍A和B的篮球比赛")
print("这个程序需要A和B的能力值(0-1)")
print("分析员:01")
def getInputs():
a=eval(input('A的能力值为:'))
b=eval(input("B的能力值为:"))
n=eval(input("比赛的场次为:"))
return a,b,n
def gameover(i,k):
if i>k:
return True
return False
def one(a,b):
scorea,scoreb=0,0
x='A'
i=1
k=randint(10,40)
while not gameover(i,k):
if x=='A':
if random()<a:
scorea+=2
else:
x='B'
else:
if random()<b:
scoreb+=2
else:
x='A'
i+=1
return scorea,scoreb
def jiashi(a,b):
scorea,scoreb=0,0
i=1
x='A'
while not gameover(i,randint(1,5)):
if x=='A':
if random()<a:
scorea+=2
else:
x='B'
else:
if random()<b:
scoreb+=2
else:
x='A'
i+=1
return scorea,scoreb
def ones(probA,probB):
wa,wb=0,0
for j in range(4):
xa,xb=one(probA,probB)
wa+=xa
wb+=xb
while wa==wb:
xa,xb=jiashi(probA,probB)
wa+=xa
wb+=xb
return wa,wb
def simNGames(n,probA,probB):
a,b=0,0
for i in range(n):
x,y=ones(probA,probB)
if x>y:
a+=1
else:
b+=1
return a,b
def printSummary(a,b,n):
print("A赢{} B赢{} 共{}".format(a,b,n))
print("A赢的概率为{:0.1%} B赢的概率为{:0.1%}".format(a/n,b/n))
def main():
printIntro()
probA,probB,n=getInputs()
winsA,winsB=simNGames(n,probA,probB)
printSummary(winsA,winsB,n)
main()
篮球一般一场比赛为四局,有A队和B队同分的可能,有加时赛,所以jiashi(a,b)为加时赛的情况,加时赛一般时间较短,所以一场可能进的球数量比较少,randint()的范围就比较小。
输入为:队伍A和B的进球概率,比赛的次数
过程为:模拟n场比赛
输出为:A和B分别的赢的次数和概率
其中一个结果为:
这个程序模拟两个队伍A和B的篮球比赛
这个程序需要A和B的能力值(0-1)
分析员:01
A的能力值为:0.667
B的能力值为:0.668
比赛的场次为:800
A赢491 B赢309 共800
A赢的概率为61.4% B赢的概率为38.6%
运用pyinstaller打包可以执行的程序,并用cmd执行: