BubbleShooter游戏中的Flood-Fill算法

时间:2015-06-05 14:00:01

标签: java algorithm stack-overflow

我在泡泡射击游戏中工作。当我用相同颜色的射击泡泡击中气泡时我必须删除气泡,我尝试用洪水填充算法搜索我应该删除哪个气泡。当射手泡泡碰到另一个泡泡时,我有一个错误:

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

我实施的Flood-Fill算法:

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;
        }
    }
}

气泡左右自上而下。

你知道我做错了吗?

3 个答案:

答案 0 :(得分:1)

因为您在tab中将地点标记为仅之后递归地调用该方法,这意味着它永远不会到达它实际上标记一个地方的阶段空值。它将匹配其中一个条件,然后再次调用自身,然后它将匹配其中一个条件,并再次调用自身。它永远不会有任何阻止它的东西。

最好将当前位置c的{​​{1}}值作为参数传递给方法,以便在之前将其标记为null 你继续搜索。 E.g:

tab

答案 1 :(得分: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是一个布尔数组,可让您跟踪已访问过的单元格(init为false)。

希望它有所帮助:)

答案 2 :(得分:0)

由于你的floodFill的实现方式,你一遍又一遍地重新访问以前的位置,直到你得到一个Stack Overflow(因为你的递归深度太高)。

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

我们在floodFill上致电x = 1, y = 1

然后调用floodFill上的x = 2, y = 1,然后x = 1, y = 1将其调用Table Column is_part_of_pk ----- ------ ------------- ADDRESS ID 1 ADDRESS ADDR_LINE_1 0 ADDRESS ADDR_CITY 0 STUDENT FIRST_NAME 1 STUDENT LAST_NAME 1 STUDENT CLASS_NAME 0

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