Python实现棋盘病毒模拟出现逻辑错误,如何进行修复
问题修复说明
- 错误1:二维数组使用浅拷贝,导致新旧网格共享行数据,本轮修改的状态污染同轮邻居统计
Python中list[:]仅实现一层浅拷贝,对于二维列表,修改新列表的子元素会同步修改原列表的对应元素,导致同轮中前面格子的更新被后面的邻居统计错误计入。 - 错误2:
neighbors函数中多余的打印语句会输出大量无关的邻居计数,干扰正常结果展示 - 错误3:
main函数中保存上一轮状态的last_grid也使用了浅拷贝,导致状态对比逻辑错误,误判进入无限循环
修复后的完整代码
grid = [ [0, 1, 0, 1], [1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0] ] def write(grid): """ 以0/1格式打印棋盘 """ for row in grid: for item in row: print(f" {item}", end="") print() def neighbors(grid, i, j): """ 统计指定位置的上下左右四个方向的感染邻居数量 """ num_neighbours = 0 if i > 0: if grid[i - 1][j]: num_neighbours = num_neighbours + 1 if i < len(grid) - 1: if grid[i + 1][j]: num_neighbours = num_neighbours + 1 if j > 0: if grid[i][j - 1]: num_neighbours = num_neighbours + 1 if j < len(grid[i]) - 1: if grid[i][j + 1]: num_neighbours = num_neighbours + 1 return num_neighbours def update(grid): """ 基于上一轮棋盘状态,计算新一轮的棋盘状态,所有更新基于上一轮的原始状态,不会互相干扰 """ # 改为逐行深拷贝,新老棋盘完全独立 new_board = [row[:] for row in grid] for i in range(len(grid)): for j in range(len(grid[i])): num_neighbours = neighbors(grid, i, j) if num_neighbours >= 2: new_board[i][j] = 1 return new_board def check_all_ones(a): """ 检查棋盘是否全部被感染 """ return not any(c != 1 for r in a for c in r) def main(): """ 运行模拟主逻辑 """ global grid print("Initial State of board:") print() write(grid) state_num = 1 while True: # 改为逐行深拷贝,保存上一轮的完整原始状态 last_grid = [row[:] for row in grid] grid = update(grid) state_num = state_num + 1 print() print(f"State {state_num} of board:") print() write(grid) if check_all_ones(grid): print() print("Virus has spread to whole board.") break if grid == last_grid: print() print("Infinite loop entered.") break if __name__ == "__main__": main()
运行验证
修复后第一轮更新结果和预期完全一致:
Initial State of board: 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 State 2 of board: 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
内容的提问来源于stack exchange,提问作者Robin Andrews
相关产品推荐
相关产品推荐

