← ブログ

コンウェイのライフゲーム

Conwayのライフゲームは、シンプルなルールから複雑さが生まれる典型的な例です。無限に広がるセルのグリッドを思い浮かべてください。各セルは「オン」(生存)または「オフ」(死亡)の状態を取ります。各ターン(「世代」)ごとに、すべてのセルが近傍セルの生存数をチェックします。セルが密集しすぎていると死亡し、孤立しすぎていても死亡します。しかし、ちょうど3つの近傍セルがあれば、死亡セルは生存状態に変化します。

このシンプルなルールセットは、無限に魅力的な挙動を生み出します。安定した構造や繰り返す振動子から、グリッドを横切る自己推進型の「宇宙船」まで様々です。これは、シンプルさから複雑さが生まれることの完璧な実証であり、チューリング完全でもあります。つまり、理論上はあらゆる計算をシミュレートできるのです。

仕組み

ゲームボードを読み込み中...

パターン例

これらの古典的なパターンは、ゲームの創発的な挙動を示しています。「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;
}
ウルフラムのルール110を見る →
仕組み

任意の領域を選択してセルのクラスターを作成するか、選択してドラッグして生きた経路を描きます。再生を押して作成物の進化を見るか、ステップ進むで1世代ずつ進めます。ランダム化でカオスを、クリアで最初からやり直します。

ルール

各世代で各セルは4つの単純なルールに従います:

  • 過疎: 2つ未満の隣人を持つ生きたセルは死にます
  • 生存: 2つまたは3つの隣人を持つ生きたセルは生き残ります
  • 過密: 3つを超える隣人を持つ生きたセルは死にます
  • 繁殖: ちょうど3つの隣人を持つ死んだセルは生き返ります
コントロール
  • 再生/一時停止: シミュレーションを開始または停止
  • ステップ進む: 一度に1世代進める
  • 速度: 世代が過ぎる速さを調整
  • ズーム: グリッドサイズを変更(一時停止中のみ)
パターン例

プリセットパターンを試して様々な動作を見てみましょう:

  • グライダー: グリッド上を斜めに移動するパターン
  • パルサー: 3世代の周期で振動する大きなパターン
  • 小型爆発器: 外側に無秩序に拡大するパターン