【问题标题】:What is making "RecursionError: maximum recursion depth exceeded in comparison" happen?是什么导致“RecursionError:比较中超出最大递归深度”发生?
【发布时间】:2022-08-09 19:49:45
【问题描述】:

我正在用 python 制作一个 2048 游戏,并且我正在使用 def 函数来执行我的某个代码块,只要我想。但是我在尝试生成在游戏开始时以及每当你移动时产生的随机数时遇到了一个问题。RecursionError:比较超过最大递归深度.我不知道这意味着什么以及它是如何发生的。这是简化的代码块:

def game():
if not \'n\' in locals():
        random_n()

#Generating 2/4s
def random_n():
    num = randint(0,100)
    global tile_number, n
    if num > 10:
        tile_number = 2
    else:
        tile_number = 4
    
    if not \'n\' in locals():
        n = 0
        random_n()
    game()

while True:
    events = pygame.event.get()
    for event in events:

    #WASD (only really the end matters(i\'m just showing I have a loop at the bottom))
        if event.type == pygame.KEYDOWN:
            def keybinds():
                if event.key == pygame.K_w:
                    print(\"Pressed W\")
                elif event.key == pygame.K_a:
                    print(\"Pressed A\")
                elif event.key == pygame.K_s:
                    print(\"Pressed S\")
                elif event.key == pygame.K_d:
                    print(\"Pressed D\")
    
                #ARROWS
                elif event.key == pygame.K_UP:
                    print(\"Pressed UP\")
                elif event.key == pygame.K_LEFT:
                    print(\"Pressed LEFT\")
                elif event.key == pygame.K_DOWN:
                    print(\"Pressed DOWN\")
                elif event.key == pygame.K_RIGHT:
                    print(\"Pressed RIGHT\")
                else:
                    keybinds()
                random_n()
                
            keybinds()

这不是我的实际代码,而是一个简化版本,以消除我认为不会影响错误的事情,但如果这不是真的,这是我的真实代码:

import pygame
from random import randint

#Initialising PyGame
pygame.init()
 
#Creating Display
w = 640
h = 780
screen = pygame.display.set_mode((w,h))

#PyGame window name and icon
pygame.display.set_caption(\'2048\')
icon = pygame.image.load(\'2048 icon.png\')
pygame.display.set_icon(icon)

#Variables
background_c = 236, 231, 217
font_c = 147, 121, 97
button_c = font_c
menu_restart_background_c = button_c
game_background_c = 191, 173, 155
score_background_c = game_background_c
font1 = pygame.font.Font(\'calibri font sv\\Calibri Bold.TTF\', 30)
font2 = pygame.font.Font(\'calibri font sv\\Calibri Bold.TTF\', 80)
font3 = pygame.font.Font(\'calibri font sv\\Calibri Bold.TTF\', 60)
game_slots_c = 208, 193, 176
number_text_c = {\"2+4_c\": (123, 110, 98), \"above4_c\": (255,255,255)}
#number_background_c = {\"2\": (238, 228, 218), \"4\": (237, 224, 199), \"8\": (242, 177, 122), \"16\": (245, 149, 99),
#\"32\": (255, 116, 85), \"64\": (, , ), \"128\": (, , ), \"256\": (, , ), \"512\": (255, 255, 255),
#\"1024\": (255, 255, 255), \"2048\": (255, 255, 255)}
play = 0

#Menu
def menu():
    #Colours + Rectangles
    screen.fill((249, 248, 236))
    pygame.draw.rect(screen, background_c,(0,0, w, h/10))
    #Title Text
    title = font1.render(\"2048\", True, font_c)
    screen.blit(title, (35, 25)) 
    pygame.display.flip()

    #Button
    pygame.draw.rect(screen, button_c, (49, 349, 536, 100), 0, 12)
    #Button Text
    pbutton_f = font2.render(\"Play\", True, (255,255,255))
    screen.blit(pbutton_f,(240, 360))
    pygame.display.update()
menu()

#Game
def game():
    i = 114
    #Game board
    screen.fill(background_c)
    game_board = pygame.Surface((536, 536))
    game_board.fill((background_c))
    pygame.draw.rect(game_board, game_background_c,(0,0, 536, 536),0,12)
    #Game slots
    while i <= 2064:
        if i <= 504:
            pygame.draw.rect(game_board, game_slots_c,((16+i)-114, 16, 114, 114),0,6)
        elif i <= 1024:
            pygame.draw.rect(game_board, game_slots_c,((16+i)-634, 146, 114, 114),0,6)
        elif i <= 1544:
            pygame.draw.rect(game_board, game_slots_c,((16+i)-1154, 276, 114, 114),0,6)
        else:
            pygame.draw.rect(game_board, game_slots_c,((16+i)-1674, 406, 114, 114),0,6)
        i += 130
    screen.blit(game_board,(49, 200))
    #Menu, Restart, Scores
    pygame.draw.rect(screen, menu_restart_background_c,(49, 25, 200, 70),0,7)
    pygame.draw.rect(screen, menu_restart_background_c,(49, 110, 200, 70),0,7)
    pygame.draw.rect(screen, score_background_c,(284, 25, 138, 155),0,7)
    pygame.draw.rect(screen, score_background_c,(437, 25, 138, 155),0,7)
    mbutton_f = font3.render(\"Menu\", True , (255,255,255))
    screen.blit(mbutton_f, (75, 32))
    rbutton_f = font3.render(\"Restart\", True , (255,255,255))
    screen.blit(rbutton_f, (58, 118))
    if not \'n\' in locals():
        random_n()

#Generating 2/4s
def random_n():
    num = randint(0,100)
    global tile_number, n
    if num > 10:
        tile_number = 2
    else:
        tile_number = 4
    
    if not \'n\' in locals():
        n = 0
        random_n()
    game()

    pygame.display.update()


#Loop
while True:
    events = pygame.event.get()
    for event in events:

        #Button functions
        if event.type == pygame.MOUSEBUTTONDOWN:
            xy = pygame.mouse.get_pos()
            if play == 0:
                if 49 <= xy[0] <= 536:
                    if 349 <= xy[1] <= 449:
                        game()
                        play = 1

            if play == 1:
                if 49 <= xy[0] <= 249:
                    if 25 <= xy[1] <= 95:
                        menu()
                        play = 0
                    if 110 <= xy[1] <= 180:
                        game()

        #Making the \"X\" button work
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        #WASD
        if event.type == pygame.KEYDOWN:
            def keybinds():
                if event.key == pygame.K_w:
                    print(\"Pressed W\")
                elif event.key == pygame.K_a:
                    print(\"Pressed A\")
                elif event.key == pygame.K_s:
                    print(\"Pressed S\")
                elif event.key == pygame.K_d:
                    print(\"Pressed D\")
    
                #ARROWS
                elif event.key == pygame.K_UP:
                    print(\"Pressed UP\")
                elif event.key == pygame.K_LEFT:
                    print(\"Pressed LEFT\")
                elif event.key == pygame.K_DOWN:
                    print(\"Pressed DOWN\")
                elif event.key == pygame.K_RIGHT:
                    print(\"Pressed RIGHT\")
                else:
                    keybinds()
                random_n()
                
            keybinds()
  • 这个错误意味着一个递归函数调用它自己,它调用它自己,它调用它自己......一遍又一遍。
  • if not \'n\' in locals(): 你怎么期望有一个名为 n 的局部变量?您明确表示n 是全球性的。
  • @JohnGordon 什么是解决方案?
  • Python 有一个最大的递归深度,这意味着它允许一个递归函数只调用自身多次而不返回。这样做的原因是,深度递归调用有 3 个问题之一:1) 有一种更有效的方式来迭代地执行操作,2) 问题将呈指数级爆发并且永远不会完成,以及 3) 算法已经进入一个循环,永远不会终止。实际原因是每个递归调用都会产生一些开销,并且为递归调用的开销保留的空间量是有限的。最有可能出现循环。
  • 在您的情况下,您检查if not \'n\' in locals():,在这种情况下,您再次调用该函数。它将再次检查同一件事,再次调用自己,再次检查,等等。无限循环 - 一个循环。

标签: python python-3.x pygame stack-overflow


【解决方案1】:

正如错误所说,您已达到最大递归限制。它发生在递归函数中——定义一个函数并在该函数中调用相同的函数。对于您的情况,您定义了一个 keybinds 函数,并在 else 部分在其中调用了相同的函数。

尝试删除 else 部分和底层的 keybinds() 代码块来解决您的问题,尽管我不完全确定这是否是您正在寻找的。

def keybinds():
    if event.key == pygame.K_w:
        print("Pressed W")
    elif event.key == pygame.K_a:
        print("Pressed A")
    elif event.key == pygame.K_s:
        print("Pressed S")
    elif event.key == pygame.K_d:
        print("Pressed D")

    # ARROWS
    elif event.key == pygame.K_UP:
        print("Pressed UP")
    elif event.key == pygame.K_LEFT:
        print("Pressed LEFT")
    elif event.key == pygame.K_DOWN:
        print("Pressed DOWN")
    elif event.key == pygame.K_RIGHT:
        print("Pressed RIGHT")
    # else:
    #     keybinds()
    random_n()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-23
    • 2019-04-18
    • 2021-02-13
    • 2022-01-22
    • 2020-03-14
    • 2017-03-24
    • 2020-10-08
    • 2020-07-13
    相关资源
    最近更新 更多