Python中的概率骰子游戏,有两个骰子



我想对下面的函数进行1000次迭代,看看你在这个游戏中是赢了还是亏了钱。

游戏的设计是这样的,你扔一对骰子,然后拿回钱或零钱。假设我们从5个硬币开始。

投掷12可获得1.5硬币。

投掷11可获得1硬币。

投掷10可获得0.5硬币。

投掷9,8或7不会产生任何结果。

投掷6,5,4,3,2或1将从您的硬币数量中扣除0.5硬币。

到目前为止,我的实现是这样的:

def luckCalc():
    amount = 5
    # if 12 then 1/36 chance
    if random.randrange(1,7) == 6 and random.randrange(1,7) == 6:
        amount = amount + 1.5
    # if 11 then 2/36 chance
    elif  (random.randrange(1,7) == 5 and random.randrange(1,7) == 6) or (random.randrange(1,7) == 6 and random.randrange(1,7) == 5):
        amount = amount + 1
   # if 10 then 3/36 chance
   elif (random.randrange(1,7) == 5 and random.randrange(1,7) == 5) or (random.randrange(1,7) == 4 and random.randrange(1,7) == 6) or (random.randrange(1,7) == 6 and random.randrange(1,7) == 4):
       amount = amount + 0.5
   # if 9,8,7
   # 4/36 + 5/36 + 6/36 chance
   # 1+6, 2+5, 3+4, 4+3, 5+2, 6+1 chance
   # 2+6, 3+5, 4+4, 5+3, 6+2 chance
   # 3+6, 4+5, 5+4, 6+3 chance
   # then no change in amount 
   # if 6,5,4,3,2,1
   # chances...
   # then amount -0.5
return amount 
# Iterate over the dice throwing simulator and calculate total
total = 0.0
for a in range(1000):
    total = total + luckCalc()
print (total)

我在函数的末尾停止了编码,因为我认识到必须有一个更优雅的解决方案来实现这一点。有什么有趣的建议吗,我一直听到的蒙特卡洛是什么?

每次调用random.randrange(1,7)时,都会生成一个新的随机数。既然你在测试一个"转弯",就滚两次:

def roll_die():
    return random.randrange(1, 7)
total = roll_die() + roll_die()

看看总和是否在一个范围内:

def play_turn():
    total = roll_die() + roll_die()
    if total == 12:
        return 1.5
    elif total == 11:
        return 1.0
    elif total == 10:
        return 0.5
    elif total <= 6:
        return -0.5
    else:  # total is 7, 8, or 9
        return 0

以下是100000发子弹的结果:

>>> from collections import Counter
>>> counts = Counter(play_turn() for i in xrange(100000))
>>> counts
    Counter({-0.5: 41823, 0: 41545, 0.5: 8361, 1.0: 5521, 1.5: 2750})
>>> probabilities = {score: count / 100000.0 for score, count in counts.items()}
>>> probabilities
    {-0.5: 0.41823, 0: 0.41545, 0.5: 0.08361, 1.0: 0.05521, 1.5: 0.0275}

您实际上可以将您正在做的一切滚动到一个函数中:

from random import randrange
def play_game(rolls=1000, amount=5, n=6):
    """Play game 'rolls' times, starting with 'amount' on 'n'-sided dice.""" 
    for i in range(rolls):
        roll = randrange(1, n+1) + randrange(1, n+1)
        if roll == 12:
            amount += 1.5
        elif roll == 11:
            amount += 1
        elif roll == 10:
            amount += 0.5
        elif roll < 7:
            amount -= 0.5
    return amount

我注意到您的代码中有一些内容。首先,对于6-1的情况,你实际上并没有从金额中减去0.5。第二,由于你没有传递每个循环的初始数量,你将在总数中添加5到6.5,这使得总数变得毫无意义。

一个更有效的总数是每次通过的金额:

def luckCalc( amount ):

然后为您的循环:

total = 5.0
for a in range(1000):
    total = luckCalc(total)

Blender的答案,就在我写这篇文章的时候发布的,是简化主函数的好方法。

我个人喜欢将我的结果表设置为数组(或字典,但这更适合我的目的,因为每个结果都是少数可能的整数之一),每个骰子滚动的索引都设置为结果更改的值。请参见下文。

import random
def luckCalc(coins=5):
  diceroll = random.randint(1,6)+random.randint(1,6) #roll them bones
  #here's that table I was talking about....
  results_table = ['index 0 is blank',"you can't roll a one on two dice",-.5,-.5,-.5,-.5,-.5,0,0,0,.5,1,1.5]
  coins += results_table[diceroll] #changes your coins value based on your roll (as an index of results_table)
  if results_table[diceroll] > 0: #change the string if your result was + or -
    result = "gained {}".format(results_table[diceroll])
  else:
    result = "lost {}".format(results_table[diceroll]*-1)
  print("You {} coins, putting you at {}".format(result,coins)) #report back to the user
  return coins #this is how you save your output

#CONSTANTS GO HERE -- YOU CAN CHANGE THESE TO CHANGE YOUR PROGRAM
STARTING_COINS = 5
HOW_MANY_ITERATIONS = 1000
#this way we don't modify a constant
coins = STARTING_COINS
#do it how many times?
for _ in range(HOW_MANY_ITERATIONS): #oh yeah that many times
  coins = luckCalc(coins) #runs the function and saves the result back to coins
#report to the user your final result.
print("After {} rolls, your final total is {}".format(HOW_MANY_ITERATIONS,coins))

最新更新