
本文介绍如何在 go 中简洁、安全地遍历二维数组,为每个非地雷格子统计其八邻域内地雷(值为 -1)的数量,避免越界访问,并生成标准扫雷数字提示图。
本文介绍如何在 go 中简洁、安全地遍历二维数组,为每个非地雷格子统计其八邻域内地雷(值为 -1)的数量,避免越界访问,并生成标准扫雷数字提示图。
在实现控制台版扫雷游戏时,一个核心逻辑是:对每个非地雷格子(即 ary[i][j] != -1),统计其周围 8 个相邻位置(上、下、左、右及四个对角线方向)中地雷(-1)的总数,并将该计数写入该格子。若直接对每个方向单独判断边界(如 i-1 >= 0 && j-1 >= 0 && ary[i-1][j-1] == -1),代码将冗长、重复且易出错。
更优雅、可维护的方案是以地雷为中心反向扩散更新:遍历整个数组,一旦发现地雷(ary[i][j] == -1),就遍历其所有合法邻域坐标 (k, l),并对其中所有非地雷格子执行 ++ 操作。关键在于:通过 max(0, i-1) 和 min(row-1, i+1) 等边界约束,动态限定邻域扫描范围,彻底规避数组越界 panic。
以下是完整、健壮的实现代码(需提前定义 max 和 min 辅助函数):
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
// 假设 ary 是 [][]int 类型,row = len(ary), col = len(ary[0])
for i := 0; i < row; i++ {
for j := 0; j < col; j++ {
if ary[i][j] == -1 { // 发现地雷
// 遍历以 (i,j) 为中心的 3×3 邻域(含自身)
for k := max(0, i-1); k <= min(row-1, i+1); k++ {
for l := max(0, j-1); l <= min(col-1, j+1); l++ {
// 跳过地雷自身,仅更新空白格子
if ary[k][l] != -1 {
ary[k][l]++
}
}
}
}
}
}✅ 优势说明:
- 逻辑清晰:地雷是“源”,主动向邻居广播影响,符合直觉;
- 边界安全:max/min 确保 k 和 l 始终在 [0, row-1] 和 [0, col-1] 内,无需嵌套 if 判断;
- 无冗余分支:相比 8 个独立 if,嵌套双循环结构紧凑、易于验证;
- 时间复杂度最优:O(m×n×9) = O(mn),与问题规模线性相关。
⚠️ 注意事项:
- 此算法修改原数组。若需保留原始地雷布局,建议先深拷贝或使用独立的 count 数组存储结果;
- 地雷格子值保持 -1 不变,其他格子初始应为 0(确保累加正确);
- 若数组为空(row == 0 || col == 0),需前置校验,避免 min(row-1, ...) 计算错误。
最终,输入示例数组将准确输出所期望的提示矩阵:
[0 1 1 1 0] [0 1 -1 1 0] [0 1 2 2 1] [0 0 1 -1 -1] [0 0 1 -1 -1]
该方法兼具工程实用性与算法简洁性,是 Go 中处理二维邻域统计任务的经典范式。










