我无法弄清楚扫雷的递归算法

时间:2017-06-14 21:26:35

标签: java recursion minesweeper

我无法弄清楚在扫雷中显示空单元格的算法。 revealCells应该占用一个单元格,然后检查周围的单元格并显示它们,直到它找到一个我的单元格,但由于某种原因,我一直得到一个arrayindexoutofbounds异常。单元格是板中的2D单元阵列。我知道我没有检查每一个条件,我只需要测试它是否有效,然后再添加其余条件。

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

1 个答案:

答案 0 :(得分:1)

这并不奇怪:你做了一个递归调用,如:

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

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

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

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

    Cell cell = cells[row][column]; // 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(row-1,column-1);
        revealCells(row-1,column);
        revealCells(row-1,column+1);
        revealCells(row,column-1);
        revealCells(row,column+1);
        revealCells(row+1,column-1);
        revealCells(row+1,column);
        revealCells(row+1,column+1);
    }
}