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

Conway's Game of Life实现错误排查:代码逻辑问题分析

康威生命游戏代码逻辑问题排查

问题描述

我正在实现康威生命游戏,规则如下:

  • 存活细胞(X):
    1. 存活邻居少于2个 → 死亡(-)
    2. 存活邻居为2或3个 → 存活(X)
    3. 存活邻居超过3个 → 死亡(-)
  • 死亡细胞(-):
    1. 存活邻居恰好3个 → 变为存活(X)

给定初始网格:

-------
-------
------X
---XXXX
------X

预期下一代网格:

-------
-------
----X-X
----X-X
----X-X

但代码生成的输出为:

-------
-------
----X--
----X--
-------

以下是我的代码:

# #mark all places where new life will be born;
# mark all organisms which will die;
# remove all marked organisms;
# fill all marked empty cells with new organisms.
# Input data will contain 5 lines of 7 characters each. They represent a 5 by 7 fragment of the game field.

def convert(initial_state= ('''-------
-------
------X
---XXXX
------X''')): #convert input into a list, so it is easier to operate on

    game_list = []
    row_start = 0 
    row_end = 7

    for _ in range(5):
        row_cells = ''

        for i in range(row_start,row_end):
            row_cells += initial_state[i]
        game_list.append(row_cells)
        row_start += 8
        row_end += 8

    return(game_list)

def mark_cell():
    #if cell has 0-1 or 3+ alive neighbours(X) - dies
    #if 2 neighbours - survives
    #if 3 neighbours - it becomes alive
    
    result = '' #life after day 1 (after one neighbour check for all cells)

    game_list = convert()

    for r in range(len(game_list)):
        result += '''
        '''
        for c in range(len(game_list[r])):
            choosen_cell = game_list[r][c]
        
            try:
                born_count = 0
                neighbours = [game_list[r-1][c-1],game_list[r-1][c],game_list[r-1][c+1],game_list[r][c-1],game_list[r][c+1],game_list[r+1][c-1],game_list[r+1][c],game_list[r+1][c+1]]
                

                if r == 0 and c != 0 and c!= 6:
                    neighbours = neighbours[3:]
                elif r == 4 and c != 0 and c!= 6:
                    neighbours = neighbours[:5]

                elif c == 0 and r != 0 and r != 4:

                    del neighbours[5]
                    del neighbours[3]
                    del neighbours[0]
                    
                elif c == 6  and r != 0 and r != 4:

                    del neighbours[7]
                    del neighbours[4]
                    del neighbours[2]

                elif r == 0 and c == 0:
                    
                    neighbours = neighbours[3:]
                    del neighbours[2]
                    del neighbours[0]

                elif r == 0 and c == 6:
                    
                    neighbours = neighbours[3:]
                    del neighbours[4]
                    del neighbours[1]

                elif r == 4 and c == 0:
                    
                    neighbours = neighbours[:5]
                    del neighbours[3]
                    del neighbours[0]

                elif r == 4 and c == 6:

                    neighbours = neighbours[:5]
                    del neighbours[4]
                    del neighbours[2]

                for num in neighbours:
                    if  num == "X":
                        born_count +=1

            except IndexError:
                pass  

            finally:
                pass

            if born_count < 2 or born_count > 3:
                result += "-"
            elif born_count == 3:
                result += "X"
            else:
                result += choosen_cell
    print (result)
    return result        

mark_cell()

核心逻辑问题分析

1. 边界邻居访问错误,异常处理失效

  • 负索引陷阱:当访问r-1(如r=0时r-1=-1),Python会将负索引解析为列表末尾元素,错误地把网格最后一行当作当前行的上一行邻居,而非判定为非法坐标。
  • 异常处理逻辑错误:当访问超出列范围的索引(如c=6时c+1=7),触发IndexError后直接pass,导致born_count保持为0,完全忽略了其他合法邻居的统计。

2. 手动裁剪邻居列表逻辑疏漏

通过先构建包含非法索引的列表再删除元素的方式极易出错,比如当c=6时,触发异常后删除元素的代码根本不会执行,导致邻居统计完全错误。


修复方案

步骤1:正确统计存活邻居

替换手动构建邻居列表的方式,通过遍历方向偏移量并检查坐标合法性,准确统计存活邻居:

def count_alive_neighbors(grid, row, col):
    rows = len(grid)
    cols = len(grid[0])
    alive_count = 0
    # 遍历8个方向的坐标偏移
    directions = [(-1, -1), (-1, 0), (-1, 1),
                  (0, -1),          (0, 1),
                  (1, -1),  (1, 0), (1, 1)]
    for dr, dc in directions:
        r = row + dr
        c = col + dc
        # 仅统计网格范围内的邻居
        if 0 <= r < rows and 0 <= c < cols:
            if grid[r][c] == 'X':
                alive_count += 1
    return alive_count

步骤2:简化convert函数

用字符串分割替代索引截取,逻辑更清晰:

def convert(initial_state= ('''-------
-------
------X
---XXXX
------X''')):
    return [line.strip() for line in initial_state.split('\n') if line.strip()]

步骤3:修正主逻辑函数

基于正确的邻居统计结果,重新实现状态转换逻辑:

def mark_cell():
    game_list = convert()
    rows = len(game_list)
    cols = len(game_list[0])
    result = []
    
    for r in range(rows):
        new_row = []
        for c in range(cols):
            current_cell = game_list[r][c]
            alive_neighbors = count_alive_neighbors(game_list, r, c)
            
            # 应用生命游戏规则
            if current_cell == 'X':
                if alive_neighbors < 2 or alive_neighbors > 3:
                    new_row.append('-')
                else:
                    new_row.append('X')
            else:
                if alive_neighbors == 3:
                    new_row.append('X')
                else:
                    new_row.append('-')
        result.append(''.join(new_row))
    
    # 输出格式化结果
    print('\n'.join(result))
    return '\n'.join(result)

mark_cell()

修复后输出

运行修正后的代码,将得到预期结果:

-------
-------
----X-X
----X-X
----X-X

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:45:50