Pygame实现Flood Fill遇‘maximum recursion depth exceeded in comparison’错误
递归式Flood Fill在Pygame中同时保留左右方向调用崩溃的问题定位
你的问题主要由两个原因导致:
1. 边界判断逻辑错误
原代码里的x > image.get_width()和y > image.get_height()写错了——Pygame图像的像素坐标范围是0 ≤ x < 图像宽度、0 ≤ y < 图像高度,当x等于宽度或者y等于高度时,已经超出图像范围了。这个错误会导致程序尝试访问不存在的像素,触发异常;当同时保留左右方向递归时,越界的概率大幅提升,直接引发崩溃。
2. 递归栈溢出
Python默认递归深度限制在1000左右,当填充较大的连续区域时,递归调用会快速耗尽栈空间。同时保留左右方向递归时,容易出现“来回递归”的情况(比如刚处理完x+1的像素,又递归处理x-1回到当前像素,虽然此时像素已经被改为新颜色,但递归栈已经累积了大量调用),进一步加速栈溢出。
修复步骤(尽量少改动原代码)
第一步:修正边界判断
把原代码中的边界条件改成正确的范围判断,修改后的递归版本代码:
full_canvas = flood_fill(full_canvas, mouse_history[-1][0], mouse_history[-1][1], brush_colour, old_colour, mouse_history[-1]) def flood_fill(image, x, y, new_colour, old_colour, start_pixel): # 修正边界判断:x >= 宽度 或 y >= 高度时直接返回 if x < 0 or x >= image.get_width() or y < 0 or y >= image.get_height(): return pixel = image.get_at((x, y)) pixel_colour = (pixel[0], pixel[1], pixel[2]) # 其他终止条件:已替换为新颜色、不是目标旧颜色、透明像素 if pixel_colour == new_colour or pixel_colour != old_colour or pixel[3] < 1: return image.set_at((x, y), new_colour) # 四个方向递归调用 flood_fill(image, x+1, y, new_colour, old_colour, start_pixel) flood_fill(image, x-1, y, new_colour, old_colour, start_pixel) flood_fill(image, x, y+1, new_colour, old_colour, start_pixel) flood_fill(image, x, y-1, new_colour, old_colour, start_pixel) return image
第二步:解决递归栈溢出问题
如果填充大区域时仍然崩溃,可以临时提高Python的递归深度限制(不推荐用于超大区域):
在调用flood_fill之前添加以下代码:
import sys sys.setrecursionlimit(10000) # 根据你的画布大小调整数值
如果想要更稳定的方案,改成迭代版(用栈模拟递归,改动不大,避免栈溢出):
full_canvas = flood_fill(full_canvas, mouse_history[-1][0], mouse_history[-1][1], brush_colour, old_colour, mouse_history[-1]) def flood_fill(image, x, y, new_colour, old_colour, start_pixel): stack = [(x, y)] width = image.get_width() height = image.get_height() while stack: cx, cy = stack.pop() # 边界判断 if cx < 0 or cx >= width or cy < 0 or cy >= height: continue pixel = image.get_at((cx, cy)) pixel_colour = (pixel[0], pixel[1], pixel[2]) if pixel_colour == new_colour or pixel_colour != old_colour or pixel[3] < 1: continue image.set_at((cx, cy), new_colour) # 四个方向加入栈 stack.append((cx+1, cy)) stack.append((cx-1, cy)) stack.append((cx, cy+1)) stack.append((cx, cy-1)) return image
内容的提问来源于stack exchange,提问作者Oyavo
相关产品推荐
相关产品推荐

