Python扫雷项目求助:修复网格索引错误并实现函数式改造
扫雷问题解决方案
问题分析
你的代码出现索引错误的核心原因是直接访问边界单元格的邻接位置(比如第一行的上方、最后一列的右侧),这些位置超出了网格的索引范围;另外还有两个隐藏问题:
- 计数器
counter没有在每个单元格处理前重置,导致计数累加错误 - 内层循环用行数作为列数范围,若网格不是正方形会出错
分步修复与函数式实现
步骤1:编写安全的邻接炸弹计数函数
先提取一个纯函数,专门计算指定位置周围的炸弹数量,从根源解决索引越界问题:
def count_adjacent_mines(grid, row, col): count = 0 # 遍历当前单元格的8个邻接方向 for dr in (-1, 0, 1): for dc in (-1, 0, 1): # 跳过单元格自身 if dr == 0 and dc == 0: continue # 计算邻接位置的索引 adj_row = row + dr adj_col = col + dc # 检查索引是否在网格合法范围内 if 0 <= adj_row < len(grid) and 0 <= adj_col < len(grid[adj_row]): if grid[adj_row][adj_col] == '#': count += 1 return count
这个函数通过索引合法性判断,只访问网格内的有效位置;同时用方向偏移量循环替代重复的条件判断,简化代码结构。
步骤2:函数式生成结果网格
利用列表推导式实现无副作用的函数式处理(不修改原网格,直接生成新结果):
mines = [ ['-', '-', '-', '#', '#'], ['-', '#', '-', '-', '-'], ['-', '-', '#', '-', '-'], ['-', '#', '#', '-', '-'], ['-', '-', '-', '-', '-'] ] def generate_minesweeper_grid(grid): return [ [ '#' if cell == '#' else str(count_adjacent_mines(grid, r, c)) for c, cell in enumerate(row) ] for r, row in enumerate(grid) ] # 生成并打印最终结果 result = generate_minesweeper_grid(mines) for row in result: print(row)
步骤3:验证输出结果
运行代码后,正确输出应该是:
['1', '1', '2', '#', '#'] ['1', '#', '3', '3', '2'] ['2', '4', '#', '2', '0'] ['1', '#', '#', '2', '0'] ['1', '2', '2', '1', '0']
关键优化说明
- 索引安全:通过边界判断确保不会访问网格外的无效位置
- 函数式风格:使用纯函数和列表推导式,避免修改原输入数据,符合函数式编程无副作用的核心原则
- 代码简洁:用方向偏移量循环替代8个重复的条件判断,减少冗余代码
内容的提问来源于stack exchange,提问作者Vaashen Dhanpat
相关产品推荐
相关产品推荐

