掷骰子模拟中的递归错误(在一次掷骰子中匹配“x”骰子需要多长时间)

2024-04-25 10:07:34 发布

您现在位置:Python中文网/ 问答频道 /正文

好吧,所以对编码和python非常非常陌生。在

这个脚本的目标:你要掷多少次“x”骰子才能让它们都产生相同的值?在

下面是它要做的: 从用户那里取一些骰子 模拟掷骰子 如果所有骰子都匹配,请打印出成功的尝试次数,如果不匹配,请再试一次。在

发生的情况如下:

如果用户输入少量骰子,1-4个左右,就可以了。在

一旦用户输入5个骰子(或更多),就会出现“调用python对象时超出最大递归深度”的错误。这似乎是随机.randint在

我希望有人能给我一些关于如何避免这个错误的指导,因为我不知道为什么递归会变得无限大。我试图对我的代码进行注释,以便它有意义(至少对我来说)。在

如果有关系的话,我将在热情的树冠环境中使用Python2.6。在

import random

#create the empty list to store values
dierolls = []  

#used to roll ythe dice
def diceroll():  
    return random.randint(1,6)

#gets user input to determine how many dice we are rollin    
def askfornumofdicetoroll():  
    return int(input("How many dice should we roll?"))

#fills the dierolls list with the appropriate     
def fillthelist(dicecount): 
    #empty the list and start fresh each iteration
    dierolls[:] = []

    #input a die roll for each die the user says to roll
    for i in range(0,dicecount):
        dierolls.append(diceroll())
    #print dierolls #used to check that this code was running
    return dierolls

#what to do when all the dice match
def wongame(attempts):
    print("You matched all the dice in", attempts , "tries")

#compares all the items in the list, and see's if they match
def comparelist(dicetoroll,attempts):

    fillthelist(dicetoroll)
    #print statement used to make sure this was running
    print dierolls
    #print statment used to see if this section of code was running
    print(all(dierolls[0] == elem for elem in dierolls))

    #gives a check to make sure the code is running and not stopped by
    #printing a result every 100 attempts
    if attempts%100 == True:
        print attempts
    else:
        pass

    #does the actual check to see if all items in the list are the same
    if all(dierolls[0] == elem for elem in dierolls):
        #if all items in list are the same, go to the results function
        wongame(attempts)
    else:
        #increment the attempts counter, and try again
        attempts += 1
        comparelist(dicetoroll, attempts)  

#runs the program
def main():
    attempts = 1
    dicetoroll = askfornumofdicetoroll()
    comparelist(dicetoroll,attempts)

Tags: thetoinifdefall骰子dice
2条回答

对于您的问题,避免此错误的最佳方法是避免递归。虽然可以说大多数迭代过程都可以递归地完成,但这并不意味着它应该是递归的。在

在您的例子中,您尝试迭代一个未确定的次数,随着骰子数量的增加,可能会以指数形式增大,因为掷骰子的组合数量是6^n或{}代表n个骰子。在

不仅如此,你的迭代很简单,每次只迭代一个变量(attempts)1。换句话说,你正在运行完全相同的代码一遍又一遍。。。直到某个停止状态。通常的答案是什么?一个循环。更具体地说,是while循环。不需要递归。在

因此,请将代码重新构造为:

#compares all the items in the list, and see's if they match
def comparelist(dicetoroll,attempts):

    #continue doing this unless break or return
    while True:
        fillthelist(dicetoroll)
        #print statement used to make sure this was running
        print dierolls
        #print statment used to see if this section of code was running
        print(all(dierolls[0] == elem for elem in dierolls))

        #gives a check to make sure the code is running and not stopped by
        #printing a result every 100 attempts
        if attempts%100 == True:
            print attempts
        else:
            pass

        #does the actual check to see if all items in the list are the same
        if all(dierolls[0] == elem for elem in dierolls):
            #if all items in list are the same, go to the results function
            wongame(attempts)
            #break out of the loop
            break
        else:
            #increment the attempts counter, and try again
            attempts += 1
     return #if you want the function to return something

Python有fairly low recursion limit by default (IIRC, 1000 stack frames)。你的代码没有限制递归(没有maximum_attempts检查),所以如果它递归太多次试图“赢”,它就会达到极限并死亡。在

你可以set a higher recursion limit,但这只会稍微扩大上限;每增加一个骰子,就会使一个骰子获胜的几率降低1/6,所以你总是用一个骰子赢,2个赢1/6,3个赢1/36,4个赢1/216,5个赢1/1296,等等。赢的几率会迅速下降;更高的递归限制仍会偶尔失败,在大多数情况下,它不会给你更多的骰子额外的容量。在

你真的需要抛弃递归,转而使用命令式技术。在

相关问题 更多 >