递归Floodfill溢出

时间:2012-12-29 00:29:42

标签: java flood-fill

public void floodFill(int x, int y) {
    if (x >= 0 && x <= 9 && y >= 0 && y <= 9) {
        if (mines[x][y] == 0) {
            btn[x][y].setBackground(Color.GRAY);
            floodFill(x - 1, y);
            // floodFill(x + 1, y);
            floodFill(x, y - 1);
            // floodFill(x, y + 1);
        } else {
            return;
        }
    }
}

这是我正在使用的FloodFill代码,用于我正在制作的类似扫雷的游戏。但是,你可以看到2个部分被注释掉了。一旦我取消评论并运行程序。

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at sun.awt.NullComponentPeer.setBackground(Unknown Source)
at java.awt.Component.setBackground(Unknown Source)
at javax.swing.JComponent.setBackground(Unknown Source)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:95)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:99)
at Minesweeper.BoardBuild.floodFill(BoardBuild.java:98)

我不确定为什么会发生这种情况,我不确定如何解决这个问题。任何帮助表示赞赏。

修改

Fls'Zen在聊天中提出的答案,以防其他人遇到此问题

public void floodFill(int x, int y) {
    if (x >= 0 && x <= 9 && y >= 0 && y <= 9) {
        if (mines[x][y] == 0 && btn[x][y].getBackground() != Color.GRAY) {
            btn[x][y].setBackground(Color.GRAY);
            floodFill(x - 1, y);
            floodFill(x + 1, y);
            floodFill(x, y - 1);
            floodFill(x, y + 1);
        } else {
            return;
        }
    }
}

2 个答案:

答案 0 :(得分:4)

取消注释这些行后,您可以为x - 1x + 1调用floodFill。考虑当您为x - 1调用floodFill时会发生什么。它还调用了x + 1的floodFill,它是名为floodFill的x值。您有floodFill调用自己的两个x值,原始x值和原始x - 1

如果你打算使用递归,你应该选择一个'方向'(+或 - )并坚持下去。否则,您需要添加一些内容来跟踪已评估的坐标。

修改 当算法已经处理了一个单元格时,以下代码将避免递归。它通过检查当前坐标的背景颜色来实现这一点。如果背景已经是灰色,那么它假定它已经处理了坐标并且不再处理它们。

if (mines[x][y] == 0 && btn[x][y].getBackground() != Color.GRAY) {
    btn[x][y].setBackground(Color.GRAY);
    floodFill(x - 1, y);
    floodFill(x + 1, y);
    floodFill(x, y - 1);
    floodFill(x, y + 1);
} else {
    return;
}

答案 1 :(得分:0)

看起来你没有记录你已经检查过哪个方块,所以它无限循环遍布整个电路板。