生命游戏:如何跟踪活跃细胞

时间:2013-07-27 12:50:24

标签: python

现在我已经阅读了其他stackoverflow Game of Life问题,并且还贪婪地使用Google搜索。我知道如何为我的生命游戏的Python实现做些什么。我想跟踪网格中的活动单元格。问题是我坚持不知道应该如何编码呢 这就是我的想法,但除此之外,我的机智已经结束了:

  • 维护一个ActiveCell列表,该列表由活动的单元坐标元组组成 死了还是活着。
  • 计算下一代时,只需迭代ActiveCell列表,计算单元格 陈述并检查状态是否发生变化。
  • 如果状态发生变化,请将所有当前单元格邻居添加到列表
  • 如果没有,请从列表中删除该单元格
  • 现在问题是:(“。” - >其他单元格)
           B C D
    . A .
    . . .

    如果A满足3)则加上B,C,D
    那么如果B也为3)返回true,这意味着它将再次添加A,C (复制)

我考虑使用OrderedSet或其他东西来处理订单并避免重复。但是我仍然遇到了这些问题。我只需要一个方向。

5 个答案:

答案 0 :(得分:1)

你有两个列表,我将它们命名为currentState和newChanges。这将是工作流程:

  1. 迭代currentState,找出哪些是新生的细胞,以及哪些细胞将会死亡。 请勿将这些更改添加到currentState 。如果有一个单元要出生或死亡,请将其添加到newChanges列表中。完成此步骤后,currentState看起来应该与开头时完全相同。
  2. 完成每个单元格的步骤1中的所有计算后,再遍历newChanges。对于newChanges中的每一对,将currentState中的它从dead变为alive,反之亦然。
  3. 示例:

    • currentState有{0,0} {0,1} {0,2}。 (一行三个点)
    • newChanges被计算为{0,0} {-1,1} {1,1} {0,2}(两个端点死亡,中间上方和下方的点出生)
    • currentState接收更改,并变为{-1,1} {0,1} {1,1},并清除newChanges。

答案 1 :(得分:1)

不知道它是否会对你有所帮助,但这里有一个生命游戏的快速草图,带有activecells字典:

from itertools import product

def show(board):
    for row in board:
        print " ".join(row)

def init(N):
    board = []
    for x in range(N):
        board.append([])
        for y in range(N):
            board[x].append(".");
    return board

def create_plane(board):
    board[2][0] = "x"
    board[2][1] = "x"
    board[2][2] = "x"
    board[1][2] = "x"
    board[0][1] = "x"

def neighbors(i, j, N):
    g1 = {x for x in product([1, 0, -1], repeat=2) if x != (0, 0)}
    g2 = {(i + di, j + dj) for di, dj in g1}
    return [(x, y) for x, y in g2 if x >= 0 and x < N and y >= 0 and y < N]

def live(board):
    N = len(board)
    acells = {}
    for i in range(N):
        for j in range(N):
            if board[i][j] == "x":
                for (x, y) in neighbors(i, j, N):
                    if (x, y) not in acells: acells[(x, y)] = board[x][y]

    while True:
        print "-" * 2 * N, len(acells), "cells to check"
        show(board)
        raw_input("Press any key...")
        for c in acells.keys():
            a = len([x for x in neighbors(c[0], c[1], N) if board[x[0]][x[1]] == "x"])
            cur = board[c[0]][c[1]]
            if a == 0:
                del acells[c]                       # if no live cells around, remove from active
            elif cur == "x" and a not in (2, 3):
                acells[c] = "."                     # if alive and not 2 or 3 neighbors - dead
            elif cur == "." and a == 3:
                acells[c] = "x"                     # if dead and 3 neighbors - alive
                for x in neighbors(c[0], c[1], N):  # add all neighbors of new born
                    if x not in acells: acells[x] = board[x[0]][x[1]] 

        for c in acells:
            board[c[0]][c[1]] = acells[c]

N = 7
board = init(N)
create_plane(board)

live(board)

答案 2 :(得分:0)

您是否考虑使用有序字典并将值设置为无?

答案 3 :(得分:0)

您没有说明您有以特定方式实施游戏的限制。因此,主要问题是:您希望能够处理多大的网格?

例如,如果您从一个小的固定大小的网格开始,最简单的表示只是[[bool]]或[[int]],包含每个单元格是活着还是死亡。因此,每轮,您可以从旧的网格中创建一个新的网格,例如假设网格外的所有单元都已死亡。示例:

[
  [False, True, False],
  [True, False, True],
  [False, True, False],
]

如果你想要一个非常大的动态大小的网格,那就是HashLife algorithm,它更快,但更复杂。

答案 4 :(得分:0)

我在Python中实现了Game of Life以获得乐趣,我所做的是使用坐标元组的棋盘。价值是一种细胞状态。您可以在此处查看代码https://raw.github.com/tdi/pycello/master/pycello.py。我知道这不是很快的实施,并且由于时间不够而放弃了该项目。

 board = {}
 board[(x,y)] = value