xxxxxxxxxx
132
const REPLACEMENT_RATE = 2.1;
const STABILITY_OFFSET = 0.1;
const INITIAL_POPULATION_RANGE = [200, 500];
const BIRTH_RATE_RANGE = [1.5, 5];
const DEATH_RATE_RANGE = [0.5, 3];
const MAX_POPULATION = 3000;
const MIN_POPULATION = 2;
const GRID_SIZE = 4;
const GRID_WIDTH = 800;
const TEXT_SIZE = 24;
const GROWING_FILL = [100, 150, 200];
const MAX_POPULATION_FILL = [50, 250, 50];
const EXTINCT_FILL = [255, 0, 0];
const POPULATION_FILL = [255];
const regions = [];
let mode = 1; // 0 = growth, 1 = random, 2 = stability
class Region {
constructor(x, y, population, fertilityRate, deathRate) {
this.x = x;
this.y = y;
this.population = population;
this.fertilityRate = fertilityRate;
this.deathRate = deathRate;
}
grow() {
const growthFactor =
this.population > 2 ? this.fertilityRate - this.deathRate : 0;
this.population += growthFactor;
this.population = constrain(
this.population,
MIN_POPULATION,
MAX_POPULATION
);
}
display() {
if (this.population <= MIN_POPULATION) {
fill(EXTINCT_FILL);
textSize(TEXT_SIZE);
text("extinct", this.x - 50, this.y - 10);
} else {
if (this.population === MAX_POPULATION) fill(MAX_POPULATION_FILL);
else fill(GROWING_FILL);
ellipse(this.x, this.y, this.population / 10);
fill(POPULATION_FILL);
textSize(TEXT_SIZE / 2);
text(int(this.population), this.x - 10, this.y);
}
}
randomizeRates() {
this.fertilityRate = random(BIRTH_RATE_RANGE);
this.deathRate = random(DEATH_RATE_RANGE);
}
stabilize() {
this.fertilityRate = lerp(
this.fertilityRate,
REPLACEMENT_RATE + random(-STABILITY_OFFSET, STABILITY_OFFSET),
0.05
); // Gradual shift towards replacement rate
this.deathRate = lerp(
this.deathRate,
REPLACEMENT_RATE + random(-STABILITY_OFFSET, STABILITY_OFFSET),
0.05
); // Shift death rate to balance fertility
}
}
function setup() {
createCanvas(GRID_WIDTH, GRID_WIDTH, SVG);
let spacing = GRID_WIDTH / GRID_SIZE;
for (let i = 0; i < GRID_SIZE; i++) {
for (let j = 0; j < GRID_SIZE; j++) {
let x = spacing * i + spacing / 2;
let y = spacing * j + spacing / 2;
let population = random(INITIAL_POPULATION_RANGE);
let fertilityRate = random(BIRTH_RATE_RANGE);
let deathRate = random(DEATH_RATE_RANGE);
regions.push(new Region(x, y, population, fertilityRate, deathRate));
}
}
}
function draw() {
background(255);
if (mode === 0) growthMode();
if (mode === 1) randomMode();
if (mode === 2) stabilityMode();
}
function keyPressed() {
if (key === "1") mode = 0;
if (key === "2") mode = 1;
if (key === "3") mode = 2;
// save svg
if (key === "s") save();
}
function growthMode() {
for (let region of regions) {
region.grow();
region.display();
}
}
function randomMode() {
for (let region of regions) {
region.randomizeRates();
region.grow();
region.display();
}
}
function stabilityMode() {
for (let region of regions) {
region.stabilize();
region.grow();
region.display();
}
}