5

现在我已经阅读了其他 stackoverflow Game of Life 的问题,并且在 Google 上搜索了很多。我知道如何为我的 Python 实现 Game Of Life。我想跟踪网格中的活动单元格。问题是我坚持我应该如何编码。
这是我的想法,但除此之外我有点不知所措:


  • 维护一个 ActiveCell 列表,该列表由活动死亡或活动的单元坐标元组组成。
  • 在计算下一代时,只需遍历 ActiveCell 列表,计算单元状态并检查状态是否发生变化。
  • 如果状态发生变化,将所有当前单元格的邻居添加到列表中。
  • 如果不是,则从列表中删除该单元格
  • 现在的问题是: (" . "--> other cell) 如果 A 满足 3) 那么它添加 B,C,D 然后如果 B 也为 3) 返回 true ,这意味着它将再次添加 A,C (重复)
    B C D
    . A .
    . . .


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

4

5 回答 5

1

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

  1. 遍历 currentState,找出哪些是新生的细胞,哪些会死亡。 不要将这些更改添加到您的 currentState中。如果有一个单元格要出生或死亡,请将其添加到 newChanges 列表中。完成此步骤后,currentState 应该与开始时完全相同。
  2. 一旦您完成了步骤 1 中每个单元格的所有计算,然后迭代 newChanges。对于 newChanges 中的每一对,在 currentState 中将其从 dead 更改为 alive,反之亦然。

例子:

  • currentState 有 {0,0} {0,1} {0,2}。(一行三个点)
  • newChanges 计算为 {0,0} {-1,1} {1,1} {0,2} (两端点死亡,中间上下点出生)
  • currentState 收到更改,变为 {-1,1} {0,1} {1 ,1},newChanges 被清除。
于 2013-07-27T13:47:33.140 回答
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)
于 2013-07-27T14:47:01.143 回答
0

我在 Python 中实现 Game of Life 是为了好玩,我所做的就是使用带有坐标元组的 board dict。值是细胞的一种状态。你可以在这里查看代码https://raw.github.com/tdi/pycello/master/pycello.py。我知道这不是很快的实施,并且由于缺乏时间而放弃了该项目。

 board = {}
 board[(x,y)] = value
于 2013-07-29T05:51:32.377 回答
0

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

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

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

如果你想要一个非常大的动态大小的网格,可以使用HashLife 算法,它更快,但更复杂。

于 2013-07-29T05:37:28.563 回答
0

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

于 2013-07-27T13:20:37.790 回答