【问题标题】:Minesweeper recursion, stackoverflow扫雷递归,stackoverflow
【发布时间】:2017-04-28 04:34:26
【问题描述】:

所以,我一直在为扫雷的 Java 编写一些代码。我正在努力尝试让空单元格以递归方式显示它们旁边的重合单元格。这是执行此操作的函数。

“单元格”是我用于游戏中单元格的按钮。

private void showCells(int x, int y) {

    //checks out of bounds
    if (x >= SIZE || y >= SIZE || x <= 0 || y <= 0) {
        return;
    }

    //function to look at each surrounding cell and see if it is a mine, 
    //has nMines as a global variable to keep track of the number of mines
    findMines(x, y);

    //if there are mines around the cell that was selected
    if (nMines > 0) {

        //set the text of that cell to the number of mines around it
        cell[x][y].setText(String.valueOf(nMines));

        //if cell is not already disabled, disable it
        if (!cell[x][y].isDisabled()) {
            cell[x][y].setDisable(true);
        }
    } else {

        //if there are no mines, recursively show the surrounding mines
        showCells(x + 1, y);
        showCells(x - 1, y);
        showCells(x, y + 1);
        showCells(x, y - 1);
    }

    //resets the mine count for the next search
    nMines = 0;
}

我知道就功能而言,我的代码还有一些其他问题,但我正试图找出这个递归的东西。我调试时发生的事情是,当我到达“x”边界的末尾时,它会返回,但随后会立即跳转到下一个递归调用,它将它带到相同的“x”位置。

showCells(x + 1, y);
showCells(x - 1, y);

我想知道我需要什么样的限定符以及我需要将它放置在哪里以确保它不会在同一个位置搜索两次。提前致谢!

【问题讨论】:

  • 如果您只是显示一个空单元格周围的单元格(只有 4 个),为什么要使用递归?目前,您的代码似乎显示了所有单元格。至于限定符,您可以使用已有的 .isDisabled()。
  • @BennettYeo 我希望它以级联形式发生,这样,如果还有其他空白空间,它也会对这些单元格做同样的事情。
  • 您必须在检查 x 和 y 是否在边界内并返回后立即添加检查单元格是否已禁用,否则您将创建无限循环。
  • @pianoman102 递归只会使这个问题变得不必要地复杂化。递归总是比迭代慢,尤其是在非尾调用优化语言(如 java)中。当我们想让代码更“可读”时,我们会选择递归。我建议只做一个空的for(cell c : cells) 并暴露周围的方块。您可以通过确保不重新显示已显示的方块来决定是否要“提升”性能。
  • 递归可能会慢一些,但对于小的输入并不重要,而且您几乎不需要发现超过 20 个字段...

标签: java recursion minesweeper


【解决方案1】:

您正在创建一个无限循环,因为每个单元格都会重复到每个相邻的单元格,然后每个为空的单元格都会重复回到原始单元格,等等。

您可以通过在第一个 if 语句中添加条件来解决此问题:

if (x >= SIZE || y >= SIZE || x <= 0 || y <= 0 || cell[x][y].isDisabled()) {
    return;
}

由于名为 short-circuiting 的便捷功能,如果 xy 越界,isDisabled() 的检查甚至不会引发错误,因为它永远不会进行评估。

编辑:回答您关于将setDisabled(true) 放在哪里的后续问题-您总是希望在单击单元格后禁用它,对吗?所以把它放在findMines()下面,if语句之前。

【讨论】:

  • 太棒了!如果它也是空的,我想我错过了一个可以将其设置为禁用的位置。是否应该在最后一个 else 语句中满足这个限定符?
猜你喜欢
  • 2016-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多