繁体   English   中英

将一个骰子转换为两个骰子

[英]Convert one dice roll to two dice roll

我是 python 的新手,现在我的代码可以刺激掷一个骰子 1,000 次,但是我只需要一些改进就可以刺激掷两个骰子 1,000 次。

到目前为止,这是我所拥有的,它运行良好,只需要一些改进:

import random
test_data = [0, 0, 0, 0, 0, 0]
n = 1000
for i in range(n):
  result = random.randint(1, 6)
  test_data[result - 1] = test_data[result - 1] + 1

for i in range(0, 6):
  print ("Number of ", i+1, "'s: ", test_data[i])

关于如何滚动两个骰子并获得与我的代码现在正在做的类似的 output 的任何建议,这是:

Number of  1 's:  180

Number of  2 's:  161

Number of  3 's:  179

Number of  4 's:  159

Number of  5 's:  146

Number of  6 's:  175

在这种情况下,结果是212之间的数字。 为了简单起见,最好保留第一个索引。

因此,需要增加test_data列表以存储12项目, result我们应该两次调用random.randint(1, 6) (而不是两次),并将它们加在一起:

import random

test_data = [0] * 12
n = 1000
for i in range(n):
  # adding up two dices
  result = random.randint(1, 6) + random.randint(1, 6)
  test_data[result - 1] += 1

for i, x in enumerate(test_data, 1):
  print ("Number of ", i, "'s: ", x)

在这里写+= 1而不是= ... + 1也更优雅,因为在这里我们避免两次写test_data[result - 1] 此外,在Python中,通常直接枚举集合,而不是索引。 可以使用enumerate(iterable, start_index)生成一个2元组(i, n)的可迭代对象,其中i为索引, x为与该索引相关的集合元素。

这是两个不可区分的骰子的解决方案,这意味着抛出1和3与3和1相同。在这种方法中,我们使用dict而不是list ,因为对于两个(或更多!)不可区分的骰子, list会出现“漏洞”(3、1之类的组合永远不会发生,因为我们将它们视为1、3)。

import random

counts = {}
for _ in range(1000):
    dice = tuple(sorted([random.randint(1, 6), random.randint(1, 6)]))
    counts[dice] = counts.get(dice, 0) + 1

dice现在既骰子,分类使得3,1被视为1,3,并从列表中转换成一个元组(基本上不可变列表),因此我们可以用它作为一个字典(标号counts )。 然后,我们只增加特定骰子组合的数量。

与列表不同,字典不进行排序,但是我们确实希望按骰子显示的内容进行排序,因此我们按keys = dice进行排序:

for dice in sorted(counts.keys()):
    print("{} occurred {} times".format(dice, counts[dice]))

这给您:

(1, 1) occurred 22 times
(1, 2) occurred 53 times
(1, 3) occurred 47 times
(1, 4) occurred 55 times
(1, 5) occurred 55 times
(1, 6) occurred 50 times
(2, 2) occurred 27 times
(2, 3) occurred 64 times
(2, 4) occurred 58 times
...

您可以使用numpy ,并且此解决方案允许您指定任意数量的骰子:

import numpy as np

no_of_dice = 2
sides_on_die = 6
rolls = 1000
dice = np.array([0]*rolls)

for i in range(no_of_dice):
    dice += np.random.randint(1,sides_on_die+1,rolls)
data = np.bincount(dice)

for i in range(no_of_dice,no_of_dice*sides_on_die+1):
    print ("Number of ", i, "'s: ", data[i])

产量:

Number of  2 's:  26
Number of  3 's:  55
Number of  4 's:  100
Number of  5 's:  106
Number of  6 's:  139
Number of  7 's:  152
Number of  8 's:  135
Number of  9 's:  104
Number of  10 's:  87
Number of  11 's:  64
Number of  12 's:  32

如果你被允许使用其他Python模块则random您可以利用collections.Counter做你的计数。 通过从random.randint()切换到random.choices,您可以一次抛出两个骰子:

import random
from collections import Counter


def roll_n_dice_of_sides_x_times(n,x,sides=6):
    """Rolls 'n' dices with 'sides' sides 'x' times. Yields 'x' values that 
    hold the sum of the 'x' dice rolls.""" 
    r = range(1,sides+1)
    yield from (sum(random.choices(r,k=n)) for _ in range(x))

# this does allthe counting and dice throwingof 1000 2-6sided-dice-sums
c = Counter(roll_n_dice_of_sides_x_times(2,1000))

# print the sorten (key,value) tuples of the Counter-dictionary. Sort by 
# how much eyes thrown, then amount of occurences
for eyes,count in sorted(c.items()):
    print(f"Number of {eyes:>3}'s : {count}")

输出:

Number of   2's : 24
Number of   3's : 51
Number of   4's : 66
Number of   5's : 115
Number of   6's : 149
Number of   7's : 182
Number of   8's : 153
Number of   9's : 116
Number of  10's : 68
Number of  11's : 58
Number of  12's : 18

Doku:

  • collections.Counter
    • 它是一个字典-您向它提供可迭代的代码,并且int会计算可迭代的每个元素出现的频率:
        print(Counter( [1,2,2,3,3,3,4,4,4,4] ) )

        # Counter({4: 4, 3: 3, 2: 2, 1: 1})

相反,如果您希望获得单个骰子结果,则可以修改代码以不对骰子求和,而是在生成随机数时传递元组。 我对它们进行了排序,以便(5,4,5)与(4,5,5)相同:

import random
from collections import Counter

def roll_n_dice_of_sides_x_times_no_sum(n,x,sides=6):
    """Rolls 'n' dices with 'sides' sides 'x' times. Yields a sorted tuple 
    of the dice throwsof all  'x' dice rolls.""" 
    r = range(1,sides+1)

    # instead of summing, create a tuple (hashable, important for Counter)
    # and return that sorted, so that 4,4,5 == 5,4,4 == 4,5,4 throw:
    yield from ( tuple(sorted(random.choices(r,k=n))) for _ in range(x))

# throw 3 6-sided dice 1000 times and count:
c = Counter(roll_n_dice_of_sides_x_times_no_sum(3,1000))

# print the sorten (key,value) tuples of the Counter-dictionary. Sort by 
# how much eyes thrown, then amount of occurences
for dice,count in sorted(c.items()):
    print(f"{dice} occured {count} times")

输出(缩短):

(1, 1, 1) occured 3 times
(1, 1, 2) occured 14 times
[...] 
(2, 3, 5) occured 32 times
(2, 3, 4) occured 21 times
[...]
(4, 6, 6) occured 10 times
(5, 5, 5) occured 3 times
(5, 5, 6) occured 20 times
(5, 6, 6) occured 9 times
(6, 6, 6) occured 4 times
  1. 写一个 model class 代表一个骰子(也就是一个边编号为 1 到 6 的立方体)。 class 可能只有一种方法 throw(),没有任何属性。 (提示:使用 Math.random 编写 throw。)然后,编写一个输出视图 class,在掷骰子后显示它。 最后,写一个 controller 让用户重复掷两个骰子。
  2. 使用上一个练习中的 class 构建一个名为“画房子”的游戏。 目标是反复掷骰子,并根据结果绘制房屋的一部分。 一次掷 6 可以画出建筑物,一个正方形; 投掷 5 可以画出屋顶; 一掷 4 让一个人拉门; 掷 3 可以画出 window。(有两个 windows。)完成的房子看起来像这样:/
    / \

| _ | |x| |x|

当然楼房一定要画在房顶之前,房顶一定要画在门和windows之前。除了代表骰子的class之外,还要写一个model class代表半建房子的state。 然后,编写一个显示房子的 output 视图,并编写一个执行游戏规则的 controller。 8. 制作之前项目中的游戏版本,让两名玩家竞争建造各自的房屋。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM