我设置了一个递归洪水填充算法,由于(我认为)达到堆栈溢出/递归深度而导致段错误。我不想弄乱堆栈限制,创建这个特定算法的迭代版本超出了我的技能水平。所以,我只想让函数在这么多循环后停止,所以它只会安全地填充小区域。
我创建了一个测试程序来解决终止条件的实现,但是我注意到尽管完成了它的工作,该函数仍在运行。例如,在下面的代码中,让它运行 200,000 次可以正确填充窗口,但 300,000 也是如此,当我让它运行 400,000 次时,它会在 337,977 处安全地停止循环。所以我很困惑到底是什么让它在 337,977 处停止,以及如何让它在我用眼睛看到的洪水填充的实际结束时停止,循环次数不到 200,000 次。
#include <stdio.h>
#include <SDL2/SDL.h>
Uint32 myPixelColour(Uint32 *pixels, int x, int y, int windowWidth, int windowHeight)
{
Uint32 thisPixelColour = 0;
thisPixelColour = pixels[x + y * windowWidth];
return thisPixelColour;
}
int mySameColour(Uint32 thisPixelColour, Uint32 thatPixelColour)
{
return (thisPixelColour == thatPixelColour);
}
void myFill(Uint32 *pixels, int windowWidth, int windowHeight, int x, int y, Uint32 finColour, int *counter)
{
if(!((x>=0) && (x<windowWidth) && (y>=0) && (y<windowHeight))) return;
if(*counter == 400000) return; /* 200000 fills the window, so does 300000 */
printf("%d\n", *counter);
*counter = *counter + 1;
Uint32 ogColour = myPixelColour(pixels, x, y, windowWidth, windowHeight);
if(mySameColour(ogColour, finColour)) return;
pixels[x+y*windowWidth] = finColour;
myFill(pixels, windowWidth, windowHeight, x, y+1, finColour, counter);
myFill(pixels, windowWidth, windowHeight, x-1, y, finColour, counter);
myFill(pixels, windowWidth, windowHeight, x, y-1, finColour, counter);
myFill(pixels, windowWidth, windowHeight, x+1, y, finColour, counter);
}
int main(void)
{
const int windowWidth = 400;
const int windowHeight = 212;
int counter;
counter = 1;
SDL_Window *window = SDL_CreateWindow("WindowTitle", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, SDL_WINDOW_SHOWN);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, windowWidth, windowHeight);
Uint32 *pixels = NULL;
pixels = (Uint32 *) malloc (sizeof(Uint32)*(Uint32)windowWidth*(Uint32)windowHeight);
memset(pixels, 255, (Uint32)windowWidth*(Uint32)windowHeight*sizeof(Uint32));
Uint32 finColour = 0x99FFCC;
SDL_Point mouse_position;
int success = 1;
while(success)
{
SDL_Event userAction;
SDL_GetMouseState(&mouse_position.x, &mouse_position.y);
SDL_UpdateTexture(texture, NULL, pixels, (int)((Uint32)windowWidth * sizeof(Uint32)));
while(SDL_PollEvent(&userAction))
{
switch(userAction.type)
{
case SDL_QUIT: success = 0; break;
case SDL_KEYDOWN:
if(userAction.key.keysym.sym == SDLK_f)
{
myFill(pixels, windowWidth, windowHeight, 1, 1, finColour, &counter);
}
break;
}
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
free(pixels);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
return 0;
}