python - 乒乓球模拟器

标签 python python-2.7 nested-loops

我编辑了我之前的问题,因为我想出了我认为正确的代码。 这背后的逻辑应该是: 10:10:A开始发球,无论得分与否,发球两次,然后B发球,也发球两次。它一直持续到比赛结束,除了当服务器改变每个得分时出现平局 10:10。

任何人都可以检查代码是否完美无缺?谢谢。

def simOneSet(probA, probB):
    serving = "A"
    scoreA = scoreB = 0
    while not setOver(scoreA, scoreB):
        if scoreA != 10 and scoreB != 10:
            if serving == "A":
                for i in range(2):
                    if random() < probA:
                        scoreA += 1
                    else:
                        scoreB += 1
                serving = "B"
            else:
                for i in range(2):
                    if random() < probB:
                        scoreB +=1
                    else:
                        scoreA += 1
                serving = "A"    
        # when there is a tie 10:10
        else:
            if serving == "A":
                if random() < probA:
                    scoreA += 1
                    serving = "B"
                else:
                    scoreB += 1
                    serving = "B"
            else:
                if random() < probB:
                    scoreB += 1
                    serving = "B"
                else:
                    scoreA += 1
                    serving = "A"
    return scoreA, scoreB

最佳答案

我会使用字典在玩家之间“切换”:

other = {'A':'B', 'B':'A'}

然后,如果serving等于 'A' , 然后 other[serving]等于 'B' , 如果 serving等于 'B' , 然后 other[serving]等于 'A' .


你也可以使用 collections.Counter跟踪分数:

In [1]: import collections

In [2]: score = collections.Counter()

In [3]: score['A'] += 1

In [4]: score['A'] += 1

In [5]: score['B'] += 1

In [6]: score
Out[6]: Counter({'A': 2, 'B': 1})

另请注意这段代码中的方式

    if serving == "A":
        for i in range(2):
            if random() < probA:
                scoreA += 1
            else:
                scoreB += 1
    else:
        for i in range(2):
            if random() < probB:
                scoreB +=1
            else:
                scoreA += 1

有两个 block 基本上是相同的想法重复了两次。这表明可以通过使用函数来加强代码。例如,我们可以定义一个函数 serve当给定概率时 prob玩家(AB)返回获胜的玩家:

def serve(prob, player):
    if random.random() < prob:
        return player
    else:
        return other[player]

那么上面的代码就变成了

    for i in range(2):
        winner = serve(prob[serving], serving)
        score[winner] += 1

因此,您可以通过这种方式大大压缩您的代码:

import random
import collections
other = {'A':'B', 'B':'A'}

def serve(prob, player):
    if random.random() < prob:
        return player
    else:
        return other[player]

def simOneSet(probA, probB):
    prob = {'A':probA, 'B':probB}
    score = collections.Counter()

    serving = "A"
    while not setOver(score['A'], score['B']):
        for i in range(2):
            winner = serve(prob[serving], serving)
            score[winner] += 1
        if score['A'] == 10 and score['B'] == 10:
            winner = serve(prob[serving], serving)
            score[winner] += 1
            serving = winner

    return score['A'], score['B']  

def setOver(scoreA, scoreB):
    return max(scoreA, scoreB) >= 21

print(simOneSet(0.5,0.5))

关于python - 乒乓球模拟器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14773594/

相关文章:

python - Memcached 不尊重元组的顺序

python - RSA实现解密/加密

python - 开始于 python 中的列表?

python - 如何使用 find_packages() 打包子目录中的所有文件

matlab - 在 Matlab 中向量化 4 个嵌套 for 循环

android - 如何防止我的程序排队按钮按下

Python 未写入 MySQL(类型错误 : format requires a mapping)

python - 如何在 Python 中解析 Linux 终端错误消息?

python - 如何从外部版本中删除代码

java - 将局部变量中的动态 int 值存储到静态?