生命游戏,如果我小时候能做出这玩意,我能自己玩一整天,看着各种复杂混沌的演化过程,最终归于寂静。

介绍

生命游戏(Game of Life)是由数学家 John Conway 在 1970 年创造的一种细胞自动机。 它是一种零玩家游戏,意味着其演化是由初始状态决定的,无需玩家干预。

游戏设定在一个二维的网格世界中,每个格子代表一个存活(标记为1)或死亡(标记为0)的细胞。 基于一组简单的规则,所有细胞会在每个时刻进行同步更新,从一个状态转变到另一个状态,象征着时间推进中生命的演化。 这些规则根据细胞周围的存活细胞数量来确定:(一个细胞受到周围八个细胞的影响)

  • 对于活细胞:
    • 如果周围有两个或三个活细胞,则它在下一个时刻仍然存活
    • 如果周围的活细胞数量少于两个,它在下一个时刻会死亡(孤立)
    • 如果周围的活细胞数量超过三个,它在下一个时刻也会死亡(拥挤)
  • 对于死细胞:
    • 如果周围有三个活细胞,它在下一个时刻会成为活细胞(繁殖)

生命游戏的演化是由给定或随机生成的初始状态开始,并按照这些简单规则不断迭代。即使这些规则非常简单,但它们可以产生出极其复杂和不可预测的行为,包括静态、振荡和移动等各种形态。

Python实现

下面可以使用Python的动态图来实现生命游戏,这里直接使用matplotlib的绘图和动画功能实现,并且为了直观显示演化过程,使用三种颜色进行区分:

  • 死亡细胞为白色
  • 刚生成的新细胞为蓝色
  • 持续存活的细胞为绿色
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation


# 随机生成初始数据
def random_initial_state(width, height):
return np.random.choice([0, 1], size=(width, height))


# 存活规则判定
def life_rule(cur, total):
if cur == 1 or cur == 2: # 持续存活或新产生的细胞
if (total < 2) or (total > 3):
return 0 # 细胞死亡
else:
return 1 # 继续存活
else: # 死亡的细胞
if total == 3:
return 2 # 重新产生新细胞
else:
return 0 # 继续保持死亡


# 计算周围邻居状态
def count_neighbors(grid, i, j, width, height):
count = 0
for x in [-1, 0, 1]:
for y in [-1, 0, 1]:
if x == 0 and y == 0:
continue
count += int(grid[(i + x) % width, (j + y) % height] > 0)
return count


# 图像更新函数
def update(frameNum, img, grid, width, height, ax):
newGrid = grid.copy()
alive_cells = 0
for i in range(width):
for j in range(height):
total = count_neighbors(grid, i, j, width, height)
newGrid[i, j] = life_rule(grid[i, j], total)
alive_cells += newGrid[i, j] > 0

img.set_data(newGrid)
ax.set_title("Time Step: {} - Alive Cells: {}".format(frameNum, alive_cells))
grid[:] = newGrid[:]
return (img,)


def main():
width, height = 30, 30
grid = random_initial_state(width, height)

cmap = plt.cm.colors.ListedColormap(["white", "green", "blue"])
bounds = [0, 1, 2, 3]
norm = plt.cm.colors.BoundaryNorm(bounds, cmap.N)

fig, ax = plt.subplots()
img = ax.imshow(grid, interpolation="nearest", cmap=cmap, norm=norm)
ani = animation.FuncAnimation(
fig,
update,
fargs=(img, grid, width, height, ax),
frames=100,
interval=100,
repeat=False,
)
plt.show()
ani.save("life_game.gif", writer="pillow")


if __name__ == "__main__":
main()

运行结果例如

经典结构

在生命游戏中有很多经典的结构,例如有很多静态的结构不会随着时间变化,除非受到外部的干扰,譬如最简单的\(2\times 2\)的正方形就是稳定的结构。 还有一个经典的整体平移的动态结构:滑翔机(glider),如下图所示,在一个循环周期后会整体平移,示意图如下

很多振荡结构也是稳定的,例如:蟾蜍(toad)

包含这两种结构的动图如下