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

模拟康威生命游戏:状态更新函数失效无输出,求调试

康威生命游戏状态更新函数修复

我在模拟康威生命游戏时,前两个生成初始状态的函数能正常运行,但最后一个更新状态的one_generation_later函数完全没有输出,没法按照游戏规则更新数组。要求不能修改前两个生成数组的函数,只修复第三个函数。

原代码如下:

import numpy as np
import random

# helper function no. 1
def seed_probabilities(i,j):
    rand_num = random.random()
    x = 1/(abs(i - j) + 2)
    if rand_num < x:
        y = 1
    else:
        y = 0
    return y

def create_world(nr, nc):
    # make array
    values = np.empty((nr,nc), dtype=int)
    # index array
    for i in range(0,nr):
        for j in range(0, nc):
            y = seed_probabilities(i,j)
            values[i,j]=y
    return values
        
values = create_world(6,7)

def one_generation_later(w):
    (nc, nr) = np.shape(w)
    for i in range(0,nr):
        for j in range(0, nc):
            L = [w[i,j-1], w[i,j+1], w[i-1,j], w[i-1,j-1], w[i-1,j+1], w[i+1,j], w[i+1, j-1], w[i+1,j+1]]
            neighborhood = []
            for k in L:
                if L[k]==1:
                    neighborhood.append(L[k])
                    num_alive = len(neighborhood)
                    if w[i,j] == 1 and num_alive > 3:
                        w[i,j] = 0
                    elif w[i,j] == 1 and num_alive <2:
                        w[i,j] = 0
                    elif w[i,j] == 1 and 2 < num_alive < 3:
                        w[i,j] = 1
                    elif w[i,j] == 0 and num_alive == 3:
                        w[i,j] = 1
    return w

one_generation_later(values)

我原本打算把初始数组传入第三个函数,遍历每个单元格获取邻域列表,通过列表长度判断细胞生死,但完全没成功。


问题分析与修复

原函数存在几个关键错误:

  • 数组形状顺序颠倒:np.shape(w)返回的是(行数, 列数),原代码写成(nc, nr),导致循环范围错误,遍历逻辑完全混乱。
  • 边界索引越界未处理:比如i=0时i-1=-1,numpy会取数组最后一行,不符合生命游戏“边界外细胞全死”的规则,需要手动处理边界情况。
  • 邻居统计逻辑错误:遍历邻域列表时用元素值当索引(L[k]==1)完全错误,应该直接统计列表中1的数量;且不能边统计边修改原数组,必须基于当前代的完整状态计算下一代,否则后续单元格会使用已修改的状态,导致结果错误。
  • 直接修改原数组:遍历过程中修改原数组会干扰后续计算,必须创建原数组的副本,在副本上更新状态。

修复后的one_generation_later函数:

def one_generation_later(w):
    nr, nc = np.shape(w)
    # 创建原数组的副本,避免修改原数据影响计算
    new_w = w.copy()
    
    for i in range(nr):
        for j in range(nc):
            num_alive = 0
            # 遍历8个方向的邻居
            for di in [-1, 0, 1]:
                for dj in [-1, 0, 1]:
                    # 跳过当前单元格本身
                    if di == 0 and dj == 0:
                        continue
                    ni, nj = i + di, j + dj
                    # 检查邻居是否在数组范围内,不在则视为死细胞(0)
                    if 0 <= ni < nr and 0 <= nj < nc:
                        num_alive += w[ni, nj]
            
            # 根据生命游戏规则更新状态
            if w[i,j] == 1:
                if num_alive < 2 or num_alive > 3:
                    new_w[i,j] = 0
                # 存活数为2或3时保持存活,无需修改
            else:
                if num_alive == 3:
                    new_w[i,j] = 1
    return new_w

修复点说明

  1. 修正数组形状的顺序,确保循环能遍历所有单元格。
  2. 用双重循环遍历8个方向邻居,手动处理边界:超出数组范围的邻居视为死细胞,不计入存活数。
  3. 先完整统计当前单元格的存活邻居数量,再根据规则更新副本数组,保证所有计算都基于当前代的初始状态。
  4. 使用原数组的副本存储下一代状态,避免修改原数组导致的计算错误。

现在调用one_generation_later(values)就能得到正确的下一代状态,比如可以打印结果查看:

print(one_generation_later(values))

内容的提问来源于stack exchange,提问作者Etaoin Shrdlu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:33:14