4

正しいと思うコードを思いついたので、前の質問を編集しました。この背後にあるロジックは次のようになります: セットが終了しておらず、引き分けではない 10:10: プレーヤー A がサーブを開始し、ポイントを獲得するかどうかに関係なく 2 回サーブを行い、その後、プレーヤー B がサーブを受け取り、それを 2 回行います。サーバーが得点する各ポイントを変更する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

基本的に同じアイデアが 2 回繰り返される 2 つのブロックがあります。これは、関数を使用してコードを引き締めることができる兆候です。たとえばserve、確率probとプレーヤー (AまたはB) が与えられたときに、勝ったプレーヤーを返す関数を定義できます。

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

役立つかもしれない何かは構文です

var = 1 if var == 2 else 2

これにより、varが2の場合はvarが1になり、varが1の場合はvarが2になります。これは学校の問題のように感じるので、完全に答えを出したくありません:)

ヒント:あなたは自分の考えで正しい方向に進んでいます。

于 2013-02-08T13:38:26.313 に答える
0

ここにヒントがあります:

セットにラウンド番号があり、どのプレーヤーがサービスを開始したかがわかれば、誰がサービスを提供しているかを知るために必要なものがすべて揃っています。

次に、ループの最初または最後にある単純な if ステートメントで十分です。

これが複雑すぎる場合は、サーバーが毎ラウンド開始するゲームをシミュレートすることから始めてみてください。

于 2013-02-08T13:30:59.853 に答える