2013-12-11 179 views
0

我想通过以下函数进行1000次交互,以确定您是否在此游戏中获胜或放弃了金钱。概率骰子Python中的两个骰子游戏

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

投掷收益率1.5硬币。

投掷收益率硬币。

投掷收益率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) 

我停止对函数结束编码,因为我认识到,必须对如何实现这一目标更优雅的解决方案。任何有趣的建议,我听说过的蒙特卡罗是什么?

+4

您当前的常规“重新卷”的骰子每个'if'声明。以'roll = random.randrange(1,7)+ random.rangerange(1,7)'开始,然后对其进行测试。您每次通过luckCalc重设金额,而不是跟踪外部总额。另外,11做什么? – jonrsharpe

+0

干得好,你敏锐的眼睛发现了一个逻辑漏洞。 - 我添加了11. – nottinhill

回答

2

每当您拨打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 

这里有10万发结果:

>>> 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} 
0

我注意到你的代码中有一些东西。首先,对于6-1的情况,你实际上并未从金额中减去0.5。其次,由于你没有在每个循环中传递最初的数量,所以你的总和增加了5到6.5,这使总数变得毫无意义。

一个更有效的总量将在量每次经过:

def luckCalc(amount): 

然后换你的循环:

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

Blender的答案,它刚刚发布,我在写这一点,是简化主要功能的好方法。

+0

总数通过外迭代得到正确计算。在luckCalc函数中,我添加了伪代码并将其注释掉。你的例子也会通过1000作为硬币的起始金额,这不符合我提供的规格。 – nottinhill

+0

猜猜我误解你的游戏。正如你写的那样,你每轮都会凭空加入5枚新硬币。我以为你只想从5个硬币开始,看看你在1000轮后会有多少钱。 – user3058428

0

我个人喜欢把我的结果表设置为一个数组(或字典,但这更适合我的目的,因为每个结果都是少量可能的整数之一),每个骰子的索引设置为由此产生的变化的价值。见下文。

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)) 
2

实际上,你可以滚(哈哈!)你正在做成一个单一的功能,一切:

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

我很喜欢你的答案,因为它的多功能性,在我的问题下你的快速评论是第一位的,但是Blender做了很好的解释。 – nottinhill