xxxxxxxxxx
146
let grid;
let cols;
let rows;
let resolution = 5;
function make2DArray(cols, rows) {
let arr = new Array(cols);
for (let i = 0; i < arr.length; i++) {
arr[i] = new Array(rows);
}
return arr;
}
function Cell(initState) {
let pos = initState.pos;
let currentState = {
isAlive: initState.isAlive,
lifetime: 1,
isInfected:
pos.x * resolution < width / 2 + 2 * resolution &&
pos.x * resolution > width / 2 - 2 * resolution &&
pos.y * resolution < height / 2 + 2 * resolution &&
pos.y * resolution > height / 2 - 2 * resolution,
// isImmune: random() < 0.5,
};
let nextState = {};
const noiseVal = noise(pos.x, pos.y);
let color = [noiseVal * 255, noiseVal * 10, noiseVal * 100];
const getNeighbors = () => {
const neighbors = [];
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let col = (pos.x + i + cols) % cols;
let row = (pos.y + j + rows) % rows;
if (!(i === 0 && j === 0)) {
neighbors.push(grid[col][row].getState());
}
}
}
return neighbors;
};
const getNextState = () => {
const { isAlive, lifetime, isInfected } = currentState;
let neighbors = getNeighbors();
let numLivingNeighbors = 0;
let infectedCount = 0;
neighbors.forEach(({ isAlive, isInfected }) => {
if (isAlive) {
numLivingNeighbors++;
if (isInfected) {
infectedCount++;
}
}
});
const nextInfected = infectedCount > 1 ? true : isInfected;
let newIsAlive = isAlive;
let newLifetime = lifetime;
if (!isAlive && numLivingNeighbors == 3) {
newIsAlive = true;
newLifetime = 1;
}
if (isAlive && (numLivingNeighbors < 2 || numLivingNeighbors > 3)) {
newIsAlive = false;
}
if (lifetime > 255) {
newIsAlive = false;
}
return {
currentState,
isAlive: newIsAlive,
lifetime: newLifetime,
isInfected: nextInfected,
};
};
return {
getState: () => currentState,
applyNextState: () => {
currentState = nextState;
},
update: () => {
currentState.lifetime += 0.5;
nextState = getNextState();
},
show: () => {
const { isAlive, lifetime, isInfected } = currentState;
if (isAlive) {
const w = noiseVal * resolution * 2;
noStroke();
rectMode(CENTER);
if (isInfected) {
fill(255, 255, 255, 255 / lifetime);
ellipse(pos.x * resolution, pos.y * resolution, w, w);
} else {
fill(color, 255 / lifetime);
rect(pos.x * resolution, pos.y * resolution, w, w);
}
}
},
};
}
function setup() {
createCanvas(800, 800);
cols = width / resolution;
rows = height / resolution;
background(0);
grid = make2DArray(cols, rows);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
grid[i][j] = new Cell({
pos: createVector(i, j),
isAlive: random() < 0.3,
});
}
}
}
function draw() {
background(0, 5);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
grid[i][j].update();
grid[i][j].show();
}
}
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
grid[i][j].applyNextState();
}
}
}