2017-01-02 56 views
0

我有蟒蛇一個非常複雜的模擬畫圖程序即大約350線長。但是,當我使用我的填充桶工具時,它會填充我繪製的形狀,然後凍結Pygame窗口而不管形狀的大小。我仍然可以移動鼠標和窗口,標題不會更改爲「不響應」。但是當我的鼠標懸停在窗口上時,光標變爲紡車。Python的遞歸函數導致Pygame的以凍結

我的填充桶工具是洪水填補了周圍的像素,當顏色不同停止遞歸程序。

我增加了遞歸限制和堆棧大小爲64 MB。

這裏是它的一個簡化版本:

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

誰知道爲什麼pygame的凍結我填的形狀後?

+0

遞歸的許多(大多數?)用法可以用循環替換。邏輯只是略有不同,但沒有(gasp!)StackOverflow的危險! :-) –

+0

是的,但從來沒有空閒給了我最大遞歸限制 – WARMFREEZER

+1

OK的錯誤,所以這是晚上11點,你知道*你的代碼*是什麼?打印出日誌條目到該例程中。運行其他一些分析方法。在'pdb'中運行它,並在它變爲無響應時點擊^ C。也許它甚至不在你認爲它掛起的代碼中。調試是編程中最重要和最少教授的技能之一。每個人都可以編寫一個程序,但幾乎沒有人可以在第一時間得到他們的程序*資料來源:我,大約。 1983年,當我開始在UNIX世界中銷售第一個* working *源代碼級C調試器時。 –

回答

1

你就到N4(n4 = n4 + 1)錯字不正確的邊界檢查要關閉屏幕的頂部。你正在繪製的矩形,可能點擊進行測試,觸及屏幕的頂部。它會永遠向上遞增。

我還就如何清潔起來顯著做出上述一些其他意見。