4

我编辑了我之前的问题,因为我想出了我认为正确的代码。这背后的逻辑应该是:当这盘比赛还没有结束,也不是平局时 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
4

4 回答 4

3

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

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

有两个块基本相同的想法重复了两次。这表明可以通过使用函数来收紧代码。例如,我们可以定义一个函数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))
于 2013-02-08T14:03:06.510 回答
0

这里有一个提示:

如果您有该组中的整数并且知道哪个球员开始发球,那么您就拥有知道谁在发球所需的一切。

那么在循环开始或结束时的简单 if 语句就足够了。

如果这太复杂,请尝试从模拟服务器开始每一轮的游戏开始。

于 2013-02-08T13:30:59.853 回答
0

可能有帮助的是语法

var = 1 if var == 2 else 2

如果 var 为 2,这将使 var 为 1,如果 var 为 1,则 var 为 2。我觉得这是一个学校问题,所以我不想完全放弃答案:)

提示:你的想法是正确的。

于 2013-02-08T13:38:26.313 回答
0

随机导入 *

P1=P2=0

while 1 :

  p1=p2=0

  while 2 :

    if random() < 0.5 : p1 +=1

    else              : p2 +=1


    if(p1 >=11 or p2 >=11) and abs(p1-p2) > 1: break

  P1 += p1 > p2; P2 += p2 > p1

  print "%2d : %2d (%d : %d)" % (p1, p2, P1, P2)

  if P1 == 4 or P2 == 4 : break

我希望这会有所帮助,它对我有用

于 2017-01-11T08:04:57.213 回答