You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java扫雷递归实现0区域展开未完成全部迭代的原因

Java扫雷0单元格递归展开仅覆盖左上区域问题修复

问题根因

你的代码无法完整遍历0值连通域、仅覆盖左上区域,是三个明显的逻辑缺陷导致的:

  • 无递归终止防重逻辑:方法入口没有判断当前坐标是否已经被标记为已点击,递归过程中遍历到当前单元格自身时会反复重入checkZero方法,触发无限递归,最终栈溢出导致程序提前终止,for循环中靠右、靠下的遍历逻辑根本没有机会执行,自然只能覆盖最先递归到的左上区域。
  • 展开逻辑覆盖不全:你将遍历周边单元格的逻辑完全放在countSurroundingMines(mines, x, y) == 0的判断块内,导致0值周边雷数为1-8的数字单元格不会被标记为已点击,不符合扫雷的常规交互(点击0值时相邻的数字格需要直接展开,仅不需要继续递归)。
  • 大括号错配风险:从你贴出的代码缩进来看,第一层if判断的开括号没有正确包裹后续的边界计算、for循环代码,会导致left/right/up/down变量作用域异常,直接触发编译错误,如果是本地编写时漏写大括号/缩进错误,也会导致逻辑执行顺序不符合预期。

修正后代码

不需要单独计算上下左右边界,把越界判断、已点击判断放在方法入口做终止条件即可,代码更简洁也不容易出边界问题:

private void checkZero(int x, int y) {
    // 递归终止:坐标越界、当前格子已点击,直接返回
    if (x < 0 || x >= 18 || y < 0 || y >= 14 || clicked[x][y]) {
        return;
    }
    // 标记当前格子为已点击状态
    clicked[x][y] = true;
    // 当前格子是数字格(周边雷数1-8),不需要继续递归展开
    if (countSurroundingMines(mines, x, y) != 0) {
        return;
    }
    // 当前是0值格,递归遍历周边8个相邻格子
    for (int i = x - 1; i <= x + 1; i++) {
        for (int j = y - 1; j <= y + 1; j++) {
            checkZero(i, j);
        }
    }
}

逻辑说明

  • 越界判断统一放在方法入口,不需要单独为边缘格子计算左右上下的遍历边界,递归到数组范围外的坐标时直接返回,减少边界判断的冗余代码。
  • 所有进入方法的未点击格子都会先被标记为已点击,保证0值周边的数字格可以正常展开。
  • 仅当当前格子是0值时才会继续递归遍历相邻格,数字格直接终止递归,避免无意义的重复遍历,也不会出现无限递归的问题。

内容的提问来源于stack exchange,提问作者Eli Robinson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:18:56