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



我正在尝试编写一个函数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,那就太好了。

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

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

1 0 0 1 0 0 0 0 1 0 1

然后,如果您想在两端用零填充数组,它看起来像

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来完成这些任务,因为您可以简单地在初学者的 2Dnumpy数组上使用numpy.pad(),但更复杂的操作也会更快,数组更容易索引等。

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

我最近用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活动/死亡的单元格列表。

最新更新