简体   繁体   English

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

[英]Convert one dice roll to two dice roll

I am a new learner with python and right now my code stimulates rolling one dice 1,000 times, however I just need some improvement to make it stimulate rolling two dice 1,000 times.我是 python 的新手,现在我的代码可以刺激掷一个骰子 1,000 次,但是我只需要一些改进就可以刺激掷两个骰子 1,000 次。

Here is what I have so far which is working perfectly just need some improvement:到目前为止,这是我所拥有的,它运行良好,只需要一些改进:

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

Any suggestions on how to get two dice rolling and get the similar output as what my code is doing right now which is this:关于如何滚动两个骰子并获得与我的代码现在正在做的类似的 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

In that case the outcome are numbers between 2 and 12 . 在这种情况下,结果是212之间的数字。 For simplicity it is better however to probably maintain the first index. 为了简单起见,最好保留第一个索引。

The test_data list thus needs to be increased to store 12 items, and as result we should call random.randint(1, 6) twice (not times two), and add these together: 因此,需要增加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)

It is also more elegant to write += 1 here, instead of = ... + 1 , since here we avoid writing test_data[result - 1] twice. 在这里写+= 1而不是= ... + 1也更优雅,因为在这里我们避免两次写test_data[result - 1] Furthermore in Python one typically enumerates over the collection directly, not over the indices. 此外,在Python中,通常直接枚举集合,而不是索引。 One can use enumerate(iterable, start_index) to generate an iterable of 2-tuples (i, n) with i the index, and x the element of the collection that is related to that index. 可以使用enumerate(iterable, start_index)生成一个2元组(i, n)的可迭代对象,其中i为索引, x为与该索引相关的集合元素。

This is a solution for two indistinguishable dice, meaning that throwing a 1 and a 3 is treated identical to a 3 and a 1. In this approach we use a dict instead of a list , because for two (or more!) indistinguishable dice the list would have "holes" (combinations like 3, 1 that can never occur because we treat them like 1, 3). 这是两个不可区分的骰子的解决方案,这意味着抛出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 is now both dice, sorted so that 3, 1 is treated as 1, 3, and converted from a list into a tuple (basically an immutable list) so we can use it as key for a dictionary ( counts ). dice现在既骰子,分类使得3,1被视为1,3,并从列表中转换成一个元组(基本上不可变列表),因此我们可以用它作为一个字典(标号counts )。 Then we just increase the count for that particular combination of dice. 然后,我们只增加特定骰子组合的数量。

Unlike the list, the dictionary is not sorted, but we do want a nice output sorted by what the dice showed, so we sort by the keys = dice: 与列表不同,字典不进行排序,但是我们确实希望按骰子显示的内容进行排序,因此我们按keys = dice进行排序:

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

This gives you: 这给您:

(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
...

You could use numpy , and this solution allows you to specify any number of dice: 您可以使用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])

Yields: 产量:

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

If you are allowed to use other python modules then random you can leverage collections.Counter to do your counting. 如果你被允许使用其他Python模块则random您可以利用collections.Counter做你的计数。 By switching from random.randint() to random.choices you can throw both dices at once: 通过从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}")

Output: 输出:

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: Doku:

  • collections.Counter collections.Counter
    • its a dictionary - you feed it an iterable and int counts how often each element of the iterable occurs: 它是一个字典-您向它提供可迭代的代码,并且int会计算可迭代的每个元素出现的频率:
        print(Counter( [1,2,2,3,3,3,4,4,4,4] ) )

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

If instead you wanted the single dice results, you can modify the code to not sum dices but instead deliver the tuples when generating the random numbers. 相反,如果您希望获得单个骰子结果,则可以修改代码以不对骰子求和,而是在生成随机数时传递元组。 I sorted them, so that (5,4,5) is the same throw as (4,5,5): 我对它们进行了排序,以便(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")

Output (shortened): 输出(缩短):

(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. Write a model class that represents a die (that is, a cube whose sides are numbered 1 to 6).写一个 model class 代表一个骰子(也就是一个边编号为 1 到 6 的立方体)。 The class will likely have just one method, throw(), and no attributes. class 可能只有一种方法 throw(),没有任何属性。 (Hint: use Math.random to write throw.) Then, write an output-view class that displays a die after it has been thrown. (提示:使用 Math.random 编写 throw。)然后,编写一个输出视图 class,在掷骰子后显示它。 Finally, write a controller that lets a user throw two dice repeatedly.最后,写一个 controller 让用户重复掷两个骰子。
  2. Use the class from the previous exercise to build a game called “draw the house.”使用上一个练习中的 class 构建一个名为“画房子”的游戏。 The objective is to throw a die repeatedly, and based on the outcome, draw parts of a house.目标是反复掷骰子,并根据结果绘制房屋的一部分。 A throw of 6 lets one draw the building, a square;一次掷 6 可以画出建筑物,一个正方形; a throw of 5 lets one draw the roof;投掷 5 可以画出屋顶; a throw of 4 lets one draw the door;一掷 4 让一个人拉门; and a throw of 3 lets one draw a window. (There are two windows.) The finished house looks something like this: /掷 3 可以画出 window。(有两个 windows。)完成的房子看起来像这样:/
    / \ / \

| | _ | _ | |x| |x| |x| |x|

Of course, the building must be drawn before the roof, and the roof must be drawn before the doors and windows. In addition to the class that represents the die, write a model class that represents the state of a partially built house.当然楼房一定要画在房顶之前,房顶一定要画在门和windows之前。除了代表骰子的class之外,还要写一个model class代表半建房子的state。 Then, write an output view that displays the house, and write a controller that enforces the rules of the game.然后,编写一个显示房子的 output 视图,并编写一个执行游戏规则的 controller。 8. Make a version of the game in the previous Project that lets two players compete at building their respective houses. 8. 制作之前项目中的游戏版本,让两名玩家竞争建造各自的房屋。

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

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