Forest Fire
Description
This model simulates a dense forest catching fire.
Live Model
Full-page example
Source Code
import { Model, Timer } from "https://vimtaai.github.io/agent/lib/index.js";
import { Random } from "https://vimtaai.github.io/agent/lib/utils.js";
const EMPTY_FIELD_CHANCE = 0.2;
const model = new Model({ width: 100, height: 100, scale: 5 });
const timer = new Timer(step, 20);
function updateFieldColor(field) {
if (field.burnedDown) {
field.color = `rgb(20, 0, 0)`;
} else if (field.fire > 0) {
field.color = `rgb(${field.fire * 255}, 0, 0)`;
} else {
field.color = `rgb(0, ${field.vegetation * 255}, 0)`;
}
}
function setup() {
for (const field of model.fields) {
const isEmpty = Random.getRandomBoolean(EMPTY_FIELD_CHANCE);
field.burnedDown = false;
field.vegetation = isEmpty ? 0 : Random.getRandomFloat(0, 1);
field.fire = 0;
updateFieldColor(field);
}
const fieldOnFire = model.fieldAt(0, model.height / 2);
fieldOnFire.fire = 1;
updateFieldColor(fieldOnFire);
}
function step() {
const fieldsOnFire = model.fields.filter((field) => field.fire > 0);
for (const fieldOnFire of fieldsOnFire) {
const neighborsNotOnFire = fieldOnFire.neighbors.filter(
(neighbor) => neighbor.fire === 0
);
for (const neighbor of neighborsNotOnFire) {
const chanceToCatchFire = fieldOnFire.fire * neighbor.vegetation;
if (Random.getRandomBoolean(chanceToCatchFire)) {
neighbor.fire = neighbor.vegetation;
updateFieldColor(neighbor);
}
}
fieldOnFire.fire = Math.max(fieldOnFire.fire - 0.1, 0);
fieldOnFire.vegetation = Math.max(fieldOnFire.vegetation - 0.1, 0);
if (fieldOnFire.fire === 0) {
fieldOnFire.burnedDown = true;
}
updateFieldColor(fieldOnFire);
}
}
document.getElementById("setup").addEventListener("click", () => setup());
document.getElementById("start").addEventListener("click", () => timer.start());
document.getElementById("stop").addEventListener("click", () => timer.stop());