【问题标题】:Count throws for sixes in rolling dice python在掷骰子蟒蛇中数掷六次
【发布时间】:2015-12-09 15:06:30
【问题描述】:

在 Python 入门课程中,我得到了一个模拟掷骰子的任务

你希望你所有的骰子(总共 5 个)都得到 6,并计算一个人总共掷了多少次才能得到所有的 6。我需要一个循环来模拟这个问题 100.000 次,然后需要将总计数除以 100.000 以获得结果。我知道最终结果应该是 13 左右,但我没有得到,我不知道为什么。

我知道我解决这个问题的方法有问题,但是怎么办?

import random

count1=0
count2=0
count3=0
count4=0
count5=0
loopcounter = 0

for loopcouter in range (1,100000):
    dice1=int( random.random()*6)+1
    if dice1 != 6:
        #reroll
        while dice1 != 6:
            dice1=int( random.random()*6)+1
            #set counter1
            count1 = count1+1
        else:
            count1 = 1

        dice2=int( random.random()*6)+1
        if dice2 != 6:
            #reroll while not six
            while dice2 != 6:
                dice2=int( random.random()*6)+1
                #set counter2
                count2 = count2+1
        else:
            count2 = 1

        dice3=int( random.random()*6)+1
        if dice3 != 6:
            #reroll while not six
            while dice3 != 6:
                dice3=int( random.random()*6)+1
                #set counter3
                count3 = count3+1
        else:
            count3 = 1
        dice4=int( random.random()*6)+1
        if dice4 != 6:
            #reroll while not six
            while dice4 != 6:
                dice4=int( random.random()*6)+1
                #set counter4
                count4 = count4+1
        else:
            count4 = 1

        dice5=int( random.random()*6)+1
        if dice5 != 6:
            #reroll while not six
            while dice5 != 6:
                dice5=int( random.random()*6)+1
                #set counter5
                count5 = count5+1
        else:
            count5 = 1


    #print (dice1)
    print (count1)

#print (dice2)
print (count2)
#print (dice3)
print (count3)
#print (dice4)
print (count4)
#print (dice5)
print (count5)

allcount = count1+count2+count3+count4+count5
averagecount = int(allcount / 100000)

print ("the total number of throws is",allcount)
print ("the average number of throws is",averagecount)

所以,如果有人能告诉我我做错了什么,那就完美了!

【问题讨论】:

  • 您能否澄清一下,您是要始终一次掷 5 个骰子,还是每次都重新掷骰子,直到掷出 6 个骰子?
  • 在经典的 yahtzee 游戏中,您只需掷 3 次即可获得 6,但您给了他们无限次滚动,如果您没有获得 5 次 6,那将是失败的。特定 yahtzee 的几率为 1.33%,因此,除以 100000 时,您会期望得到 0.013 的结果。
  • 您初始的 if 条件意味着如果您掷出 6 没有其他骰子,实际上没有必要的 if 条件。
  • 请不要破坏您的问题;您不能使其他人为回答您所做的工作无效。

标签: python loops simulation dice


【解决方案1】:

这是一种非常不同的方法。

让我们做一个物体,死了,它会滚动直到它击中目标:

import random

class die(object):
    def __init__(self, sides=6):
        self.sides=sides
        self.count=0

    def roll(self):
        self.count+=1
        return random.randint(1,self.sides)    

    def roll_until(self, tgt, giveup=100000):
        result=0
        self.tgt=tgt
        while result!=tgt and self.count<giveup:
            result=self.roll()
        if self.count<giveup:
            return self.count

然后你可以创建一个实例(单个骰子)并告诉它自己滚动直到命中目标:

>>> d=die()
>>> d.roll_until(6)
2
>>> d.tgt
6
>>> d.count
2

2 是 d 需要滚动的次数,直到 6 是 6 面骰子的结果。

为什么要这样?现在您可以轻松创建模具列表:

>>> dice=[die().roll_until(6) for i in range(6)]
>>> dice
[15, 3, 3, 4, 5, 2]

轻松回答您的问题。

取这个列表的最大值:

>>> max(die().roll_until(6) for i in range(6))
9

n 乘以 float(n) 得到结果:

>>> n=100000
>>> sum(max(die().roll_until(6) for i in range(6)) for i in range(n))/float(n)
13.95879

哎呀!在 Yatzee 游戏中只有五个骰子。轻松更改:

>>> sum(max(die().roll_until(6) for i in range(5)) for i in range(n))/float(n)
13.0032

【讨论】:

  • 仅供参考:yahtzee 游戏中只有 5 个骰子。
  • 轻松更改! &gt;&gt;&gt; sum(max(die().roll_until() for i in range(5)) for i in range(n))/float(n) 13.0032
【解决方案2】:

根据说明,您需要每轮的最大计数,因为这将告诉您需要多少次滚动才能获得所有 6。 这是对每个骰子使用循环的代码重写:

import random

allcount = 0
for loopcouter in range(100000):   # 1,100000 would only loop 99999 times
    count = [0]*5
    for i in range(5):             # 5 dice
        while True:
            dice = random.randint(1,6)  # Use randint
            count[i] += 1
            if dice == 6:
                break
    allcount += max(count)         # The number of rolls needed to get all 6s

averagecount = allcount // 100000

print("the total number of throws is", allcount)
print("the average number of throws is", averagecount)

这似乎是 12/13 范围内的平均值。

有很多方法可以解决这个问题,例如您可以使用iter 和匿名函数lambda 来替换内部while 循环。这些开始使用 python 的更高级功能(迭代器和生成器):

from random import randint

allcount = 0
for _ in range(100000):
    counts = [1]*5
    for i in range(5):
        dice = list(iter(lambda: randint(1,6), 6))
        counts[i] += len(dice)
    allcount += max(counts)
averagecount = allcount // 100000

事实上,你可以将它完全折叠成一行代码,但它变得越来越难以阅读并打破了各种风格:

allcount = sum(max((1 + sum(1 for _ in iter(lambda: randint(1, 6), 6)))
                   for _ in range(5)) for _ in range(100000))
averagecount = allcount // 100000

【讨论】:

  • 你总结了所有骰子的所有掷骰数。对于每一轮,您只需要所有骰子的最差数量(最大值)。如果您碰巧在第一轮中掷出 6,则 if 条件将计数器任意重置为 1 - 这应该是 += 1,因为它是一个正在运行的计数器。删除 if 条件实际上改进了代码,但你计算的太多了。
【解决方案3】:

对于您的新编辑,计数仍应以 0 开头,但您还应该在进入 while 循环之前增加一次计数器,因为这已经标记了一个滚动。

此外,您应该使用不同的函数来确定您的随机整数。而不是使用

(random.random() * 6) + 1

使用:

random.randint(1,6)

【讨论】:

    猜你喜欢
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 2018-12-17
    • 2015-06-26
    • 1970-01-01
    相关资源
    最近更新 更多