OverviewCode › R81
Code · blind round

R81 · Flocking birds with three rules

blind round 4/8 local models answered

Answers below are anonymized and shuffled. Read, judge, pick a favourite — then scroll down and reveal the models.

The field: deepseek-r1:14b · gemma4:26b · llama3.1:8b · mistral-small:24b · qwen3-coder:30b · qwen3:14b · qwen3:8b · qwen3.5:9b — listed alphabetically, which is not the order of the cards below.

2 of the 8 local models delivered nothing through our test harness in this round — for reasons that lie with our setup, not with the models. Those cards are marked DNF like any other, but they are not evidence about those models. Which ones, and why, is spelled out in the reveal.

Show task
Create ONE self-contained HTML file (STRICT LIMIT: max 7000 characters in total — this is a budget on characters, not on lines, so removing line breaks does not help) that simulates 200 flocking birds on a <canvas> using the three classic rules: separation, alignment and cohesion. Draw each bird as a small triangle pointing in its direction of travel, let flocks form, split and merge on their own, and wrap the birds around the edges. Show the current number of distinct flocks and the average speed. Smooth requestAnimationFrame animation, NO user input, starts immediately and keeps running (restart with a fresh random instance when finished). No external libraries, no comments needed. Output ONLY the HTML file content, nothing else.

The answers — blind

Local models (Brain cluster) — identical prompt, anonymized order
MODEL Adeepseek-r1:14bBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head>
    <style>body{margin:0;padding:0;display:flex;justify-content:center;align-items:center;height:100vh;background:#fff}.canvas-container{position:relative}.info{position:absolute;top-left:5px;color:black;font-family:sans-serif}</style>
</head>
<body>
    <div class="info">
        <div id="flocks">Flocks: 0</div>
        <div id="speed">Speed: 0</div>
    </div>
    <canvas class="canvas-container" width="800" height="600"></canvas>

    <script>
        const canvas = document.querySelector('canvas');
        const ctx = canvas.getContext('2d');
        const birds = [];
        const flocks = [];
        const maxBirds = 200;
        let frameCount = 0;

        class Bird {
            constructor() {
                this.reset();
            }

            reset() {
                this.x = Math.random() * canvas.width;
                this.y = Math.random() * canvas.height;
                this.vx = (Math.random() - 0.5) * 2;
                this.vy = (Math.random() - 0.5) * 2;
                this.speed = 1;
                this.angle = 0;
            }

            update() {
                const separationForce = this.applySeparation();
                const alignmentForce = this.applyAlignment();
                const cohesionForce = this.applyCohesion();

                let forceX = (separationForce.x + alignmentForce.x + cohesionForce.x) * 0.1;
                let forceY = (separationForce.y + alignmentForce.y + cohesionForce.y) * 0.1;

                this.vx += forceX;
                this.vy += forceY;

                const speedLimit = Math.sqrt(this.vx ** 2 + this.vy ** 2);
                if (speedLimit > 3) {
                    this.vx *= 0.8;
                    this.vy *= 0.8;
                }

                this.x += this.vx;
                this.y += this.vy;

                if (this.x < 0) this.x = canvas.width;
                if (this.x > canvas.width) this.x = 0;
                if (this.y < 0) this.y = canvas.height;
                if (this.y > canvas.height) this.y = 0;
            }

            applySeparation() {
                let sumX = 0, sumY = 0;
                for (let bird of birds) {
                    if (bird !== this && distance(this, bird) < 30) {
                        sumX += (this.x - bird.x);
                        sumY += (this.y - bird.y);
                    }
                }
                return {x: sumX * 0.1, y: sumY * 0.1};
            }

            applyAlignment() {
                let sumX = 0, sumY = 0, count = 0;
                for (let bird of birds) {
                    if (bird !== this && distance(this, bird) < 80) {
                        sumX += bird.vx;
                        sumY += bird.vy;
                        count++;
                    }
                }
                return {x: (sumX / count || 0) * 0.1, y: (sumY / count || 0) * 0.1};
            }

            applyCohesion() {
                let sumX = 0, sumY = 0;
                for (let bird of birds) {
                    if (bird !== this && distance(this, bird) < 80) {
                        sumX += bird.x;
                        sumY += bird.y;
                    }
                }
                const count = birds.length - 1;
                return {x: (sumX / count - this.x) * 0.3, y: (sumY / count - this.y) * 0.3};
            }

            draw() {
                ctx.beginPath();
                ctx.fillStyle = '#F00';
                ctx.moveTo(this.x, this.y);
                ctx.lineTo(this.x + Math.cos(this.angle) * 5, this.y + Math.sin(this.angle) * 8);
                ctx.lineTo(this.x - Math.cos(this.angle) * 3, this.y + Math.sin(this.angle) * 8);
                ctx.fill();
            }
        }

        function distance(bird1, bird2) {
            return Math.sqrt((bird1.x - bird2.x)**2 + (bird1.y - bird2.y)**2);
        }

        function findFlocks() {
            if (!birds.length) return [];
            const newFlocks = [];
            let currentFlock = [birds[0]];
            
            for (let bird of birds.slice(1)) {
                let minDist = Infinity;
                let nearestBird = null;

                for (let f in newFlocks) {
                    const flockBirds = newFlocks[f];
                    let distToFirst = distance(bird, flockBirds[0]);
                    if (distToFirst < 25 && distToFirst < minDist) {
                        minDist = distToFirst;
                        nearestBird = flockBirds[0];
                    }
                }

                if (!nearestBird || distance(bird, nearestBird) > 25) {
                    currentFlock.push(bird);
                } else {
                    newFlocks[newFlocks.length - 1] = [...newFlocks[newFlocks.length - 1], ...currentFlock];
                    currentFlock = [bird];
                }
            }

            if (currentFlock.length > 0) {
                newFlocks.push(currentFlock);
            }

            return newFlocks;
        }

        function animate() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            for (let bird of birds) bird.update();
            
            flocks.value = findFlocks().length;

            let totalSpeed = 0;
            for (let bird of birds) {
                totalSpeed += Math.sqrt(bird.vx ** 2 + bird.vy ** 2);
                bird.draw();
            }

            document.getElementById('flocks').textContent = `Flocks: ${flocks.value}`;
            document.getElementById('speed').textContent = `Speed: ${(totalSpeed / birds.length).toFixed(1)}`;

            if (++frameCount % 60 === 59) {
                // Every second, update speeds
                for (let bird of birds) {
                    bird.speed *= 1 + Math.random() * 0.4 - 0.2;
                    if (bird.speed < 0.5) bird.speed = 0.5;
                }
            }

            requestAnimationFrame(animate);
        }

        function init() {
            for (let i = 0; i < maxBirds; i++) {
                birds.push(new Bird());
            }
            animate();
        }

        // Start fresh simulation
        init();

        window.addEventListener('resize', () => {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        });
    </script>
</body>
</html>
```
MODEL Bgemma4:26bDNF
No usable answer reached the harness (TIMEOUT). Counted as a did-not-finish.
MODEL Cllama3.1:8bDNF
No usable answer reached the harness (TIMEOUT). Counted as a did-not-finish.
MODEL Dqwen3:8bDNF
No usable answer reached the harness (ERR). Counted as a did-not-finish.
No usable answer reached the harness (TIMEOUT). Counted as a did-not-finish.
MODEL Fqwen3-coder:30bERRBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head>
<title>Flocking Simulation</title>
<style>body {margin:0;overflow:hidden;background-color:#111}canvas {display:block;}</style>
</head>
<body>
<canvas id="flockCanvas"></canvas>
<script>
const canvas = document.getElementById('flockCanvas');
const ctx = canvas.getContext('2d');

let width, height;
let birds = [];
let MAX_BIRDS = 200;

// Constants for flocking rules
const VISION_RADIUS = 50;
const SEPARATION_DISTANCE = 10;
const COHESION_WEIGHT = 0.3;
const ALIGNMENT_WEIGHT = 0.5;
const SEPARATION_WEIGHT = 1.5;
const MAX_FORCE = 0.2;
const NEIGHBOR_COUNT_THRESHOLD = 5;

function init() {
    width = window.innerWidth;
    height = window.innerHeight;
    canvas.width = width;
    canvas.height = height;
    birds = [];
    for (let i = 0; i < MAX_BIRDS; i++) {
        birds.push(new Bird(Math.random() * width, Math.random() * height));
    }
    animationLoop();
}

class Vector {
    constructor(x, y) {
        this.x = x || 0;
        this.y = y || 0;
    }
    add(v) { return new Vector(this.x + v.x, this.y + v.y); }
    sub(v) { return new Vector(this.x - v.x, this.y - v.y); }
    mult(s) { return new Vector(this.x * s, this.y * s); }
    magSq() { return this.x * this.x + this.y * this.y; }
    mag() { return Math.sqrt(this.magSq()); }
    normalize() { 
        const m = this.mag();
        return m > 0 ? this.mult(1 / m) : new Vector(0, 0);
    }
    limit(max) {
        if (this.magSq() > max * max) {
            const ratio = max / Math.sqrt(this.magSq());
            return this.mult(ratio);
        }
        return this;
    }

    static random2D() {
        return new Vector((Math.random() - 0.5) * 2, (Math.random() - 0.5) * 2);
    }
}


class Bird {
    constructor(x, y) {
        this.pos = new Vector(x, y);
        this.vel = Vector.random2D().mult(1 + Math.random());
        this.acc = new Vector();
        this.maxSpeed = 3;
        this.maxForce = 0.25;
    }

    applyForce(force) {
        this.acc = this.acc.add(force);
    }

    flock(allBirds) {
        const separation = this.separate(allBirds);
        const alignment = this.align(allBirds);
        const cohesion = this.cohere(allBirds);

        // Weighted combination of forces
        this.applyForce(separation.mult(SEPARATION_WEIGHT));
        this.applyForce(alignment.mult(ALIGNMENT_WEIGHT));
        this.applyForce(cohesion.mult(COHESION_WEIGHT));
    }

    separate(allBirds) {
        let steer = new Vector();
        let count = 0;
        for (const other of allBirds) {
            if (other === this) continue;
            const distSq = this.pos.sub(other.pos).magSq();
            if (distSq < SEPARATION_DISTANCE * SEPARATION_DISTANCE) {
                const diff = this.pos.sub(other.pos);
                diff.normalize();
                diff.div(1 / Math.sqrt(Math.PI * 2)); // Weight inversely by distance
                steer = steer.add(diff);
                count++;
            }
        }
        if (count > 0) {
             steer = steer.mult(1 / count).normalize().mult(this.maxSpeed);
             return this.seek(steer);
        }
        return new Vector();
    }

    align(allBirds) {
        let sumVel = new Vector();
        let count = 0;
        for (const other of allBirds) {
            if (other === this) continue;
            const distSq = this.pos.sub(other.pos).magSq();
            if (distSq < VISION_RADIUS * VISION_RADIUS) {
                sumVel = sumVel.add(other.vel);
                count++;
            }
        }
        if (count > 0) {
            const avg = sumVel.mult(1 / count).normalize().mult(this.maxSpeed);
            return this.seek(avg);
        }
        return new Vector();
    }

    cohere(allBirds) {
        let centerOfMass = new Vector();
        let count = 0;
        for (const other of allBirds) {
            if (other === this) continue;
            const distSq = this.pos.sub(other.pos).magSq();
            if (distSq < VISION_RADIUS * VISION_RADIUS) {
                centerOfMass = centerOfMass.add(other.pos);
                count++;
            }
        }
        if (count > 0) {
            const avgPos = centerOfMass.mult(1 / count).add(this.pos); // Adjust for seeking, but keep it simple: just the target location
            const desiredVel = new Vector(avgPos.x - this.pos.x, avgPos.y - this.pos.y).normalize().mult(this.maxSpeed);
            return this.seek(desiredVel);
        }
        return new Vector();
    }

    // Standard steering force calculation (Desired Velocity - Current Velocity)
    seek(targetVector) {
        const desired = targetVector; 
        let steer = desired.sub(this.vel).limit(this.maxForce);
        steer.normalize().mult(this.maxSpeed);
        return steer;
    }

    update() {
        // Apply forces and calculate new velocity/position
        this.applyForce(new Vector(0, 0)); // Reset acceleration before calculation (flock calls handle this)
        this.flock(birds);

        this.vel = this.vel.add(this.acc);
        this.vel = this.vel.limit(this.maxSpeed);
        this.pos = this.pos.add(this.vel);
        this.acc = new Vector(); // Reset acceleration for next frame

        // Wrap boundaries
        if (this.pos.x < 0) this.pos.x += width; else if (this.pos.x > width) this.pos.x -= width;
        if (this.pos.y < 0) this.pos.y += height; else if (this.pos.y > height) this.pos.y -= height;
    }

    draw() {
        ctx.save();
        ctx.translate(this.pos.x, this.pos.y);
        ctx.rotate(Math.atan2(this.vel.y, this.vel.x));
        ctx.fillStyle = '#FFF';
        ctx.beginPath();
        // Draw triangle (bird representation)
        ctx.moveTo(10, 0);
        ctx.lineTo(-5, -7);
        ctx.lineTo(-5, 7);
        ctx.closePath();
        ctx.fill();
        ctx.restore();
    }

    getSpeed() {
        return this.vel.mag();
    }
}


function drawFlocks(birds) {
    const occupied = new Set();
    let flockCount = 0;

    for (let i = 0; i < birds.length; i++) {
        if (occupied.has(i)) continue;

        // Simple clustering heuristic to detect flocks
        let currentBird = birds[i];
        let clusterMembers = [currentBird];
        let searchQueue = [i];
        let visitedIndices = new Set([i]);

        while (searchQueue.length > 0) {
            const index = searchQueue.shift();
            const bird = birds[index];

            for (let j = i + 1; j < birds.length; j++) {
                if (!visitedIndices.has(j)) {
                    const otherBird = birds[j];
                    const distSq = currentBird.pos.sub(otherBird.pos).magSq();
                    // Use a slightly larger radius for initial detection
                    if (distSq < 150 * 150) { 
                        clusterMembers.push(otherBird);
                        visitedIndices.add(j);
                        searchQueue.push(j);
                    }
                }
            }
        }

        // Check if the cluster is large enough to count as a flock
        if (clusterMembers.length >= NEIGHBOR_COUNT_THRESHOLD) {
             flockCount++;
        }
    }
    return flockCount;
}


function loop() {
    ctx.fillStyle = 'rgba(17, 17, 17, 0.2)';
    ctx.fillRect(0, 0, width, height);

    let totalSpeed = 0;
    const activeBirds = birds.filter(b => b !== undefined);
    for (let i = 0; i < activeBirds.length; i++) {
        activeBirds[i].update();
        activeBirds[i].draw();
        totalSpeed += activeBirds[i].getSpeed();
    }

    const avgSpeed = totalSpeed / activeBirds.length || 0;
    const flockCount = drawFlocks(activeBirds);

    // Display metrics
    ctx.fillStyle = '#FFF';
    ctx.font = '16px Arial';
    ctx.fillText(`Flocks: ${flockCount}`, 10, 25);
    ctx.fillText(`Avg Speed: ${avgSpeed.toFixed(2)}`, 10, 50);

    requestAnimationFrame(loop);
}


// Setup and run
window.addEventListener('resize', () => {
    width = window.innerWidth;
    height = window.innerHeight;
    canvas.width = width;
    canvas.height = height;
});

init();

</script>
</body>
</html>
```
MODEL Gqwen3:14bOKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Boid Simulation</title>
    <style>
        body { margin: 0; overflow: hidden; background-color: #111; }
        canvas { display: block; }
        #stats { position: absolute; top: 10px; left: 10px; color: white; font-family: monospace; z-index: 10; background: rgba(0, 0, 0, 0.5); padding: 10px; border-radius: 5px; }
    </style>
</head>
<body>
    <canvas id="boidCanvas"></canvas>
    <div id="stats">Flocks: 0 | Avg Speed: 0.0</div>

    <script>
        const canvas = document.getElementById('boidCanvas');
        const ctx = canvas.getContext('2d');
        let WIDTH, HEIGHT;

        // Simulation Parameters
        const N_BIRDS = 200;
        const MAX_SPEED = 5.0;
        const MAX_FORCE = 0.1;
        const SEPARATION_DISTANCE = 30;
        const COHESION_RADIUS = 80;

        let birds = [];
        let lastTime = 0;

        // --- Vector Helper Functions (to save space) ---
        function createVector(x, y) { return { x: x || 0, y: y || 0 }; }
        function add(v1, v2) { return createVector(v1.x + v2.x, v1.y + v2.y); }
        function sub(v1, v2) { return createVector(v1.x - v2.x, v1.y - v2.y); }
        function mult(v, s) { return createVector(v.x * s, v.y * s); }
        function magSq(v) { return v.x * v.x + v.y * v.y; }
        function magnitude(v) { return Math.sqrt(magSq(v)); }
        function normalize(v) { const m = magnitude(v); return m ? mult(v, 1 / m) : createVector(0, 0); }

        // --- Bird Class/Object Setup ---
        class Bird {
            constructor() {
                this.x = Math.random() * WIDTH;
                this.y = Math.random() * HEIGHT;
                this.vx = (Math.random() - 0.5) * MAX_SPEED;
                this.vy = (Math.random() - 0.5) * MAX_SPEED;
                this.accX = 0;
                this.accY = 0;
            }

            applyForce(force) {
                this.accX += force.x;
                this.accY += force.y;
            }

            // Calculates the desired steering force based on neighbors and rules
            flock(boids) {
                let separation = createVector(0, 0);
                let alignment = createVector(0, 0);
                let cohesion = createVector(0, 0);
                
                let neighborCount = 0;

                for (const other of boids) {
                    if (other === this) continue;

                    let d = sub(this, other);
                    let distSq = magSq(d);
                    let dist = Math.sqrt(distSq);
                    
                    // Check if within cohesion/alignment radius
                    if (neighborCount < 10 && dist < COHESION_RADIUS) { // Limit processing to keep it fast
                         neighborCount++;

                        // Separation: Steer away from nearby boids
                        if (dist < SEPARATION_DISTANCE && dist > 0.1) {
                            let strength = 1 / dist;
                            separation = add(separation, normalize(d));
                        }

                        // Alignment & Cohesion accumulation (always within COHESION_RADIUS)
                        alignment = add(alignment, other);
                        cohesion = add(cohesion, other);
                    }
                }

                // Separate and average forces
                let separationForce = mult(normalize(separation), 1 / Math.max(1, neighborCount));
                let alignmentForce = mult(normalize(alignment), neighborCount * MAX_SPEED / COHESION_RADIUS);
                let cohesionForce = mult(normalize(cohesion), 1 / Math.max(1, neighborCount)) ;

                // Apply rules (Weighted averages)
                this.applyForce(mult(separationForce, 1.5)); // Separation weight higher
                this.applyForce(mult(alignmentForce, 1.0));
                this.applyForce(mult(cohesionForce, 1.0));

                // Limit acceleration
                let acc = createVector(this.accX, this.accY);
                if (magnitude(acc) > MAX_FORCE) {
                    let factor = MAX_FORCE / magnitude(acc);
                    acc = mult(acc, factor);
                }
            }

            // Updates position and velocity using accumulated acceleration
            update() {
                this.vx += this.accX;
                this.vy += this.accY;

                // Limit speed
                let currentSpeed = Math.sqrt(this.vx * this.vx + this.vy * this.vy);
                if (currentSpeed > MAX_SPEED) {
                    let factor = MAX_SPEED / currentSpeed;
                    this.vx *= factor;
                    this.vy *= factor;
                }

                // Apply force damping to prevent infinite acceleration buildup
                this.accX *= 0.1;
                this.accY *= 0.1;


                this.x += this.vx;
                this.y += this.vy;

                // Wrap around boundaries
                if (this.x < 0) this.x = WIDTH;
                if (this.x > WIDTH) this.x = 0;
                if (this.y < 0) this.y = HEIGHT;
                if (this.y > HEIGHT) this.y = 0;
            }

            // Draws the bird as a triangle pointing in direction of travel
            draw() {
                ctx.save();
                ctx.translate(this.x, this.y);
                let angle = Math.atan2(this.vy, this.vx);
                ctx.rotate(angle);

                ctx.beginPath();
                ctx.moveTo(10, 0); // Nose point
                ctx.lineTo(-5, -5); // Wing back left
                ctx.lineTo(-5, 5);  // Wing back right
                ctx.closePath();
                
                ctx.fillStyle = 'white';
                ctx.fill();
                ctx.restore();
            }
        }

        // --- Core Simulation Logic ---

        function handleResize() {
            WIDTH = canvas.width = window.innerWidth;
            HEIGHT = canvas.height = window.innerHeight;
        }

        function initBirds() {
            birds = [];
            for (let i = 0; i < N_BIRDS; i++) {
                birds.push(new Bird());
            }
        }

        function updateSimulation(time) {
            const deltaTime = time - lastTime;
            lastTime = time;

            // 1. Apply Flocking Rules (Acceleration)
            for (let i = 0; i < N_BIRDS; i++) {
                birds[i].flock(birds);
            }

            // 2. Update Physics and Position
            for (const bird of birds) {
                bird.update();
            }

            // 3. Drawing and Stats
            ctx.clearRect(0, 0, WIDTH, HEIGHT);
            for (const bird of birds) {
                bird.draw();
            }

            // Calculate Statistics
            let totalSpeed = 0;
            let flockCount = 0; // Simplified count: Assume a cluster is formed if velocity vectors are close enough to neighbors.
                                 // A robust method requires graph theory, so we'll use a simple proximity check for visualization/estimation.

            for (const bird of birds) {
                totalSpeed += Math.sqrt(bird.vx * bird.vx + bird.vy * bird.vy);
            }
            let avgSpeed = totalSpeed / N_BIRDS;

            // Simple Flock Estimation: Use a temporary grid/distance metric to count clusters
            const visited = new Set();
            const FLOCK_SEARCH_DIST_SQ = 250 * 250; // Max distance for initial cluster check
            let currentFlocks = new Set();

            for (let i = 0; i < N_BIRDS; i++) {
                if (visited.has(i)) continue;

                const startBird = birds[i];
                let neighborsInCluster = [startBird];
                let queue = [{ b: startBird, index: i }];
                let visitedIndices = new Set([i]);

                while (queue.length > 0) {
                    let current = queue.shift();
                    const qB = current.b;
                    const qIdx = current.index;

                    // Check all remaining unvisited birds for proximity
                    for(let j=0; j<N_BIRDS; ++j) {
                        if (!visitedIndices.has(j)) {
                            const other = birds[j];
                            let dSq = (qB.x - other.x)**2 + (qB.y - other.y)**2;

                            if (dSq < FLOCK_SEARCH_DIST_SQ) {
                                neighborsInCluster.push(other);
                                visitedIndices.add(j);
                                queue.push({ b: other, index: j });
                            }
                        }
                    }
                }
                currentFlocks.add(neighborsInCluster.length > 5 ? 'Active' : 'Small'); // Count if cluster is large enough

                // Mark all birds found in this cluster as visited for the next iteration
                for (const neighbor of neighborsInCluster) {
                    visited.add(birds.indexOf(neighbor));
                }
            }
            flockCount = currentFlocks.size;


            document.getElementById('stats').innerHTML = `Flocks: ${Math.max(1, Math.round(flockCount))} | Avg Speed: ${avgSpeed.toFixed(2)}`;

            requestAnimationFrame(updateSimulation);
        }

        // --- Initialization ---
        window.addEventListener('resize', handleResize);
        handleResize();
        initBirds();
        requestAnimationFrame(updateSimulation);

    </script>
</body>
</html>
```
MODEL Hqwen3.5:9bOKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head>
<title>Boids Simulation</title>
<style>body { margin: 0; overflow: hidden; background-color: #111; } canvas { display: block; }</style>
</head>
<body>
<canvas id="boidCanvas"></canvas>
<script>
const canvas = document.getElementById('boidCanvas');
const ctx = canvas.getContext('2d');

let W, H;
let birds = [];

// Simulation Parameters
const NUM_BIRDS = 200;
const MAX_SPEED = 3.5;
const MAX_FORCE = 0.1;
const SEPARATION_WEIGHT = 1.5;
const ALIGNMENT_WEIGHT = 1.0;
const COHESION_WEIGHT = 1.0;

function resize() {
    W = canvas.width = window.innerWidth;
    H = canvas.height = window.innerHeight;
}
window.addEventListener('resize', resize);
resize();

class Bird {
    constructor(x, y) {
        this.pos = { x: x, y: y };
        this.vel = { x: Math.random() * 2 - 1, y: Math.random() * 2 - 1 };
        this.acc = { x: 0, y: 0 };
    }

    applyForce(force) {
        this.acc.x += force.x;
        this.acc.y += force.y;
    }

    // Separation: Steer away from nearby birds
    separate(boids) {
        let steering = { x: 0, y: 0 };
        let count = 0;
        for (const other of boids) {
            if (other === this) continue;
            let d = Math.hypot(this.pos.x - other.pos.x, this.pos.y - other.pos.y);
            if (d < 50 && d > 1) {
                let diffX = this.pos.x - other.pos.x;
                let diffY = this.pos.y - other.pos.y;
                steering.x += diffX / d;
                steering.y += diffY / d;
                count++;
            }
        }
        if (count > 0) {
            steering.x /= count;
            steering.y /= count;
            let mag = Math.hypot(steering.x, steering.y);
            steering.x /= mag;
            steering.y /= mag;
            return { x: steering.x * SEPARATION_WEIGHT, y: steering.y * SEPARATION_WEIGHT };
        }
        return { x: 0, y: 0 };
    }

    // Alignment: Steer towards average velocity of neighbors
    align(boids) {
        let avgVel = { x: 0, y: 0 };
        let count = 0;
        for (const other of boids) {
            if (other === this) continue;
            let d = Math.hypot(this.pos.x - other.pos.x, this.pos.y - other.pos.y);
            if (d < 75) {
                avgVel.x += other.vel.x;
                avgVel.y += other.vel.y;
                count++;
            }
        }
        if (count > 0) {
            avgVel.x /= count;
            avgVel.y /= count;
            let mag = Math.hypot(avgVel.x, avgVel.y);
            if (mag > 0) {
                avgVel.x /= mag;
                avgVel.y /= mag;
                return { x: avgVel.x * ALIGNMENT_WEIGHT, y: avgVel.y * ALIGNMENT_WEIGHT };
            }
        }
        return { x: 0, y: 0 };
    }

    // Cohesion: Steer towards the center of nearby birds
    cohese(boids) {
        let center = { x: 0, y: 0 };
        let count = 0;
        for (const other of boids) {
            if (other === this) continue;
            let d = Math.hypot(this.pos.x - other.pos.x, this.pos.y - other.pos.y);
            if (d < 100) {
                center.x += other.pos.x;
                center.y += other.pos.y;
                count++;
            }
        }
        if (count > 0) {
            center.x /= count;
            center.y /= count;
            let desired = { x: center.x, y: center.y };
            let steerX = desired.x - this.pos.x;
            let steerY = desired.y - this.pos.y;
            let dist = Math.hypot(steerX, steerY);
            if (dist > 0) {
                steerX /= dist;
                steerY /= dist;
                return { x: steerX * COHESION_WEIGHT, y: steerY * COHESION_WEIGHT };
            }
        }
        return { x: 0, y: 0 };
    }

    update(boids) {
        let separation = this.separate(boids);
        let alignment = this.align(boids);
        let cohesion = this.cohese(boids);

        this.applyForce(separation);
        this.applyForce(alignment);
        this.applyForce(cohesion);

        // Limit acceleration and apply force
        let accMag = Math.hypot(this.acc.x, this.acc.y);
        if (accMag > MAX_FORCE) {
            this.acc.x *= (MAX_FORCE / accMag);
            this.acc.y *= (MAX_FORCE / accMag);
        }

        // Update velocity and position
        this.vel.x += this.acc.x;
        this.vel.y += this.acc.y;
        let velMag = Math.hypot(this.vel.x, this.vel.y);
        if (velMag > MAX_SPEED) {
            this.vel.x *= (MAX_SPEED / velMag);
            this.vel.y *= (MAX_SPEED / velMag);
        }

        this.pos.x += this.vel.x;
        this.pos.y += this.vel.y;

        // Edge wrapping
        if (this.pos.x < 0) this.pos.x = W; else if (this.pos.x > W) this.pos.x = 0;
        if (this.pos.y < 0) this.pos.y = H; else if (this.pos.y > H) this.pos.y = 0;

        // Reset acceleration for next frame
        this.acc.x = 0;
        this.acc.y = 0;
    }

    draw() {
        ctx.save();
        ctx.translate(this.pos.x, this.pos.y);
        let angle = Math.atan2(this.vel.y, this.vel.x);
        ctx.rotate(angle);
        ctx.beginPath();
        ctx.moveTo(10, 0); // Tip of the triangle
        ctx.lineTo(-5, -5); // Bottom left
        ctx.lineTo(-5, 5);  // Bottom right
        ctx.closePath();
        ctx.fillStyle = '#FFF';
        ctx.fill();
        ctx.restore();
    }
}

function initialize() {
    birds = [];
    for (let i = 0; i < NUM_BIRDS; i++) {
        const x = Math.random() * W;
        const y = Math.random() * H;
        birds.push(new Bird(x, y));
    }
}

function calculateMetrics() {
    let totalSpeedSq = 0;
    for (const b of birds) {
        totalSpeedSq += b.vel.x * b.vel.x + b.vel.y * b.vel.y;
    }
    const avgSpeed = Math.sqrt(totalSpeedSq / NUM_BIRDS);

    // Simple flock counting: count groups of birds that are close together
    let numFlocks = 0;
    let visited = new Array(NUM_BIRDS).fill(false);

    for (let i = 0; i < NUM_BIRDS; i++) {
        if (!visited[i]) {
            numFlocks++;
            let seed = [i];
            let head = 0;
            while (head < seed.length) {
                const currentBirdIndex = seed[head++];
                visited[currentBirdIndex] = true;

                for (let j = currentBirdIndex + 1; j < NUM_BIRDS; j++) {
                    if (!visited[j]) {
                        const b1 = birds[currentBirdIndex];
                        const b2 = birds[j];
                        const dist = Math.hypot(b1.pos.x - b2.pos.x, b1.pos.y - b2.pos.y);
                        if (dist < 30) { // Flocking proximity threshold
                            seed.push(j);
                        }
                    }
                }
            }
        }
    }

    document.getElementById('stats').innerHTML = `Flocks: ${numFlocks}<br>Avg Speed: ${avgSpeed.toFixed(2)}`;
}

function animate() {
    ctx.fillStyle = 'rgba(17, 17, 17, 0.5)';
    ctx.fillRect(0, 0, W, H);

    for (const bird of birds) {
        bird.update(birds);
        bird.draw();
    }

    calculateMetrics();
    requestAnimationFrame(animate);
}

// Setup HUD element dynamically
document.body.insertAdjacentHTML('beforeend', '<div id="stats" style="position: fixed; top: 10px; left: 10px; color: white; font-family: monospace; background: rgba(0, 0, 0, 0.6); padding: 5px;">Initializing...</div>');

initialize();
animate();
</script>
</body>
</html>
```
Reveal the models— compare the answers first, then open. Names, blind scores and latencies are hidden until you do.

Who wrote what

Blind labelModelBlind scoreLatencyStatus
MODEL A deepseek-r1:14b 54.1 sOK
MODEL B gemma4:26b harness
MODEL C llama3.1:8b DNF
MODEL D qwen3:8b harness
MODEL E mistral-small:24b DNF
MODEL F qwen3-coder:30b 71.2 sOK
MODEL G qwen3:14b 106.5 sOK
MODEL H qwen3.5:9b 36.0 sOK