当前位置: 首页 > 知识库问答 >
问题:

算法-康威生命游戏的极端细节

盖辉
2023-03-14

我的问题很难描述,所以我会尽可能简洁地解释。

在康威的《生活游戏》中,假设我有一张这样的地图:

_   _   _   _   _
_   _   _   _   _
U   _   R   Y   _
_   T   _   X   _
_   Z   _   C   _

与其在每个单元格上循环,包括不可能相关的死单元格,不如让我将第0代中的每个活单元格放在链接列表中。在每一代人更新时,我都会遍历整个LinkedList,并执行Conway的生活游戏对每一代人的规则。这样我就避免了无缘无故地迭代大跨度的死单元。

其中一条规则规定,有3个活邻居的死细胞变为活细胞。因为在我的算法中我只迭代活细胞,所以我可以查看死细胞的唯一方法是查看链接列表中活细胞的邻居。对于我的LinkedList中的每一项,我都必须循环遍历该单元格的所有相邻单元格,对于每个相邻单元格,我必须环顾该单元格,计算是否有三个相邻单元格,然后将其设置为alive,然后将其作为活动单元格添加到LinkedList中。

我的问题:

显然,我的LinkedList会很快变得杂乱无章,不会出现在左上方-

按照游戏规则,这合法吗?还是我需要从左上角到右下角遍历整个2D数组?这些规则非常模糊。

任何少于两个活邻居的活细胞都会死亡,就好像是由于人口不足造成的一样。

任何有两个或三个活邻居的活细胞都会延续到下一代。

任何有三个以上活邻居的活细胞都会死亡,就好像是因为人口过多。

任何有三个活邻居的死细胞都会变成活细胞,就像通过繁殖一样。

我需要循环通过整个2D数组,做规则:

任何少于两个活邻居的活细胞都会死亡,就好像是由于人口不足造成的一样。

然后再次循环遍历整个二维数组,并执行以下规则:

任何有两个或三个活邻居的活细胞都会延续到下一代。

这到底有关系吗?我读过很多帖子,似乎从来没有人提到过这个话题。

谢谢。


共有2个答案

干旺
2023-03-14

您应该在每次移动时重新创建链接列表。康威的生命游戏是按轮次进行的,所有活细胞在当前轮次不算作活细胞,所有死细胞在当前轮次不算作死细胞。因此,使用LinkedList方法,您持有两个列表(我说的是哈希表,因为您需要一个快速函数来检查对象是否已经在列表中),一个表示当前的活细胞集,另一个表示收集的下一轮活细胞集。然后,遍历第一组单元格,抓取当前单元格的相邻单元格,将其填充到下一轮的列表中,使“邻居”等于1,然后增加每个处理过的活单元格的值。此外,应将当前活动单元添加到设置了“活动”标志且邻居为0的集合中。伪代码

ArrayCollection.<Cell> existing; // currently alive cells
ArrayCollection.<Cell> next; // next turn
void processTurn() {
    next.clear();
    for each (Cell cell in existing) {
        Cell nextTC=next.getByParameters(cell); // check presence by X and Y
        if (nextTC) nextTC.alive=true; else   
            next.addNewCell(cell.x,cell.y,0,true); // add a new element
            // 0 is current neighbors, true is alive flag
        for each (Cell neigh in cell.neighbors) {
            nextTC=next.getByParameters(neigh);
            if (nextTC) nextTC.neighbors++; else   
                next.addNewCell(cell.x,cell.y,1,false); // add a new element
                // added a dead cell with 1 neighbor - currently processed alive cell
        }
    }
    for each (cell in next) {
        if (!cell.alive && (cell.neighbors==3)) cell.alive=true; else
        if (cell.alive && ((cell.neighbors==2) || (cell.neighbors==3))) ; // no change
        else next.remove(cell); // dead cell that either was alive or failed to become alive
    }
    swap(current,next);
}
冀嘉木
2023-03-14

在康威的人生游戏中,整个矩阵应该只循环一次:所有的变化都是同时进行的。

实际上,这将需要两个矩阵:旧状态和新状态。对于旧状态下的每个单元格,计算实时邻居计数。然后,如果细胞是活的,并且有2或3个邻居,它就会在新的矩阵中继续存在。如果细胞不是活的,并且有3个邻居,它会产卵。否则,它就死了。

链表的问题是查找邻居计数。由于必须搜索整个列表才能计算邻居,因此在活细胞数量上产生下一代将是O(n^2)。此外,您还必须检查链接列表中单元格的每个邻居,因为它们已生成。

 类似资料:
  • 我试图为康威的生活游戏写一个计数邻居方法。如果一个死细胞与2或3个活细胞相邻,它应该会活过来。然而,我的代码没有正确计算所有的邻居。如果我给输入坐标(10, 10), (10, 11), (10, 12)这将产生 该程序将下一代打印为 坐标在(10,11)和(11,11)。但是,在(9,11)也应该有一个点。我知道问题发生在这个函数中,对于点(9,11),函数不包括3个邻居。

  • 我正在制作康威的生活游戏,就像几乎所有其他初学者一样。我的主要问题是我不知道如何执行游戏规则,这些规则是:一个有三个活邻居的死细胞变成活细胞,一个有一个活邻居的活细胞变成死细胞,一个有三个以上活邻居的活细胞变得死了。我以前从未操纵过矩阵,所以我不知道从哪里开始。我所在的类还不允许我们使用非静态方法,而且我们也不能使用java库。这是我目前所拥有的: 我现在收到的输出是我最初一代游戏所需要的。我想我

  • 问题围绕康威的人生游戏,以及如何为新一代同时实施所有规则。这个游戏遵循三条新世代的规则:一个只有三个活邻居的死细胞变为活细胞,一个只有一个活邻居的活细胞变为死细胞,一个有三个以上活邻居的活细胞变为死细胞。原始世代是随机的。我认为,我的问题在于,我的新一代正在一次一个地实施规则,而不是一次全部实施,这是一种方法: 以下是我的完整代码,以防问题不在该方法中: 以下是我的输出: 我期待这样的事情: 在我

  • 我最近已经解决了名为“康威的人生游戏”的有趣的黑客问题问题陈述如下: 《生命的游戏》是一款由英国数学家约翰·霍顿·康威设计的细胞自动机游戏。最初的游戏是零人游戏。它的发展完全取决于它的投入。 生命游戏在2D网格上进行。网格中的每个单元格将处于两种可能状态之一, 活死人细胞的出生或死亡是基于以下规则。 如果一个细胞正好被3个活细胞包围,它就会从死细胞转换为活细胞。如果一个细胞被2或3个活细胞包围,它

  • 在本章中,我们考虑二维细胞自动机,特别是 John Conway 的生命游戏(GoL)。 像上一章中的一些 CA 一样,GoL 遵循简单的规则并产生令人惊讶的复杂行为。 就像沃尔夫勒姆的规则 110 一样,事实证明 GoL 是通用的;也就是说,至少在理论上它可以计算任何可计算的函数。 GoL 的复杂行为引发了科学哲学问题,特别是科学现实主义和工具主义的相关问题。 我讨论这些问题并提出扩展阅读的建议

  • 意义不明的面试,技术面非常非常简单感觉就像KPI面,然后后面是主管面,主管面的比技术时间还长。 技术面约20分钟 问实习,实习的一些实现,以及觉得实习最难的事情是什么怎么解决的,和别人怎么沟通的 c#的数据结构,list,字典等等 gc,为什么会产生gc, gc带给玩家的影响是什么 lua 怎么看待lua这个语言 然后就是长达四十多分钟的主管面,什么都问,学校,家题,为什么做不选择本专业,别人怎么