J'ai un programme de simulation de maquette en python très complexe d'environ 350 lignes. Cependant, lorsque j'utilise mon outil de remplissage, il remplit la forme que j'ai dessinée puis gèle la fenêtre Pygame, quelle que soit la taille de la forme. Je peux toujours déplacer la souris et la fenêtre, et le titre ne change pas pour "Ne répond pas". Mais quand ma souris survole la fenêtre, le curseur se transforme en roue tournante.La fonction de récursion de Python provoque le blocage de Pygame
Mon outil de remplissage de seau est un programme de récursion dont l'inondation remplit les pixels environnants et s'arrête lorsque la couleur est différente.
J'ai augmenté la limite de récursivité et la taille de la pile est de 64 mB.
Voici une version simplifiée de celui-ci:
from pygame import *
from sys import *
from math import *
from threading import *
screen = display.set_mode((800,600)) #Same size as my real paint canvas
white = (255,255,255)
red = (255,0,0)
brush = Rect(0,0,25,25)
bucket = Rect(30,0,25,25)
running = True
tool = 1
setrecursionlimit(20000)
stack_size(67108864)
screen.fill(white)
draw.rect(screen,0,(0,0,25,25),0)
draw.rect(screen,0,(30,0,25,25),0)
def fill(x,y,oldColor,newColor,n1,n2,n3,n4):
if n1 >=800 : #Stops flooding right when it exceeds width
return
if n2 <= 0: #Stops flooding left
return
if n3 >= 600: #Stops down
return
if n4 <= 0: #Stops up
return
try:
if screen.get_at((x,y)) != oldColor:
return
except IndexError:
return
draw.rect(screen,newColor,(x,y,1,1),0)
fill(x+1,y,oldColor,newColor,n1=n1+1,n2=n2,n3=n3,n4=n4) #Floods right
fill(x-1,y,oldColor,newColor,n1=n1,n2=n2-1,n3=n3,n4=n4) #Left
fill(x,y+1,oldColor,newColor,n1=n1,n2=n2,n3=n3+1,n4=n4) #Down
fill(x,y-1,oldColor,newColor,n1=n1,n2=n2,n3=n3,n4=n4+1) #Up
while running:
for e in event.get():
if e.type == QUIT:
running = False
mb = mouse.get_pressed()
mx,my = mouse.get_pos()
if brush.collidepoint(mx,my) and mb[0] == 1:
tool = brush
if bucket.collidepoint(mx,my) and mb[0] == 1:
tool = fill
if tool == brush and mb[0] == 1:
draw.circle(screen,red,(mx,my),5,0)
if tool == fill and mb[0] == 1:
pixel = screen.get_at((mx,my))
fill(mx,my,pixel,red,mx,mx,my,my)
display.flip()
quit()
Quelqu'un sait pourquoi Pygame gèle après que je remplirai une forme?
De nombreuses (plus?) Utilisations de la récursivité peuvent être remplacées par une boucle. La logique est seulement légèrement différente, mais il n'y a aucun danger de (gasp!) StackOverflow! :-) –
Oui, mais IDLE ne me donne jamais une erreur de limite de récursivité max – WARMFREEZER
OK, donc il est 23 heures, savez-vous où * votre code * est? Imprimez/consignez les entrées dans cette routine. Exécutez une autre méthode de profilage. Exécutez-le dans 'pdb' et appuyez sur^C quand il ne répond plus. Peut-être que ce n'est même pas dans le code que vous pensez qu'il est quand il se bloque. Le débogage est l'une des compétences les plus importantes et les moins enseignées en programmation. Tout le monde peut écrire un programme, mais presque personne ne peut obtenir son programme correctement * la toute première fois. * Source: moi, ca. 1983, quand j'ai commencé à vendre le premier débogueur C * source * au niveau source dans le monde UNIX. –