2013-02-08 127 views
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 
+0

我剛纔編輯的代碼和要求,任何人都可以跟着它嗎? – nutship 2013-02-09 10:31:23

回答

3

我會用字典來 「開關」 的玩家之間:

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)) 
+0

非常感謝。你的帖子可能會略微超過我的頭,因爲我還沒有涉及字典和關聯,但是沒關係,我可以回到你的帖子,當我追上一點。 – nutship 2013-02-08 14:23:10

0

這裏是一個暗示:

如果在設定的roundnumber,知道哪些球員開始放送,你有你需要知道誰是服務應有盡有。

然後,在循環的開始或結束處使用一個簡單的if語句就足夠了。

如果這太複雜了,試着從模擬一個服務器每輪啓動的遊戲開始。

0

的東西,可能會幫助是語法

var = 1 if var == 2 else 2 

這將使VAR爲1,如果var爲2,和VAR是2,如果var爲1。我覺得好像這是一所學校的問題,所以我不想完全放棄答案:)

提示:您的思維正處於正確的軌道上。

+0

謝謝,它不是一塊作業。我正在學習Zelle的Python編程,這就是爲什麼:) – nutship 2013-02-08 13:46:29

+0

我很高興聽到您正在學習python!如果您需要更多幫助,請發表評論,我可以更新我的答案以獲得更多解釋。 – William 2013-02-08 13:51:11

+0

嗨,威廉,起初我沒有得到你的提示代碼,但它現在只是在我身上恍然大悟,然後用它來改變一組服務完成後的下一個功能。謝謝先生:) – nutship 2013-02-09 11:29:28

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 

我希望這可以幫助,它爲我工作