我在泡泡射击游戏中工作。当我用相同颜色的射击泡泡击中气泡时我必须删除气泡,我尝试用洪水填充算法搜索我应该删除哪个气泡。当射手泡泡碰到另一个泡泡时,我有一个错误:
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;
}
}
}
气泡左右自上而下。
你知道我做错了吗?
答案 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
。
请确保不要重新访问相同的节点。