康威的生命游戏:如何初始化网格?

时间:2017-08-05 01:34:42

标签: python conways-game-of-life

我试图编写一个函数nextGen,它接受​​一个参数(当前网格),然后计算但不打印新网格。基本上,我不知道如何检查位,它检查周围的9个单元格。首先,我认为我可以创建一个完全由0开始制作的基本网格,它比当前网格大2行2列,这样它就可以是0的边界,但我可以'弄清楚如何将初始网格值输入基础网格。我目前的代码是:

def initlist(positions,initval):
    newlist = []
    for i in range(0,positions):
        newlist.append(initval)
    return newlist

def init2DTableV3(rows,cols,initval):
    newrow = initlist(cols,initval)
    table = initlist(rows,newrow)
    return table

def nextGen(current_grid):
    rows = len(current_grid)
    cols = len(current_grid[0])
    base_value = 0
    base_grid = init2DTableV3(rows + 2, cols + 2, base_value)
    import copy
    init_newgrid = copy.deepcopy(current_grid)

有人可以帮帮我吗?我是Python的初学者,所以如果有人能够解释如何使用基本的Python函数来创建nextGen那么棒。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,你有基本网格而你不确定如何在边缘用零填充它,对吗?

有时首先考虑1D中的问题会更容易,然后看看是否可以将其扩展到2D。假设您的1D网格看起来像

1 0 0 1 0 0 0 0 1 0 1

然后,如果你想 pad 数组的每一端都是零,那么它看起来就像

0 1 0 0 1 0 0 0 0 1 0 1 0

假设您只使用标准Python列表,这很容易做到。您可以在开头插入list.insert(),在结尾插入.insert().append()

>>> L = [1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1]
>>> L.insert(0,0)
>>> L.append(0)
>>> L
[0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0]

所以让我们用2D列表尝试相同的事情来看看会发生什么:

>>> M = [[1,1],[1,1]]
>>> M.insert(0,[0,0])
>>> M.append([0,0])
>>> M
[[0, 0], [1, 1], [1, 1], [0, 0]]

因此,这会在顶部和底部用零提供一行,但我们没有左侧和右侧。我们将在一秒钟内解决这个问题。当我添加顶行和底行时,我明确地给它了所需的零数(即[0,0])。但是你可以使用一行的长度自动轻松完成:

>>> M = [[1,1],[1,1]]
>>> M.insert(0,[0]*len(M[0]))
>>> M.append([0]*len(M[0]))
>>> M
[[0, 0], [1, 1], [1, 1], [0, 0]]

现在,每个行向量只有长度为2,但它应该是4.一个简单明了的方法就是循环遍历子列表并插入并附加0:

>>> for r in M:
...     r.insert(0,0)
...     r.append(0)
... 
>>> M
[[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]

这将为您提供填充的2D列表。

一般情况下,我建议您使用numpy执行这些任务,因为您可以在2D numpy数组上使用numpy.pad()作为初学者,但更复杂的操作也会更快并且数组更容易索引等。

答案 1 :(得分:0)

另一种方法是使用已经存在的东西而不是添加额外的元素。

我最近在javascript中写了 Life 的副本,但想法是一样的。每个单元格由其坐标标识,并用其邻居的对象(Python:字典)初始化。坐标。

makeCell(x, y) {
    let div = $('<div></div>');
    let id = "x" + x + "y" + y;

    let neighbors = this.getNeighbors(x, y);

    let attributes = {
                "id": id,
                "data-entity": _entity.id
        }

    $("#grid").append(div);
}

function getNeighbors(x, y) {
    let leftX =     x - 1;
    let rightX =    x + 1;
    let topY =      y - 1;
    let bottomY =   y + 1;

    // neighbor positions
    let neighbors = [
        "#x" + leftX + "y" + topY,
        "#x" + x + "y" + topY,
        "#x" + rightX + "y" + topY,
        "#x" + leftX + "y" + y,
        "#x" + rightX + "y" + y,
        "#x" + leftX + "y" + bottomY,
        "#x" + x + "y" + bottomY,
        "#x" + rightX + "y" + bottomY,
    ];
    return neighbors;
}

在回合结束时,所有活细胞都存储在列表中。检查每个活细胞及其每个邻居以计数其各自的相邻细胞。

this.cellCountNeighbors = function() {
    let count = 0;
    let neighbors = this.neighbors;
    let n = this.entity;
    let u = this;

    neighbors.forEach(function(neighbor) {
        let div = $(neighbor);
        if ($(div).hasClass("alive")) {
            count++;
        } else if (!check_cells.includes(neighbor)) {
            check_cells.push(neighbor);
        }
    });

    return count;
}

和生命的检查条件:

this.setNextLife = function(_count) {
    if (this.alive) {

        if (_count == 2 || _count == 3) {
            return this.age++;
        } else {
            changes.push(this);
            return;
        }

    } else {
        changes.push(this);
    }
}

其中changes是要切换的单元格列表bool alive / dead。