我仍在考虑自己是一个编程新手(我的声誉很大程度上是因为gamedev.SE),因此我遇到了一个我自己无法解决的问题。
我有一个函数,它接受指定数量的骰子并滚动它们,并返回结果。但是,如果它碰巧滚动了可用的最高值,例如6个模具上的6,则它会移除所讨论的模具并在其位置滚动两个新的骰子。它按预期工作,但我在实现另一个必要的部分时遇到问题:跟踪1的滚动数量,特别是在初始骰子中滚动的任何1。
from random import randint
def roll_die(number, sides=6):
results = []
for dice in range(number):
roll = randint(1, sides)
if roll == sides:
#rolling two new dice instead
results.append(roll_die(2, sides))
else:
results.append(roll)
return sum(results)
我也不确定是否将结果存储在列表中然后对其进行求和是最好的方法,但我想我永远不会达到足够多的骰子来担心这一点。
如何跟踪第一个掷骰子?当我说“第一个”时,我的意思是在最初指定的数字中进行滚动,在添加任何新骰子之前由于滚动六个。
答案 0 :(得分:2)
第二个数组可能是original = []
,而roll == sides
部分的sides
部分会在else
附加roll
附加return [sum(results), original]
。然后你可以if roll == sides:
。在results.append(roll_die(2,sides)[0])
中,您必须执行from random import randint
def roll_die(number, sides=6):
results = []
ones = 0
for dice in range(number):
roll = randint(1, sides)
if roll == sides:
#rolling two new dice instead
results.append(roll_die(2, sides)[0])
else:
results.append(roll)
if roll == 1:
ones += 1
return sum(results), ones
在回答您的列表问题时,您可以将滚动的值添加到每个滚动的整数然后返回。
一个例子:
{{1}}
答案 1 :(得分:2)
你(和另一个答案)使这太复杂了。
不要立即掷骰子。记下有多少新掷骰子,并在你完成簿记后滚动它们。
不要建立已滚动的所有内容的列表。你不需要它。滚动初始骰子,收集统计数据,然后递归以滚动更多骰子。
避免编写显式循环来累积数据。 Python知道如何累积数据。只需告诉它你想在列表中最终得到什么(通过列表理解)。
不要进行多次递归调用。一个人会这样做。想想你将如何用物理骰子做到这一点:你将六个一起拉出来,然后将它们翻倍并重新卷起。
from random import randint
def roll_dice(count, sides=6):
if count == 0: return (0, 0) # we need to guard against infinite recursion.
initial = [randint(1, sides) for die in range(count)]
initial_mins = initial.count(1)
initial_maxes = initial.count(sides)
# Add up all the dice that weren't maximum.
subtotal = sum(result for result in initial if result != sides)
# Recurse to re-roll the maxed-out dice.
ignored, reroll = roll_dice(2 * initial_maxes, sides)
return (initial_mins, subtotal + reroll)
请注意,递归调用会返回一些我们忽略的初始调用,因为我们只关心第一次滚动的那些。我们解压缩递归结果并保留有趣的值,即递归重新掷骰子的总数。
我们也可以迭代地完成它,并且只在第一次迭代中加起来:
from random import randint
def roll_dice(count, sides=6):
initial_mins = None
result = 0
while count:
dice = [randint(1, sides) for die in range(count)]
if initial_mins == None: initial_mins = dice.count(1)
result += sum(result for result in dice if result != sides)
count = 2 * dice.count(sides) # number to roll the next time through.
return (initial_mins, result)
请注意None
sentinel值是如何用于确保我们第一次设置initial_mins
然后每隔一次跳过它。这比使用“不可能”的整数值(如-1)更清晰。拥抱动态类型。 :)