java - 我无法弄清楚扫雷递归算法

标签 java recursion minesweeper

我无法弄清楚扫雷中显示空单元格的算法。 RevealCells 应该获取一个单元格,然后检查周围的单元格并显示它们,直到找到一个我的单元格,但由于某种原因,我不断收到 arrayindexoutofbounds 异常。单元是板上单元的二维阵列。我知道我不会检查每个条件,我只需要在添加其余条件之前测试它是否有效。

public void revealCells(Cell cell){
    row = cell.getRow();
    column = cell.getCol();

    if (row < 0 || row > cells.length - 1|| column < 0 || column > cells.length - 1) return;

    else if(cell instanceof MineCell) return;       

    else if(cell.getMineCount() == 0 && !(cell.isRevealed())){
        cell.reveal();
        revealCells(cells[row+1][column]);
        revealCells(cells[row][column+1]);
        revealCells(cells[row-1][column]);
        revealCells(cells[row][column-1]);
        revealCells(cells[row+1][column+1]);
        revealCells(cells[row-1][column-1]);
    }
    else{
        return;
    }
}

最佳答案

这并不奇怪:您执行如下递归调用:

revealCells(cells[row+1][column]);

这意味着 Java 将首先获取cells[row+1][column]。现在您没有进行任何边界检查。该方法中的绑定(bind)检查可能相当无用,因为那时您已经获得了单元格,因此您知道它是一个有效的坐标。

在我看来,您最好重新设计系统以使用坐标而不是单元格,然后在边界检查后获取单元格:

public void revealCells(<b>int row, int column</b>) {
    if (row < 0 || row <b>>=</b> cells.length|| column < 0 || column <b>>=</b> cells<b>[0]</b>.length)
        return;

    <b>Cell cell = cells[row][column];</b> // now we are safe, so fetch the cell
    if(cell instanceof MineCell)
        return;   

    else if(cell.getMineCount() == 0 && !(cell.isRevealed())){
        cell.reveal();
        // call recursive with coordinates, not cells
        revealCells(<b>row-1,column-1</b>);
        revealCells(<b>row-1,column</b>);
        revealCells(<b>row-1,column+1</b>);
        revealCells(<b>row,column-1</b>);
        revealCells(<b>row,column+1</b>);
        revealCells(<b>row+1,column-1</b>);
        revealCells(<b>row+1,column</b>);
        revealCells(<b>row+1,column+1</b>);
    }
}

关于java - 我无法弄清楚扫雷递归算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44554985/

相关文章:

c++ - 获取进程的基址

java - 渲染脚本生成方法 : cannot find symbol method getPointSize()

java - 输入输出流

java - Spring 安全: get password in UserDetailsServiceMethod

vim - 是否可以使用 Vim 的普通命令来记录和运行递归宏?

javascript - 如何折叠多维数组

java - 创建扫雷,更改难度时如何重置棋盘。

java - 如何在正则表达式中使用加号字符

python - 如何修改此代码以删除全局变量? (解包嵌套的 json 递归生成器)

c++ - 检查二维数组中的相邻索引