2017-01-02 1 views
0

파이썬에서 대략 350 줄의 모의 페인트 프로그램이 있습니다. 그러나 채우기 도구를 사용하면 모양을 채우고 모양의 크기에 상관없이 파이 게임 창을 고정시킵니다. 마우스와 창을 움직일 수는 있지만 제목은 "응답 없음"으로 바뀌지 않습니다. 그러나 마우스를 창 위로 가져 가면 커서가 회전 휠로 바뀝니다.파이썬 재귀 함수가 파이 게임이 멈추는 원인이

내 채우기 도구는 채우기가 주변 픽셀을 채우고 색이 다른 경우 중지되는 재귀 프로그램입니다.

재귀 한계가 증가했으며 스택 크기는 64MB입니다.

여기의 단순화 된 버전입니다 : 나는 모양을 기입 한 후 파이 게임이 정지 이유

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() 

누구나 알아?

+0

재귀의 많은 (대부분?) 사용을 루프로 바꿀 수 있습니다. 논리는 약간 다르지만 (헐떡 거림) 위험은 없습니다. StackOverflow! :-) –

+0

예, IDLE은 최대 재귀 제한 오류를주지 않습니다. – WARMFREEZER

+1

좋아요, 그래서 11시입니다. * 코드 *가 어디에 있는지 알고 계십니까? 해당 루틴에 항목을 인쇄하거나 기록하십시오. 다른 프로파일 링 방법을 실행하십시오. 'pdb '에서 실행하고 응답이 없으면^C를 누릅니다. 어쩌면 코드가 멈춰있을 때도 생각조차하지 않을 수도 있습니다. 디버깅은 프로그래밍에서 가장 중요하고 가장 배운 기술 중 하나입니다. 누구나 프로그램을 쓸 수는 있지만 거의 아무도 프로그램을 시작할 수 없습니다. * 출처 : me, ca. 1983 년 UNIX 세계에서 최초의 * working * 소스 레벨 C 디버거를 판매하기 시작했습니다. –

답변

1

n4 (n4 = n4 + 1)와 관련하여 오타가 화면 상단에서 제대로 확인되지 않습니다. 그리는 직사각형이 이것을 테스트하기 위해 아마도 클릭하면 화면 상단이 터치됩니다. 그것은 위로 영원히 재발합니다.

나는 또한이를 정리하는 방법에 대한 위의 몇 가지 의견을 많이 보냈습니다.

관련 문제