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

在Kotlin中实现扫雷洪水填充算法的代码完善求助

扫雷洪水填充算法优化方案

问题背景

我正在复刻扫雷游戏,需要完善洪水填充逻辑的explore函数。游戏规则如下:

  1. 初始雷区为9x9的空白单元格(用.表示):
│123456789│
—│—————————│
1│.........│
2│.........│
3│.........│
4│.........│
5│.........│
6│.........│
7│.........│
8│.........│
9│.........│
—│—————————│
  1. 玩家探索单元格时的三种情况:
    • 踩到地雷则游戏失败(此部分已实现)
    • 单元格为空但周围有地雷,仅显示该单元格的地雷数量
    • 单元格为空且周围无地雷,标记为/并自动递归探索所有相邻单元格,直到遇到有地雷的单元格为止

已实现checkIfMinesAround函数检测单元格周围地雷数量,现有explore代码存在问题,需要修正。

原代码问题

import java.util.Queue
import java.util.LinkedList

fun explore(row: Int, column: Int) {
    val length1 = minefield.size
    val length2 = minefield[0].size
    if (displayedMinefield[row][column] == "/") return
    
    val queue: Queue<Int> = LinkedList<Int>()
    queue.add(listOf(row, column))
    while (!queue.isEmpty()) {
        val (i, j) = queue.first
        queue.removeFirst()
        if (i < 0 || i >= length1 || j < 0 || j >= length2) {
            continue
        } else {
            if (checkIfMinesAround(i, j)) {
                displayedMinefield[i][j] = minefield[i][j]
            } else {
                displayedMinefield[i][j] = "/"
            }
            queue.add(listOf(i + 1, j))
            queue.add(listOf(i - 1, j))
            queue.add(listOf(i, j + 1))
            queue.add(listOf(i, j - 1))
        }
    }
}

原代码存在的问题:

  1. 队列类型声明错误:Queue<Int>无法存储行列坐标对,应该用Queue<List<Int>>
  2. 无重复处理判断:同一单元格会被多次入队,导致无效循环
  3. 逻辑不符合规则:有地雷的单元格仍会继续探索相邻单元格,违反规则B
  4. 坐标检查时机晚:已经入队的无效坐标才会被过滤,浪费资源

修正后的代码

import java.util.Queue
import java.util.LinkedList

fun explore(row: Int, column: Int) {
    val totalRows = minefield.size
    if (totalRows == 0) return
    val totalCols = minefield[0].size

    // 检查是否踩雷(假设地雷在minefield中用"*"标记)
    if (minefield[row][column] == "*") {
        // 调用已实现的游戏失败逻辑
        return
    }

    // 已显示的单元格直接返回
    if (displayedMinefield[row][column] != ".") {
        return
    }

    val queue: Queue<List<Int>> = LinkedList()
    queue.add(listOf(row, column))
    // 先标记为已处理,避免重复入队
    displayedMinefield[row][column] = "/"

    while (queue.isNotEmpty()) {
        val (currentRow, currentCol) = queue.poll()

        val hasSurroundingMines = checkIfMinesAround(currentRow, currentCol)
        if (hasSurroundingMines) {
            // 显示周围地雷数量
            displayedMinefield[currentRow][currentCol] = minefield[currentRow][currentCol]
            continue // 有地雷的单元格,不再探索相邻
        }

        // 定义四个相邻方向(如需八方向可添加斜向坐标)
        val adjacentDirections = listOf(
            listOf(1, 0), listOf(-1, 0),
            listOf(0, 1), listOf(0, -1)
        )

        for ((rowOffset, colOffset) in adjacentDirections) {
            val newRow = currentRow + rowOffset
            val newCol = currentCol + colOffset
            // 检查坐标合法且未被处理
            if (newRow in 0 until totalRows && newCol in 0 until totalCols 
                && displayedMinefield[newRow][newCol] == ".") {
                displayedMinefield[newRow][newCol] = "/"
                queue.add(listOf(newRow, newCol))
            }
        }
    }
}

修改说明

  • 修正队列类型:将队列改为存储List<Int>类型的坐标对,解决类型不匹配问题
  • 提前过滤无效操作:函数开头检查踩雷、已显示的单元格,直接返回避免无效执行
  • 避免重复入队:入队前先标记单元格为已处理,防止同一单元格被多次加入队列
  • 符合游戏规则:周围有地雷的单元格,仅显示数量并终止后续探索,符合规则B
  • 优化坐标检查:入队前先验证坐标合法性,减少无效循环
  • 代码更简洁:用方向列表统一管理相邻单元格,便于后续扩展(比如八方向探索)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:15:33