Python 掷骰子
Python dice throw
因此,对于一个私人项目,我想将几个不同骰子的掷数数字化。到目前为止,我的代码要求输入、掷出的骰子数量和种类,并输出结果。到目前为止,我有以下内容:
import dice
die = input("Roll the dice: ")
if die == "d4":
dice.d4()
elif die == "d6":
dice.d6()
而骰子模块包含
import random
def d4():
n = int(input())
x = 0
d4=[1, 2, 3, 4]
while x < n:
print(random.choice(d4))
x = x + 1
def d6():
n = int(input())
x = 0
d6=[1, 2, 3, 4, 5, 6]
while x < n:
print(random.choice(d6))
x = x + 1
等等。
用于确定骰子类型的 if-elif 检查似乎可以使用,但感觉有些笨拙。
现在回答我的问题:是否有更优雅的方法来检查骰子的数量和类型?
例如,我可以输入 3d6 并且脚本计算 3 次 d6 投掷?
Is there a more elegant way to check for the number and type of dice?
您可以使用正则表达式解析 (\d+)d(\d+)
以便从 XdY 中提取 X 和 Y。或者甚至只是在 "d"
上拆分,因为输入格式严格是 <numbers>d<numbers>
,这意味着拆分没有歧义。
据此,你可以使用getattr
从骰子模块中获取相应的方法,虽然实际上骰子模块并不是很有用:dX
只是random.randint(1, X)
。所以你可以按照以下方式做一些事情:
def roll(spec):
rolls, dice = map(int, spec.split('d'))
return [
random.randint(1, dice)
for _ in range(rolls)
]
并且对于您要支持的骰子的“形状”没有任何限制,这对于从 1 到基本上无穷大的任何面数都没有问题。
顺便说一句,这可以通过使用 random.choices
和显式 range
进一步修改。你觉得简单不简单是个人喜好问题:
def roll(spec):
rolls, dice = map(int, spec.split('d'))
return random.choices(range(1, dice+1), k=rolls)
这具有不太广泛的兼容性(在 python 3.6 中添加了选择)但可以很容易地扩展以支持例如加权骰子,或某些面重复的特殊骰子(虽然显然后者可以通过从常规骰子重新分配值来支持)。
最“专业”的方法是使用正则表达式 (read about regex here)。
对于您输入的模式 ([0-9]*)(d[46])
它匹配两组。
对于输入 3d6
它将匹配 ('3', 'd6')
.
此外,您在列表中使用 random.choice
从 1
到 6
的随机数,您可以使用 d6
例如,random.randint(1, 6)
而不是 random.choice
它将 return 从 1
到 6
的随机数。
因此,对于一个私人项目,我想将几个不同骰子的掷数数字化。到目前为止,我的代码要求输入、掷出的骰子数量和种类,并输出结果。到目前为止,我有以下内容:
import dice
die = input("Roll the dice: ")
if die == "d4":
dice.d4()
elif die == "d6":
dice.d6()
而骰子模块包含
import random
def d4():
n = int(input())
x = 0
d4=[1, 2, 3, 4]
while x < n:
print(random.choice(d4))
x = x + 1
def d6():
n = int(input())
x = 0
d6=[1, 2, 3, 4, 5, 6]
while x < n:
print(random.choice(d6))
x = x + 1
等等。 用于确定骰子类型的 if-elif 检查似乎可以使用,但感觉有些笨拙。 现在回答我的问题:是否有更优雅的方法来检查骰子的数量和类型? 例如,我可以输入 3d6 并且脚本计算 3 次 d6 投掷?
Is there a more elegant way to check for the number and type of dice?
您可以使用正则表达式解析 (\d+)d(\d+)
以便从 XdY 中提取 X 和 Y。或者甚至只是在 "d"
上拆分,因为输入格式严格是 <numbers>d<numbers>
,这意味着拆分没有歧义。
据此,你可以使用getattr
从骰子模块中获取相应的方法,虽然实际上骰子模块并不是很有用:dX
只是random.randint(1, X)
。所以你可以按照以下方式做一些事情:
def roll(spec):
rolls, dice = map(int, spec.split('d'))
return [
random.randint(1, dice)
for _ in range(rolls)
]
并且对于您要支持的骰子的“形状”没有任何限制,这对于从 1 到基本上无穷大的任何面数都没有问题。
顺便说一句,这可以通过使用 random.choices
和显式 range
进一步修改。你觉得简单不简单是个人喜好问题:
def roll(spec):
rolls, dice = map(int, spec.split('d'))
return random.choices(range(1, dice+1), k=rolls)
这具有不太广泛的兼容性(在 python 3.6 中添加了选择)但可以很容易地扩展以支持例如加权骰子,或某些面重复的特殊骰子(虽然显然后者可以通过从常规骰子重新分配值来支持)。
最“专业”的方法是使用正则表达式 (read about regex here)。
对于您输入的模式 ([0-9]*)(d[46])
它匹配两组。
对于输入 3d6
它将匹配 ('3', 'd6')
.
此外,您在列表中使用 random.choice
从 1
到 6
的随机数,您可以使用 d6
例如,random.randint(1, 6)
而不是 random.choice
它将 return 从 1
到 6
的随机数。