Gra w życie Conwaya
Gra w życie Conwaya to klasyczny przykład tego, jak złożoność może wyłonić się z zaledwie kilku prostych reguł. Wyobraź sobie nieskończoną siatkę komórek — każda może być „włączona" (żywa) lub „wyłączona" (martwa). W każdej turze (lub „generacji") każda komórka sprawdza, ilu sąsiadów jest żywych. Jeśli jest zbyt zatłoczona, umiera. Jeśli jest zbyt samotna, również umiera. Ale przy dokładnie trzech sąsiadach martwa komórka ożywa.
Ten prosty zestaw reguł prowadzi do nieskończenie fascynujących zachowań — od stabilnych formacji i powtarzających się oscylatorów, po samopropagujące się „statki kosmiczne" przemierzające siatkę. To doskonała demonstracja tego, jak złożoność może wyłonić się z prostoty, a gra jest nawet Turing-zupełna, co oznacza, że teoretycznie może symulować dowolne obliczenia.
Przykłady wzorców
Te klasyczne wzorce pokazują emergentne zachowanie Gry. „Glider" demonstruje ruch po siatce, „Pulsar" tworzy hipnotyzującą oscylację, a „Small Exploder" pokazuje, jak proste kształty mogą ewoluować w złożone formy.
Algorytm
U podstaw Gry w życie leży zaledwie kilka eleganckich funkcji, które decydują o życiu i śmierci w naszym komórkowym wszechświecie:
// 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;
}
// 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;
}