Skip to main content
Artificial Life Natural Selection new

Natural Selection

Observe Darwinian evolution in action: a single species adapts to environmental pressures through genetic variation and natural selection

Population
Population 0
Generation 0
Food 0
Diversity 0
Trait Averages
Speed -
Size -
Vision -
Metabolism -
Controls
Simulation
Parameters
Effects
Population Over Time
Trait Dominance Over Time
Speed Size Vision Metabolism

Darwinian Natural Selection

This simulation demonstrates the four pillars of evolution by natural selection, applied to a single species competing for food resources.

The Four Pillars:

  • Variation: Individuals differ in their genetic traits
  • Heredity: Offspring inherit traits from their parent
  • Selection: Individuals better adapted to their environment survive longer and reproduce more
  • Time: Over many generations, advantageous traits accumulate in the population

Genetic Traits (4 genes, each 0-1):

  • Speed: Movement velocity. Faster organisms find food quicker, but burn more energy per frame
  • Size: Body radius. Larger organisms store more energy and eat from wider area, but cost more to maintain
  • Vision: Detection range. Wider vision locates food from further away, but adds a metabolic cost
  • Metabolism: Energy efficiency. Higher metabolism extracts more energy from food, but increases base energy burn

Trade-offs: Each trait has a cost proportional to its value. An organism that is fast, large, with wide vision, and high metabolism will burn energy extremely quickly. Natural selection favors balanced genomes that extract enough food to offset their energy costs.

Visual Encoding: Organism color is derived from their genome (HSL mapping), allowing you to visually track genetic lineages. Similar colors indicate similar genomes. When the population converges, organisms become uniform in color.

Reproduction: Asexual reproduction occurs when an organism’s energy exceeds the reproduction threshold. The offspring inherits the parent’s genes with small random mutations, introducing the variation that drives evolution.

© 2013 - 2026 Cylian 🤖 Claude
Instructions Claude

Prompt utilisé pour régénérer cette page :

Page: Natural Selection - Darwinian Evolution Simulation
Description: "Observe Darwinian evolution in action: a single species adapts to environmental pressures through genetic variation and natural selection"
Category: artificial-life
Icon: dna
Tags: evolution, natural-selection, simulation, genetics
Status: new

Front matter (index.md):
  title: "Natural Selection"
  description: "Observe Darwinian evolution in action: a single species adapts to environmental pressures through genetic variation and natural selection"
  icon: "dna"
  tags: ["evolution", "natural-selection", "simulation", "genetics"]
  status: ["new"]

HTML structure (index.md):
  <section class="container visual size-800 ratio-1-1 canvas-contain">
    <canvas id="natural-selection-canvas"></canvas>
  </section>

Widget files:
- _stats.right.md (weight: 10): Two stat groups:
  ##### Population — div.natural-selection-stats with 4 stat-items:
    Population (swatch.organism), Generation, Food (swatch.food), Diversity
    Stat IDs: stat-population, stat-generation, stat-food, stat-diversity
  ##### Trait Averages — div.natural-selection-stats.traits with 4 stat-items:
    Speed, Size, Vision, Metabolism
    Stat IDs: stat-avg-speed, stat-avg-size, stat-avg-vision, stat-avg-metabolism

- _controls.right.md (weight: 20): Two sections:
  ##### Controls — div.natural-selection-controls > div.natural-selection-actions:
    {{< button id="btn-start" label="Start" class="is-start" >}}
    {{< button id="btn-pause" label="Pause" class="is-pause" >}}
    {{< button id="btn-reset" label="Reset" >}}
  ##### Simulation — div.natural-selection-options:
    Speed slider: opt-speed (0.5-3, step 0.5, value 1), display span#speed-value

- _options.right.md (weight: 30): Two sections:
  ##### Parameters — div.natural-selection-options with 5 sliders:
    Initial Population: opt-population (5-80, step 5, value 30), display span#population-value
    Food Abundance: opt-food (10-100, step 5, value 50) → CONFIG.foodAbundance = value/100, display span#food-value
    Mutation Rate: opt-mutation-rate (5-80, step 5, value 20) → CONFIG.mutationRate = value/100, display span#mutation-rate-value
    Mutation Strength: opt-mutation-strength (5-50, step 5, value 15) → CONFIG.mutationStrength = value/100, display span#mutation-strength-value
    Reproduction Threshold: opt-reproduction (60-200, step 10, value 120), display span#reproduction-value
  ##### Effects — 3 checkboxes:
    opt-traits (checked): Show Traits
    opt-energy: Show Energy
    opt-vision: Show Vision

- _graph.right.md (weight: 40): ##### Population Over Time — div.natural-selection-graph > <canvas id="population-graph">

- _traits-graph.right.md (weight: 50): ##### Trait Dominance Over Time — div.natural-selection-graph > <canvas id="traits-graph">
  Legend: div.natural-selection-legend.inline with 4 legend-items:
    Speed (swatch.speed), Size (swatch.size), Vision (swatch.vision), Metabolism (swatch.metabolism)

- _algorithm.after.md: Explains Darwinian natural selection: 4 pillars (variation/heredity/selection/time), 4 genetic traits with trade-offs, visual encoding via HSL color, asexual reproduction with mutation.

Architecture (single file default.js):
- IIFE, no imports (uses console.log)
- No external dependencies

SCSS file (default.scss):
- CSS custom properties: --natural-selection-color-organism (#3498db), --natural-selection-color-food (#27ae60), --natural-selection-color-speed (#e74c3c), --natural-selection-color-size (#3498db), --natural-selection-color-vision (#f39c12), --natural-selection-color-metabolism (#9b59b6)
- $breakpoint-mobile: 768px
- layout-main: flex column centered, #natural-selection-canvas 100% with border
- .natural-selection-controls: .natural-selection-actions flex row, .is-start/.is-pause toggled by .is-running
- .natural-selection-stats: flex column, .stat-item with .label+.swatch and .value; .traits variant with smaller font
- .natural-selection-graph: #population-graph and #traits-graph both 120px height (100px mobile), border, background
- .natural-selection-options: flex column, .option-item with label+range, .checkbox variant for horizontal layout
- .natural-selection-legend: flex column (or .inline row), .legend-item with colored .swatch circles per trait
- Responsive: smaller padding/gaps/fonts on mobile

CONFIG defaults:
  initialPopulation: 30, foodAbundance: 0.50, maxFood: 120, foodEnergy: 25,
  reproductionThreshold: 120, reproductionCost: 50,
  mutationRate: 0.20, mutationStrength: 0.15, speed: 1.0,
  showTraits: true, showEnergy: false, showVision: false

Food class:
- Stationary green circle at random position
- size: 3 + random()*2, energy: CONFIG.foodEnergy (25)
- Drawn using cachedColors.food

Organism class:
- Constructor: x, y, genes (null → 4 random 0-1), gen (0)
- Genome: 4 genes [speed, size, vision, metabolism], each 0-1
- Derived traits:
  - speed = 1 + genes[0]*3 (range 1-4)
  - size = 4 + genes[1]*8 (range 4-12 px)
  - visionRange = 30 + genes[2]*120 (range 30-150 px)
  - metabolismEfficiency = 0.5 + genes[3]*0.5 (range 0.5-1.0)
- Energy starts at reproductionThreshold * 0.8
- Movement vector: vx, vy initialized to random (-1 to 1)
- HSL color derived from genome:
  - Hue = (genes[0] + genes[3])/2 * 360
  - Saturation = 40 + genes[1]*50 (40-90%)
  - Lightness = 35 + genes[2]*30 (35-65%)
- Methods:
  - computeColor(): HSL string from genome for visual lineage tracking
  - senseFood(): finds nearest food within visionRange
  - moveTowards(targetX, targetY): steer toward target at this.speed
  - wander(): random acceleration with speed limiting
  - update(width, height): sense → move/wander → apply movement → wrap edges → apply energy cost
  - tryEat(): eat food on contact (this.size + item.size), gain item.energy * metabolismEfficiency
  - canReproduce(): energy > CONFIG.reproductionThreshold
  - isDead(): energy <= 0
  - reproduce(): subtract reproductionCost, create child with mutated genes, update generation counter
  - drawEnergyBar(ctx): colored bar above entity (red→green based on energy/threshold)
  - draw(ctx): draw circle (trait color or default), optional vision range circle, optional energy bar

Energy cost formula per frame:
  baseCost(0.05) + genes[0]*0.08 + genes[1]*0.06 + genes[2]*0.04 + genes[3]*0.03

Reproduction:
- Asexual: when energy > threshold
- Child gets mutated genes: each gene has mutationRate chance of mutation
- Mutation: gene + (random()-0.5) * mutationStrength * 2, clamped to 0-1
- Child spawned at parent position ±10px

Genetic diversity calculation:
- Average standard deviation across 4 genes
- Normalized to 0-1 range (multiplied by 4)

Population history:
- HISTORY_LENGTH = 300 samples max
- Recorded every 5 frames
- populationHistory[] stores organism count
- traitHistory {speed, size, vision, metabolism} stores average gene values per sample

Simulation loop:
- Fixed timestep accumulator pattern (16.67ms base step)
- CONFIG.speed multiplier applied to delta time
- Food spawning: probability CONFIG.foodAbundance * 0.3 per step, max CONFIG.maxFood (120)
- Organism update → tryEat → reproduce → filter dead
- Extinction protection: respawn 5 random organisms if population hits 0

Rendering:
- HD canvas: 800px × devicePixelRatio, ctx.setTransform for scaling
- Main canvas: surface background, green food dots, colored organism circles
- Optional vision range circles (faint stroke, alpha 0.1)
- Optional energy bars above organisms (red→green gradient)
- Population graph: separate canvas sized to parent, line chart with axes (alpha 0.3)
- Trait dominance graph: separate canvas, 4 colored lines (speed=red, size=blue, vision=yellow, metabolism=purple), Y axis fixed 0-1

Controls:
- Start/Pause buttons toggle isRunning, toggle .is-running CSS class
- Reset: stop, clear organisms/food/history, regenerate initial populations, redraw
- Sliders update CONFIG values; display span updated via updateValueDisplay()
- Checkboxes toggle CONFIG.showTraits/showEnergy/showVision; redraw when paused

Color caching:
- cachedColors object with surface, food, organism, grid, traitSpeed, traitSize, traitVision, traitMetabolism
- cacheColors() reads from CSS custom properties
- Refreshed on prefers-color-scheme change

Canvas setup:
- Main canvas: fixed 800x800 pixels (square)
- Graph canvases: sized to parent bounding rect
- All use devicePixelRatio with setTransform for HD rendering

DOM element lookups:
- All use getElementById with optional chaining (?.)
- Graph canvases are optional (null-checked before drawing)

Auto-init on DOM ready (DOMContentLoaded or immediate if already loaded).

Page entièrement générée et maintenue par IA, sans intervention humaine.