康威生命游戏
Conway的生命游戏是复杂性如何从简单规则中涌现的经典示例。想象一个无限的单元格网格——每个单元格可以是「开」(存活)或「关」(死亡)。每一轮(或「代」),每个单元格都会检查有多少邻居存活。如果过于拥挤,它会死亡。如果过于孤立,它也会死亡。但如果恰好有三个邻居,死亡的单元格就会重获生命。
这套简单的规则带来了无尽迷人的行为——从稳定的结构和重复的振荡器,到穿越网格的自推进「宇宙飞船」。这完美展示了复杂性如何从简单中产生,而且它是图灵完备的,意味着理论上可以模拟任何计算。
正在加载游戏板...
图案示例
这些经典模式展示了游戏的涌现行为。「Glider」展示了网格上的移动,「Pulsar」创造了迷人的振荡,「Small Exploder」展示了简单形状如何演化成复杂形式。
算法
生命游戏的核心是几个优雅的函数,它们决定了我们这个细胞宇宙中的生与死:
// The core algorithm that determines life and death
function computeNextGeneration(currentGrid) {
const newGrid = createEmptyGrid(rows, cols);
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
const neighbors = countNeighbors(currentGrid, r, c);
const cellState = currentGrid[r][c];
// Apply Conway's rules of life
if (cellState === 1) {
// Live cell survives if it has 2 or 3 neighbors
newGrid[r][c] = (neighbors === 2 || neighbors === 3) ? 1 : 0;
} else {
// Dead cell springs to life if it has exactly 3 neighbors
newGrid[r][c] = (neighbors === 3) ? 1 : 0;
}
}
}
return newGrid;
}
核心算法将Conway的规则应用于网格中的每个单元格。每一代,它检查每个单元格的状态和邻居数量,以确定它是存活、死亡还是重获新生。
// Count live neighbors for each cell
function countNeighbors(g, row, col) {
let count = 0;
for (let i = 0; i < 8; i++) {
const nr = row + NEIGHBOR_OFFSETS[i * 2];
const nc = col + NEIGHBOR_OFFSETS[i * 2 + 1];
if (nr >= 0 && nr < rows && nc >= 0 && nc < cols) {
count += g[nr][nc];
}
}
return count;
}