生命游戏,由剑桥数学家约翰·康威发明,是一种“细胞自动机”。这个游戏实际上是一种零玩家游戏,意味着它的演变是由初始状态决定的,不需要人类玩家的任何输入。玩家通过创建初始配置并观察其演变来与生命游戏互动。
这个游戏在1970年《科学美国人》杂志的一篇文章中被提及后变得广为人知。它由一组细胞组成,这些细胞根据一些数学规则可以生存、死亡或繁殖。根据初始条件,细胞在游戏过程中形成各种模式。可以观看斯蒂芬·霍金的《生命的意义》中的视频片段来了解这个游戏。
约翰·康威扩展了约翰·冯·诺伊曼的工作,后者创造了一种可以在棋盘上复制自己的机器。诺伊曼的机器运作的规则比康威生命游戏中的规则要复杂得多。
生命游戏在创建后不久就变得非常出名。许多人对细胞运作的非常简单的规则能够从混乱中创造秩序,以及如此复杂的模式能够演变感到着迷。当家用电脑在游戏发布后不久变得流行起来时,许多实现变得可用,游戏成为了流行的屏幕保护程序。
然而,康威的生命游戏不仅看起来令人着迷,而且对数学、物理学、哲学、经济学等许多科学领域都具有理论意义。例如,它是细胞自动机最著名的例子之一,已经成为计算理论中一个受欢迎的研究主题。
生命游戏的宇宙是一个无限的二维正交网格,每个网格都是一个可能处于两种可能状态之一的正方形细胞:活着或死亡。每个细胞与其八个邻居互动,这些邻居是直接水平、垂直或对角相邻的细胞。在每个时间步骤中,会发生以下转换:
-- 扩展规则(不是原始定义的一部分)以展示可插拔的规则引擎
初始模式构成了系统的“种子”。第一代是通过同时将上述规则应用于种子中的每个细胞来创建的——出生和死亡是同时发生的,这个离散的时刻有时被称为一个“滴答”。(换句话说,每一代都是前一代的纯函数。)规则继续被反复应用以创造更多的后代。
下面的输入代表宇宙中的细胞,用X或-表示。X是一个活细胞。-是一个死细胞或没有细胞。下面的输入提供了宇宙中的模式或初始细胞。输出是系统在下一个滴答(一次应用所有规则的运行)的状态,以相同的格式表示。
一个细胞C用1表示活着,用0表示死亡,在m-by-m的方格数组中。计算N - C的八位置邻居中活细胞的总和,然后根据以下表格决定细胞C在下一代是活着还是死亡:
细胞数量 | 新细胞数量 |
1 | 0,1 |
0 | # 孤独 |
1 | 4,5,6,7,8 |
0 | # 过度拥挤 |
1 | 2,3 |
1 | # 生存 |
0 | 3 |
1 | # 需要三个来诞生! |
0 | 0,1,2,4,5,6,7,8 |
0 | # 贫瘠 |
从这里开始,假设边界之外的细胞总是死亡的。
“游戏”实际上是一个零玩家游戏,意味着它的演变是由初始状态决定的,不需要人类玩家的任何输入。玩家通过创建初始配置并观察其演变来与生命游戏互动。
尽管应该在更复杂的例子上测试实现,比如在更大的宇宙中的滑翔机,展示三个世代中的闪烁器(三个相邻的细胞都活着)在3x3网格上的行动,这是一个关于如何在Web上制作游戏的指南。
现在让深入了解代码...
规则引擎是通用的,依赖于ITransition,看起来像这样:
namespace gameOfLife.Framework {
public interface ITransition {
void Apply(ITransitive cellContainer);
}
public interface ITransitive {
void ApplyTransitions(params ITransition[] transitions);
IList Cells { get; set; }
}
}
|
基于此,规则集被实现并链接到执行顺序。这是链中的第一个规则。
using gameOfLife.Framework;
namespace gameOfLife.Transition {
public class Loneliness : ITransition {
public void Apply(ITransitive cellContainer) {
// cellContainer.Cells = cellContainer.Cells.Where((cell) => CanBeAlive(cellContainer.Cells, cell)).ToList();
foreach (var cell in cellContainer.Cells) {
if (!CanBeAlive(cellContainer.Cells, cell)) {
cell.Kill();
}
}
}
private bool CanBeAlive(IList otherCells, Cell cell) {
return cell.NeighbouringLocations.Match(otherCells).Count > 1;
}
}
}
|
作为棋盘的PatternOfCells类:
public class PatternOfCells : ITransitive {
private IList cells = new List();
// threadsafe initialization
private static ITransitive instance = new PatternOfCells();
private PatternOfCells() {
}
public static ITransitive Instance {
get {
// do not need double lock here
return instance;
}
}
public void ApplyTransitions(params ITransition[] transitions) {
foreach (ITransition transition in transitions) {
transition.Apply(this);
}
ClearDeadCells();
}
}
| |
该框架对于尝试使用康威生命游戏实现解决方案的应用程序很有用。
private void InitializeTransitionIndexes() {
...
else {
knownTransitions = new List() {
"Loneliness",
"OverCrowding",
"NextGeneration",
"Spawn",
"Die"
};
// "Die" has to be appended
}
}