xxxxxxxxxx
const agentCount = 100;
const agentSpeed = 1;
let _agents;
let pixelSize;
let pixelsWidth, pixelsHeight;
function setup() {
pixelSize = sqrt(windowWidth * windowHeight) / 220;
pixelsWidth = floor(windowWidth / pixelSize);
pixelsHeight = floor(windowHeight / pixelSize);
createCanvas(pixelSize * pixelsWidth, pixelSize * pixelsHeight);
background("white");
_agents = agents();
}
mouseClicked = () => setup();
function draw() {
scale(pixelSize);
_agents.update();
}
function agents() {
const pixels = pixelsFunction();
const agentArray = Array.from({ length: agentCount }, () => agent(pixels));
return {
update: () => {
for (let i = 0; i < agentSpeed; i++) {
agentArray.forEach((agent) => agent.next());
}
},
};
}
function pixelsFunction() {
let pixelData = 0n;
index = (x, y) => BigInt(x + y * pixelsWidth);
return {
canMoveTo: ({ x, y }) =>
0 <= x &&
x < pixelsWidth &&
0 <= y &&
y < pixelsHeight &&
!((pixelData >> index(x, y)) & 1n),
set: ({ x, y }) => (pixelData |= 1n << index(x, y)),
draw: (pos1, pos2, colour) => {
stroke(colour);
line(pos1.x, pos1.y, pos2.x, pos2.y);
},
};
}
function* agent(pixels) {
const directions = shuffle([
{ dx: +1, dy: 0 },
{ dx: 0, dy: +1 },
{ dx: -1, dy: 0 },
{ dx: 0, dy: -1 },
]);
const colour = "#" + hex(random(0xffffff), 6);
const start = {
x: floor(random(pixelsWidth)),
y: floor(random(pixelsHeight)),
};
const stack = [start];
pixels.set(start);
while (stack.length) {
const current = stack.pop();
for (const { dx, dy } of directions) {
const target = {
x: current.x + dx,
y: current.y + dy,
};
if (!pixels.canMoveTo(target)) continue;
stack.push(target);
pixels.set(target);
pixels.draw(current, target, colour);
yield;
}
}
}