ConwaysGameOfLife [康威生命游戏]
# 介绍
康威生命游戏(英语:Conway's Game of Life),又称康威生命棋,是英国数学家约翰・何顿・康威在 1970 年发明的细胞自动机。
细胞自动机
细胞自动机(英语:Cellular automaton),又称格状自动机、元胞自动机,是一种离散模型,在可计算性理论、数学及理论生物学都有相关研究。它是由无限个有规律、坚硬的方格组成,每格均处于一种有限状态。整个格网可以是任何有限维的。同时也是离散的。每格于 t 时的态由 t-1 时的一集有限格(这集叫那格的邻域)的态决定。每一格的 “邻居” 都是已被固定的。(一格可以是自己的邻居。)每次演进时,每格均遵从同一规矩一齐演进。参考:细胞自动机 - Wikiwand (opens new window)
就形式而言,细胞自动机有三个特征:
- 平行计算(parallel computation):每一个细胞个体都同时同步的改变
- 局部的(local):细胞的状态变化只受周遭细胞的影响。
- 一致性的(homogeneous):所有细胞均受同样的规则所支配
生命游戏中,对于任意细胞,规则如下:
- 每个细胞有两种状态 - 存活或死亡,每个细胞与以自身为中心的周围八格细胞产生互动(如图,黑色为存活,白色为死亡)
- 当前细胞为存活状态时,当周围的存活细胞低于 2 个时(不包含 2 个),该细胞变成死亡状态。(模拟生命数量稀少)
- 当前细胞为存活状态时,当周围有 2 个或 3 个存活细胞时,该细胞保持原样。
- 当前细胞为存活状态时,当周围有超过 3 个存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
- 当前细胞为死亡状态时,当周围有 3 个存活细胞时,该细胞变成存活状态。(模拟繁殖)
可以把最初的细胞结构定义为种子,当所有在种子中的细胞同时被以上规则处理后,可以得到第一代细胞图。按规则继续处理当前的细胞图,可以得到下一代的细胞图,周而复始。
# 概述
生命游戏是一个零玩家游戏。它包括一个二维矩形世界,这个世界中的每个方格居住着一个活着的或死了的细胞。一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死了的细胞的数量。如果相邻方格活着的细胞数量过多,这个细胞会因为资源匮乏而在下一个时刻死去;相反,如果周围活细胞过少,这个细胞会因太孤单而死去。实际中,玩家可以设定周围活细胞的数目怎样时才适宜该细胞的生存。如果这个数目设定过高,世界中的大部分细胞会因为找不到太多的活的邻居而死去,直到整个世界都没有生命;如果这个数目设定过低,世界中又会被生命充满而没有什么变化。
实际中,这个数目一般选取 2 或者 3;这样整个生命世界才不至于太过荒凉或拥挤,而是一种动态的平衡。这样的话,游戏的规则就是:当一个方格周围有 2 或 3 个活细胞时,方格中的活细胞在下一个时刻继续存活;即使这个时刻方格中没有活细胞,在下一个时刻也会 “诞生” 活细胞。
在这个游戏中,还可以设定一些更加复杂的规则,例如当前方格的状况不仅由父一代决定,而且还考虑祖父一代的情况。玩家还可以作为这个世界的 “上帝”,随意设定某个方格细胞的死活,以观察对世界的影响。
# 实现
/*
Conway's Game of Life
The Game of Life is a cellular automaton devised by the British mathematician John Horton Conway in 1970. The universe of the Game of Life is an infinite, two-dimensional orthogonal grid of square cells,
each of which is in one of two possible states, live or dead, (or populated and unpopulated, respectively).
Every cell interacts with its eight neighbours, which are the cells that are horizontally, vertically, or diagonally adjacent.
At each step in time, the following transitions occur:
1. Any live cell with two or three live neighbours survives.
2. Any dead cell with three live neighbours becomes a live cell.
3. All other live cells die in the next generation. Similarly, all other dead cells stay dead.
(description adapted from https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life )
(example adapted from https://github.com/TheAlgorithms/Python/blob/master/cellular_automata/conways_game_of_life.py )
*/
/*** Generates the next generation for a given state of Conway's Game of Life. */
function newGeneration(cells) {
const nextGeneration = [];
for (let i = 0; i < cells.length; i++) {
const nextGenerationRow = [];
for (let j = 0; j < cells[i].length; j++) {
// Get the number of living neighbors
let neighborCount = 0;
if (i > 0 && j > 0) neighborCount += cells[i - 1][j - 1];
if (i > 0) neighborCount += cells[i - 1][j];
if (i > 0 && j < cells[i].length - 1) neighborCount += cells[i - 1][j + 1];
if (j > 0) neighborCount += cells[i][j - 1];
if (j < cells[i].length - 1) neighborCount += cells[i][j + 1];
if (i < cells.length - 1 && j > 0) neighborCount += cells[i + 1][j - 1];
if (i < cells.length - 1) neighborCount += cells[i + 1][j];
if (i < cells.length - 1 && j < cells[i].length - 1) neighborCount += cells[i + 1][j + 1];
// Decide whether the cell is alive or dead
const alive = cells[i][j] === 1;
if ((alive && neighborCount >= 2 && neighborCount <= 3) || (!alive && neighborCount === 3)) nextGenerationRow.push(1);
else nextGenerationRow.push(0);
}
nextGeneration.push(nextGenerationRow);
}
return nextGeneration;
}
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