3D康威生命游戏迭代计算异常排查与正确实现方法
3D版康威生命游戏迭代计算实现指南
现有代码的错误原因
- 遍历范围完全错误
你在next_iteration函数中用len(grid)(当前网格存储的细胞总数)作为x/y/z坐标的遍历上限,属于逻辑混淆。比如你给出的示例grid有8个存活细胞,len(grid)=8,此时遍历的坐标范围是0、2、4、6,不仅远超出实际有效坐标范围,也完全覆盖不到坐标为负的可能新生细胞区域。 - 错误套用2D生命游戏规则
你直接沿用了2D版康威生命游戏的B3/S23规则(死亡细胞邻居数为3则复活,存活细胞邻居数在2-3之间则存活),但你给出的初始2×2×2全存活网格中,每个细胞的存活邻居数为7,远大于3的阈值,第一轮迭代所有细胞就会全部死亡,自然后续所有迭代结果全为False。 - 邻居坐标硬编码冗余,容易出现拼写错误
修复后的实现代码
from itertools import product # 生成所有3D摩尔邻居的相对偏移(步长为2,排除自身) NEIGHBOR_OFFSETS = [pos for pos in product([-2, 0, 2], repeat=3) if pos != (0, 0, 0)] def get_neighbors(grid, x, y, z): count = 0 for dx, dy, dz in NEIGHBOR_OFFSETS: pos = (x + dx, y + dy, z + dz) if pos in grid and grid[pos]: count += 1 return count def is_alive(grid, x, y, z): return grid.get((x, y, z), False) def next_iteration(grid, rule_birth={3}, rule_survive={2,3,4}): # 收集所有需要检查的坐标:存活细胞+存活细胞的所有邻居 check_positions = set() for (x, y, z), alive in grid.items(): if alive: check_positions.add((x, y, z)) for dx, dy, dz in NEIGHBOR_OFFSETS: check_positions.add((x + dx, y + dy, z + dz)) new_grid = {} for (x, y, z) in check_positions: neighbor_count = get_neighbors(grid, x, y, z) current_alive = is_alive(grid, x, y, z) if current_alive: new_grid[(x, y, z)] = neighbor_count in rule_survive else: new_grid[(x, y, z)] = neighbor_count in rule_birth return new_grid # 测试示例 if __name__ == "__main__": grid = {(0, 0, 0): True, (0, 0, 2): True, (2, 0, 0): True, (2, 0, 2): True, (0, 2, 0): True, (0, 2, 2): True, (2, 2, 0): True, (2, 2, 2): True} # 迭代3次 for i in range(3): grid = next_iteration(grid) # 打印存活细胞数量 alive_count = sum(1 for v in grid.values() if v) print(f"第{i+1}次迭代后存活细胞数:{alive_count}")
规则调整说明
3D版康威生命游戏没有统一的标准规则,你可以根据自己的预期效果修改next_iteration函数的rule_birth(复活所需邻居数)和rule_survive(存活所需邻居数)参数:
- 如果你希望初始2×2×2的立方体保持稳定,可以将
rule_survive调整为{2,3,4,5,6,7} - 常用的3D生命游戏规则还有B3/S234、B36/S23等,你可以自行测试选择符合需求的规则。
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

