我正在尝试编写一个函数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
活动/死亡的单元格列表。