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

Python实现康威生命游戏:如何检测数组边角/边界单元格?

解决康威生命游戏的边界索引错误问题

嘿,这个索引错误的坑我当初写生命游戏的时候也踩过!问题出在你直接访问x-1、x+1这类坐标时,没有考虑单元格处于数组边界或边角的情况——比如当x=0时,x-1就是-1,这在普通列表里直接就会抛出索引错误,就算是NumPy数组也会默认做环绕(但你明确说不需要环绕),所以咱们得先判断邻居坐标是否在数组的有效范围内。

问题根源

你的代码直接把8个方向的邻居都列出来,但对于边界单元格来说,有些邻居根本不存在(比如左上角的单元格没有左上方、上方、左方的邻居),强行访问这些不存在的索引就会报错。另外你当前返回的updated_array是一维列表,和输入的二维数组结构不匹配,后续迭代也会出问题。

修复方案:先验证邻居坐标的有效性

我们可以先定义所有8个邻居的坐标偏移量,然后逐个检查每个偏移后的坐标是否在数组的行和列范围内,只有有效的坐标才计入邻居数量,同时把输出改成和输入一致的二维结构。

修改后的代码(兼容普通嵌套列表)

import numpy

def new_state(array):
    rows = len(array)
    cols = len(array[0]) if rows > 0 else 0
    # 初始化和输入同尺寸的二维结果数组
    updated_array = [[0 for _ in range(cols)] for _ in range(rows)]
    
    # 定义8个邻居的坐标偏移(上下左右+四个对角线)
    neighbor_offsets = [(-1, -1), (0, -1), (1, -1),
                        (1, 0),          (1, 1),
                        (0, 1), (-1, 1), (-1, 0)]
    
    for x in range(rows):
        for y in range(cols):
            cell = array[x][y]
            neighbours_count = 0
            
            # 遍历每个邻居偏移,检查坐标是否在有效范围内
            for dx, dy in neighbor_offsets:
                nx = x + dx
                ny = y + dy
                # 只有当坐标在数组边界内时,才统计这个邻居
                if 0 <= nx < rows and 0 <= ny < cols:
                    neighbours_count += array[nx][ny]
            
            # 根据生命游戏规则更新单元格状态
            if cell == 1:
                updated_array[x][y] = 1 if neighbours_count in (2, 3) else 0
            else:
                updated_array[x][y] = 1 if neighbours_count == 3 else 0
    
    return updated_array

关键改进点

  • 边界检查:通过0 <= nx < rows和0 <= ny < cols过滤无效坐标,彻底避免索引错误
  • 二维结果结构:保证输出和输入的二维数组结构一致,方便后续迭代使用
  • 简化规则判断:用in (2,3)替代多个elif,让代码逻辑更清晰

如果你想用NumPy优化(更高效)

既然你提到结合NumPy,其实可以用卷积操作快速统计邻居数量,处理大网格时速度会快很多,而且不需要手动写边界检查:

import numpy as np
from scipy.signal import convolve2d

def new_state_numpy(array):
    arr = np.array(array)
    # 定义3x3卷积核,中心为0(不统计自身),周围8个位置为1
    kernel = np.array([[1,1,1],
                       [1,0,1],
                       [1,1,1]])
    # 计算邻居数量,边界外的单元格视为0
    neighbours_count = convolve2d(arr, kernel, mode='same', boundary='fill', fillvalue=0)
    
    # 根据规则生成新状态
    new_arr = np.where(
        (arr == 1) & ((neighbours_count == 2) | (neighbours_count == 3)),
        1,
        np.where((arr == 0) & (neighbours_count == 3), 1, 0)
    )
    return new_arr.tolist()  # 如需转回列表格式可调用此方法

这个版本利用NumPy的向量化操作和卷积功能,省去了嵌套循环的繁琐,边界处理也更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 08:53:12