Prompt utilisé pour régénérer cette page :
Page: Cellular Automata
Description: "Simple rules, emergent complexity"
Category: computer-science
Icon: grid
Tags: cellular-automata, simulation, game-of-life, emergence
Status: new
Front matter (index.md):
title: "Cellular Automata"
description: "Simple rules, emergent complexity"
icon: "grid"
tags: ["cellular-automata", "simulation", "game-of-life", "emergence"]
status: ["new"]
HTML structure (index.md):
<section class="container visual size-800 ratio-1-1 canvas-contain">
<canvas id="automata-canvas"></canvas>
</section>
Widget files:
- _controls.right.md (weight: 10):
##### Controls — div.automata-controls with 5 buttons:
{{< button id="btn-start" label="Start" class="is-start" >}}
{{< button id="btn-pause" label="Pause" class="is-pause" >}}
{{< button id="btn-step" label="Step" >}}
{{< button id="btn-reset" label="Reset" >}}
{{< button id="btn-clear" label="Clear" >}}
- _presets.right.md (weight: 20):
##### Preset Rules — div.automata-presets:
<select id="preset-select"> with 4 options:
Game of Life B3/S23 (life, selected), HighLife B36/S23 (highlife),
Day & Night B3678/S34678 (daynight), Seeds B2/S (seeds)
- _patterns.right.md (weight: 25):
##### Patterns — div.automata-patterns:
<select id="pattern-select"> with optgroups:
Still Life: Block (e5f6g7h8), Beehive (f6g7h8i9), Loaf (g7h8i9j0)
Oscillators: Blinker (b2c3d4e5), Toad (c3d4e5f6), Beacon (d4e5f6g7), Pulsar (i9j0k1l2)
Spaceships: Glider (a1b2c3d4), LWSS (h8i9j0k1)
Methuselahs: R-pentomino (j0k1l2m3), Acorn (k1l2m3n4)
Guns: Gosper Glider Gun (l2m3n4o5)
First option: value="" label "-- Select --"
Values are pattern IDs matching JSON filenames in _api/automata/ directory.
- _options.right.md (weight: 30):
##### Options — div.automata-options:
Grid Size: <select id="grid-size"> with 50/100(selected)/150/200 options
Speed: label with <span id="speed-value">10</span> gen/s + range slider id="speed-slider" (1-60, value 10)
- _stats.right.md (weight: 40):
##### Statistics — <dl> with 4 dt/dd pairs:
Generation (stat-generation), Population (stat-population), Born (stat-born), Died (stat-died)
- _algorithm.after.md (no weight specified): Explains cellular automata basics: Moore neighborhood (8 neighbors), Birth/Survival rules (B/S notation), 4 classic presets with descriptions.
Data files:
- _api/automata/*.json: 12 pattern JSON files (a1b2c3d4.json through l2m3n4o5.json)
Format: { "name": "Pattern Name", "cells": [[0,1,0,...], ...] }
2D array of 0/1 values representing the pattern shape.
Architecture (single file default.js):
- IIFE, no imports (uses console.log)
- No external dependencies
SCSS file (default.scss):
- $breakpoint-mobile: 768px
- #automata-canvas: 100% width/height, cursor crosshair, background surface
- .automata-controls: flex row wrap, .button flex:1 min-width 60px, .is-start/.is-pause toggled by .is-running; mobile .button 45%
- .automata-presets: select full width, themed colors, bordered, rounded
- .automata-options: flex column, label 0.875rem weight 300, select full width with focus styling, range with custom thumb (webkit+moz 16px thumb), #speed-value weight 600 primary color
- dl: grid 2-col (1fr auto), dt 0.875rem weight 300, dd weight 600 tabular-nums right-aligned
Preset rules (PRESETS object, using Set for birth/survival):
life: birth=[3], survival=[2,3]
highlife: birth=[3,6], survival=[2,3]
daynight: birth=[3,6,7,8], survival=[3,4,6,7,8]
seeds: birth=[2], survival=[] (empty — no survival)
State:
canvas, ctx, dpr (devicePixelRatio)
gridSize=100 (configurable via dropdown: 50/100/150/200)
grid: Uint8Array(gridSize*gridSize), nextGrid: Uint8Array — double-buffered
rules: current PRESETS entry (default: life)
generation, population, born, died counters
isRunning, animationId, speed=10, lastUpdate
isDrawing, drawValue (1 or 0) — mouse drawing state
patternData: loaded pattern JSON (or null)
cachedColors: { background, cell, grid }
Grid operations:
createGrid(size): returns new Uint8Array(size*size)
getCell(g, x, y): toroidal wrap-around — wx = (x+gridSize)%gridSize, returns g[wy*gridSize+wx]
setCell(g, x, y, value): bounds-checked set
countNeighbors(g, x, y): Moore neighborhood (8 directions), uses getCell for wrapping
randomize(density=0.3): fills grid with random cells, counts population
clearGrid(): fills both grids with 0, resets born/died/population
Pattern loading:
loadPattern(patternId): async, fetches _api/automata/{id}.json
On success: clears grid, resets generation, places pattern centered, updates display
placePattern(startX, startY): reads patternData.cells 2D array, centers on click position, wraps around grid edges, updates population incrementally
Simulation step:
step(): for each cell, count neighbors and apply current rules (birth Set/survival Set)
Tracks newBorn/newDied per step
Swaps grid/nextGrid buffers
Updates generation, born, died, population
Mouse drawing:
mouseToGrid(e): converts clientX/Y to grid cell coordinates via getBoundingClientRect
handleMouseDown(e): start drawing, toggle clicked cell, set drawValue (0 or 1) based on current state
handleMouseMove(e): continue drawing with drawValue if isDrawing
handleMouseUp(): stop drawing
Touch events: touchstart/touchmove/touchend with preventDefault, mapped to mouse handlers
Rendering (draw):
Canvas: 800px fixed size × dpr, ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
Cell dimensions: width/gridSize, height/gridSize
Clear with cachedColors.background
Grid lines: drawn only if cellWidth > 3px (too small = no grid), cachedColors.grid at 0.5 lineWidth
Live cells: cachedColors.cell, drawn as filled rects with 0.5px inset on each side
Animation loop:
run(timestamp) via requestAnimationFrame
Speed-based interval: 1000/speed ms between steps
Elapsed time tracking with remainder carried: lastUpdate = timestamp - (elapsed % interval)
Controls:
btn-start/btn-pause: toggle isRunning, toggle .is-running on .automata-controls
btn-step: advance one step manually (only when paused)
btn-reset: stop → randomize(0.3) → reset generation/born/died → draw
btn-clear: stop → clearGrid → reset generation → draw
preset-select: change rules = PRESETS[value]
grid-size: change gridSize, recreate both grids, reset generation, randomize, redraw
pattern-select: stop → loadPattern(value) (async fetch)
speed-slider: update speed, update speed-value display span
Color caching:
cachedColors: background (--background-color-surface), cell (--draw-color-primary), grid (--draw-color-surface)
cacheColors() reads from CSS computed styles with fallbacks
Refreshed on prefers-color-scheme change
Canvas setup:
Fixed 800×800 pixels (square)
HD rendering via devicePixelRatio with ctx.setTransform
Auto-init on DOM ready (DOMContentLoaded or immediate if already loaded).
Initial state: random at 30% density, not running.
Page entièrement générée et maintenue par IA, sans intervention humaine.