2015-06-05 24 views
0

我在泡沫射击游戏工作。当我用相同颜色的射手泡泡击中泡泡时,我必须删除泡泡,并尝试搜索使用泡泡填充算法删除哪个泡泡。当射手泡沫触碰另一个泡沫我有一个错误:BubbleShooter游戏中的Flood-Fill算法

Exception in thread "Thread-1" java.lang.StackOverflowError 

我实现的洪水填充算法:

public void floodFill(int disX, int disY){ 
    //up 
    if(tab[disX][disY - 1] != null){ 
     if (tab[disX][disY - 1].c == tab[disX][disY].c){ 

      floodFill(disX, disY - 1); 
      tab[disX][disY - 1] = null; 
     } 
    } 
    //right 
    if(tab[disX + 1][disY] != null){ 
     if (tab[disX + 1][disY].c == tab[disX][disY].c){ 
      floodFill(disX + 1, disY); 
      tab[disX + 1][disY] = null; 
     } 
    } 
    //left 
    if(tab[disX - 1][disY] != null){ 
     if (tab[disX - 1][disY].c == tab[disX][disY].c){ 
      floodFill(disX - 1, disY); 
      tab[disX - 1][disY] = null; 
     } 
    } 
    //down 
    if(tab[disX][disY +1] != null){ 
     if (tab[disX][disY +1].c == tab[disX][disY].c){ 
      floodFill(disX, disY + 1); 
      tab[disX][disY + 1] = null; 
     } 
    } 
} 

泡泡触摸自己上下左右。

你知道我做错了吗?

回答

0

您正在递归而不将当前数组单元格设置为null,从而导致无限递归。你应该标记当前小区做floodFill(X, Y);

之前访问你也更好地与另一个数组markVisited跟踪所在小区,而不是使当前单元格null

下面是正确的代码:

markVisited[disX][disY] = true; // mark the current node as visited 
if(tab[disX][disY - 1] != null && !markedVisited[disX][disY-1]){ // test if target cell is notvisited 
    if (tab[disX][disY - 1].c == tab[disX][disY].c){ 

     floodFill(disX, disY - 1); 

    } 
} 

markedVisited其中markedVisited是一个布尔数组,让您可以跟踪已经访问过的单元格(init为false)。

希望它能帮助:)

0

因为你floodFill是如何实现的,你一遍一遍重温以前的位置,直到你得到一个堆栈溢出(因为你的递归深度是如此之高)。

例如,考虑位置x = 1, y = 1是红色,位置x = 2, y = 1是红色,所有其他位置是其他颜色。

我们致电floodFillx = 1, y = 1

然后在x = 2, y = 1上调用floodFill,然后在x = 1, y = 1上调用它。

只要确保不要重新访问相同的节点。

1

因为你是标志着tab的地方,你是递归调用方法只空,这意味着它永远不会得到它实际上标志着一个地方作为空阶段。它将匹配其中一个条件,然后再次调用自己,然后它将匹配其中一个条件,然后再次调用它自己。它从来没有达到有任何阻止它的地步。

这将是更好地在当前位置作为参数的方法,从tab传递的c值,这样就可以将其标记为空,你在搜索中继续之前。例如:

public void floodFill(int disX, int disY, int currentColor){ 
    //up 
    if(tab[disX][disY - 1] != null){ 
     if (tab[disX][disY - 1].c == currentColor){ 
      tab[disX][disY - 1] = null; 
      floodFill(disX, disY - 1, currentColor); 
     } 
    } 
    ... 
}