如何获得掷骰子的概率总和,其中一个是公平的,另一个是不公平的?
How to get sum of probabilities of rolling w dice where one is fair and the other one is unfair?
我正在写一个小程序,想问一下如何在游戏中添加不公平骰子的逻辑?现在,我的代码生成了掷 2 个 6 面骰子 i 次的概率总和。但是,它以 1/6 的概率掷出给定数字来处理骰子。我该如何调整它,使不公平的骰子只出现在 2-5 的范围内,而不会出现在 1 或 6 的范围内?在给定公平和不公平骰子的情况下,输出应该是 2-12 范围内所有数字的概率总和。
import random
from collections import defaultdict
def main():
dice = 2
sides = 6
rolls = int(input("Enter the number of rolls to simulate: "))
result = roll(dice, sides, rolls)
maxH = 0
for i in range(dice, dice * sides + 1):
if result[i] / rolls > maxH: maxH = result[i] / rolls
for i in range(dice, dice * sides + 1):
print('{:2d}{:10d}{:8.2%} {}'.format(i, result[i], result[i] / rolls, '#' * int(result[i] / rolls / maxH * 40)))
def roll(dice, sides, rolls):
d = defaultdict(int)
for _ in range(rolls):
d[sum(random.randint(1, sides) for _ in range(dice))] += 1
return d
main()
输出
Enter the number of rolls to simulate: 10000
2 265 2.65% ######
3 567 5.67% #############
4 846 8.46% ####################
5 1166 11.66% ############################
6 1346 13.46% ################################
7 1635 16.35% ########################################
8 1397 13.97% ##################################
9 1130 11.30% ###########################
10 849 8.49% ####################
11 520 5.20% ############
12 279 2.79% ######
鉴于目前哪些结果可能的逻辑被线路控制
random.randint(1, sides)
如果你想以不同的界限滚动,那是要改变的线。例如,要获得 2-5
,您可以概括函数:
def main():
dice = 2
sides = 6
unfair_min = 2
unfair_max = 5
rolls = int(input("Enter the number of rolls to simulate: "))
result_unfair = roll_biased(dice, sides, rolls, min_roll=unfair_min, max_roll=unfair_max)
maxH = max(result_unfair.values()) / rolls
for i in range(dice, dice * sides + 1):
print('{:2d}{:10d}{:8.2%} {}'.format(i, result_unfair[i], result_unfair[i] / rolls,
'#' * int(result_unfair[i] / rolls / maxH * 40)))
def roll_biased(dice, sides, rolls, min_roll=1, max_roll=None):
if max_roll is None:
max_roll = sides
d = defaultdict(int)
for _ in range(rolls):
d[sum(random.randint(min_roll, max_roll) for _ in range(dice))] += 1
return d
可以打印:
Enter the number of rolls to simulate: 10000
2 0 0.00%
3 0 0.00%
4 632 6.32% ##########
5 1231 12.31% ###################
6 1851 18.51% #############################
7 2480 24.80% ########################################
8 1873 18.73% ##############################
9 1296 12.96% ####################
10 637 6.37% ##########
11 0 0.00%
12 0 0.00%
您也可以使用 random.choices()
将其概括为任意选择(或任意权重):
def roll_from_choices(dice, sides, rolls, allowed_rolls=None):
if allowed_rolls is None:
allowed_rolls = list(range(1, sides+1))
d = defaultdict(int)
for _ in range(rolls):
d[sum(random.choices(allowed_rolls, k=dice))] += 1
return d
您可以称其为:
result_unfair = roll_from_choices(dice, sides, rolls, allowed_rolls=[2, 3, 4, 5])
我会开始一个函数,returns掷骰子(a)的结果,其中可以定制可用选项以排除不可能的选项,例如:
import random
def throw_die(options):
return random.choice(options)
然后我会为一般情况编写代码,您可以拥有 any 个骰子,每个 个不同的能力(待通过作为掷骰子时的选项)。在您的特定情况下,这将是两个骰子,第二个骰子不包括 1
和 6
(b):
dice = [
[1, 2, 3, 4, 5, 6],
[ 2, 3, 4, 5 ]
]
然后为结果分配足够的存储空间(我在这里浪费了少量 space 以确保收集数据的代码更简单):
min_res = sum([min(die) for die in dice]) # Smallest possible result,
max_res = sum([max(die) for die in dice]) # and largest.
count = [0] * (max_res + 1) # Allocate space + extra.
你的数据收集相对简单(我在这里硬编码了滚动计数而不是使用输入,但你可以把它放回去):
rolls = 10000 # rolls = int(input("How many rolls? "))
for _ in range(rolls):
# Throw each die, sum the results, then increment correct count.
result = sum([throw_die(die) for die in dice])
count[result] += 1
并且数据输出可以这样完成(四舍五入而不是截断,以便最高计数有 40 个哈希值——这只是我的 CDO(c) 性质):
hash_mult = 40 / max(count)
for i in range(min_res, max_res + 1):
per_unit = count[i] / rolls
hashes = "#" * int(count[i] * hash_mult + 0.5)
print(f"{i:2d}{count[i]:10d}{per_unit:8.2%} {hashes}")
完整的程序变成:
import random
# Throw a single die.
def throw_die(options):
return random.choice(options)
# Define all dice here as list of lists.
# No zero/negative number allowed, will
# probably break code :-)
dice = [
[1, 2, 3, 4, 5, 6],
[ 2, 3, 4, 5 ]
]
# Get smallest/largest possible result.
min_res = sum([min(die) for die in dice])
max_res = sum([max(die) for die in dice])
# Some elements wasted (always zero) to simplify later code.
# Example: throwing three normal dice cannot give 0, 1, or 2.
count = [0] * (max_res + 1)
# Do the rolls and collect results.
rolls = 10000
for _ in range(rolls):
result = sum([throw_die(die) for die in dice])
count[result] += 1
# Output all possible results.
hash_mult = 40 / max(count)
for i in range(min_res, max_res + 1):
per_unit = count[i] / rolls
hashes = "#" * int(count[i] * hash_mult + 0.5)
print(f"{i:2d}{count[i]:10d}{per_unit:8.2%} {hashes}")
和一些示例运行以查看它的实际效果:
pax:/mnt/c/Users/Pax/Documents/wsl> python prog.py
3 418 4.18% #########
4 851 8.51% ####################
5 1266 12.66% ##############################
6 1681 16.81% ########################################
7 1606 16.06% ######################################
8 1669 16.69% #######################################
9 1228 12.28% #############################
10 867 8.67% ####################
11 414 4.14% #########
pax:/mnt/c/Users/Pax/Documents/wsl> python prog.py
3 450 4.50% ##########
4 825 8.25% ###################
5 1206 12.06% ############################
6 1655 16.55% #######################################
7 1679 16.79% ########################################
8 1657 16.57% #######################################
9 1304 13.04% ###############################
10 826 8.26% ###################
11 398 3.98% #########
pax:/mnt/c/Users/Pax/Documents/wsl> python prog.py
3 394 3.94% #########
4 838 8.38% ####################
5 1271 12.71% ##############################
6 1617 16.17% ######################################
7 1656 16.56% #######################################
8 1669 16.69% ########################################
9 1255 12.55% ##############################
10 835 8.35% ####################
11 465 4.65% ###########
脚注:
(a) 对单骰子和多骰子使用正确的命名法,以防任何非英语使用者感到困惑。
(b) 你也可以处理像 [1, 2, 3, 4, 4, 5, 6]
这样的情况,你得到 4
的可能性是任何其他号码。任何比这更复杂的事情最好用一个元组来处理,该元组代表每个可能的结果及其相对可能性。可能有点太复杂了,无法放入脚注(考虑到这不是问题的要求),但如果您有兴趣,可以随时在 separate 问题中询问这个问题。
(c) 就像强迫症一样,但顺序正确:-)
我正在写一个小程序,想问一下如何在游戏中添加不公平骰子的逻辑?现在,我的代码生成了掷 2 个 6 面骰子 i 次的概率总和。但是,它以 1/6 的概率掷出给定数字来处理骰子。我该如何调整它,使不公平的骰子只出现在 2-5 的范围内,而不会出现在 1 或 6 的范围内?在给定公平和不公平骰子的情况下,输出应该是 2-12 范围内所有数字的概率总和。
import random
from collections import defaultdict
def main():
dice = 2
sides = 6
rolls = int(input("Enter the number of rolls to simulate: "))
result = roll(dice, sides, rolls)
maxH = 0
for i in range(dice, dice * sides + 1):
if result[i] / rolls > maxH: maxH = result[i] / rolls
for i in range(dice, dice * sides + 1):
print('{:2d}{:10d}{:8.2%} {}'.format(i, result[i], result[i] / rolls, '#' * int(result[i] / rolls / maxH * 40)))
def roll(dice, sides, rolls):
d = defaultdict(int)
for _ in range(rolls):
d[sum(random.randint(1, sides) for _ in range(dice))] += 1
return d
main()
输出
Enter the number of rolls to simulate: 10000
2 265 2.65% ######
3 567 5.67% #############
4 846 8.46% ####################
5 1166 11.66% ############################
6 1346 13.46% ################################
7 1635 16.35% ########################################
8 1397 13.97% ##################################
9 1130 11.30% ###########################
10 849 8.49% ####################
11 520 5.20% ############
12 279 2.79% ######
鉴于目前哪些结果可能的逻辑被线路控制
random.randint(1, sides)
如果你想以不同的界限滚动,那是要改变的线。例如,要获得 2-5
,您可以概括函数:
def main():
dice = 2
sides = 6
unfair_min = 2
unfair_max = 5
rolls = int(input("Enter the number of rolls to simulate: "))
result_unfair = roll_biased(dice, sides, rolls, min_roll=unfair_min, max_roll=unfair_max)
maxH = max(result_unfair.values()) / rolls
for i in range(dice, dice * sides + 1):
print('{:2d}{:10d}{:8.2%} {}'.format(i, result_unfair[i], result_unfair[i] / rolls,
'#' * int(result_unfair[i] / rolls / maxH * 40)))
def roll_biased(dice, sides, rolls, min_roll=1, max_roll=None):
if max_roll is None:
max_roll = sides
d = defaultdict(int)
for _ in range(rolls):
d[sum(random.randint(min_roll, max_roll) for _ in range(dice))] += 1
return d
可以打印:
Enter the number of rolls to simulate: 10000
2 0 0.00%
3 0 0.00%
4 632 6.32% ##########
5 1231 12.31% ###################
6 1851 18.51% #############################
7 2480 24.80% ########################################
8 1873 18.73% ##############################
9 1296 12.96% ####################
10 637 6.37% ##########
11 0 0.00%
12 0 0.00%
您也可以使用 random.choices()
将其概括为任意选择(或任意权重):
def roll_from_choices(dice, sides, rolls, allowed_rolls=None):
if allowed_rolls is None:
allowed_rolls = list(range(1, sides+1))
d = defaultdict(int)
for _ in range(rolls):
d[sum(random.choices(allowed_rolls, k=dice))] += 1
return d
您可以称其为:
result_unfair = roll_from_choices(dice, sides, rolls, allowed_rolls=[2, 3, 4, 5])
我会开始一个函数,returns掷骰子(a)的结果,其中可以定制可用选项以排除不可能的选项,例如:
import random
def throw_die(options):
return random.choice(options)
然后我会为一般情况编写代码,您可以拥有 any 个骰子,每个 个不同的能力(待通过作为掷骰子时的选项)。在您的特定情况下,这将是两个骰子,第二个骰子不包括 1
和 6
(b):
dice = [
[1, 2, 3, 4, 5, 6],
[ 2, 3, 4, 5 ]
]
然后为结果分配足够的存储空间(我在这里浪费了少量 space 以确保收集数据的代码更简单):
min_res = sum([min(die) for die in dice]) # Smallest possible result,
max_res = sum([max(die) for die in dice]) # and largest.
count = [0] * (max_res + 1) # Allocate space + extra.
你的数据收集相对简单(我在这里硬编码了滚动计数而不是使用输入,但你可以把它放回去):
rolls = 10000 # rolls = int(input("How many rolls? "))
for _ in range(rolls):
# Throw each die, sum the results, then increment correct count.
result = sum([throw_die(die) for die in dice])
count[result] += 1
并且数据输出可以这样完成(四舍五入而不是截断,以便最高计数有 40 个哈希值——这只是我的 CDO(c) 性质):
hash_mult = 40 / max(count)
for i in range(min_res, max_res + 1):
per_unit = count[i] / rolls
hashes = "#" * int(count[i] * hash_mult + 0.5)
print(f"{i:2d}{count[i]:10d}{per_unit:8.2%} {hashes}")
完整的程序变成:
import random
# Throw a single die.
def throw_die(options):
return random.choice(options)
# Define all dice here as list of lists.
# No zero/negative number allowed, will
# probably break code :-)
dice = [
[1, 2, 3, 4, 5, 6],
[ 2, 3, 4, 5 ]
]
# Get smallest/largest possible result.
min_res = sum([min(die) for die in dice])
max_res = sum([max(die) for die in dice])
# Some elements wasted (always zero) to simplify later code.
# Example: throwing three normal dice cannot give 0, 1, or 2.
count = [0] * (max_res + 1)
# Do the rolls and collect results.
rolls = 10000
for _ in range(rolls):
result = sum([throw_die(die) for die in dice])
count[result] += 1
# Output all possible results.
hash_mult = 40 / max(count)
for i in range(min_res, max_res + 1):
per_unit = count[i] / rolls
hashes = "#" * int(count[i] * hash_mult + 0.5)
print(f"{i:2d}{count[i]:10d}{per_unit:8.2%} {hashes}")
和一些示例运行以查看它的实际效果:
pax:/mnt/c/Users/Pax/Documents/wsl> python prog.py
3 418 4.18% #########
4 851 8.51% ####################
5 1266 12.66% ##############################
6 1681 16.81% ########################################
7 1606 16.06% ######################################
8 1669 16.69% #######################################
9 1228 12.28% #############################
10 867 8.67% ####################
11 414 4.14% #########
pax:/mnt/c/Users/Pax/Documents/wsl> python prog.py
3 450 4.50% ##########
4 825 8.25% ###################
5 1206 12.06% ############################
6 1655 16.55% #######################################
7 1679 16.79% ########################################
8 1657 16.57% #######################################
9 1304 13.04% ###############################
10 826 8.26% ###################
11 398 3.98% #########
pax:/mnt/c/Users/Pax/Documents/wsl> python prog.py
3 394 3.94% #########
4 838 8.38% ####################
5 1271 12.71% ##############################
6 1617 16.17% ######################################
7 1656 16.56% #######################################
8 1669 16.69% ########################################
9 1255 12.55% ##############################
10 835 8.35% ####################
11 465 4.65% ###########
脚注:
(a) 对单骰子和多骰子使用正确的命名法,以防任何非英语使用者感到困惑。
(b) 你也可以处理像 [1, 2, 3, 4, 4, 5, 6]
这样的情况,你得到 4
的可能性是任何其他号码。任何比这更复杂的事情最好用一个元组来处理,该元组代表每个可能的结果及其相对可能性。可能有点太复杂了,无法放入脚注(考虑到这不是问题的要求),但如果您有兴趣,可以随时在 separate 问题中询问这个问题。
(c) 就像强迫症一样,但顺序正确:-)