簡體   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