OverviewCode › R111
Code · blind round

R111 · Ant colony laying pheromone trails

blind round 9/11 local models answered

Every answer below carries the name of the model that wrote it. Blind refers to the scoring: the review was done without knowing which model produced which answer — the published result names them.

2 of the 11 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 — the reason is noted on the card itself.

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 an ant colony on a <canvas>: ants leave a nest, wander with a random walk biased towards pheromone, and when one finds a food source it returns to the nest depositing pheromone along the way, so a visible trail forms and other ants follow it. Let pheromone evaporate slowly so abandoned trails fade. Draw the pheromone field and the ants, and show the ant count and the food carried home. 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

Local models (Brain cluster) — identical prompt, shuffled order (the sequence is not a ranking)
gemma4:26bharness
No answer reached us (THIN) — and the reason lies with our setup, not with the model: reasoning consumed the entire token budget (3 min 28 s, zero characters of answer); larger budgets are refused by the gateway Counted as a did-not-finish, but it is not evidence about this model.
qwen3.5:9bERRBLANKMINIFIEDFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head><title>Ant Colony Simulation</title></head>
<body><canvas id="c"></canvas><script>const c=document.getElementById('c');c.width=800;c.height=600;const ctx=c.getContext('2d');let A=[],Pouse=new Map(),FOOD_LOC={x:750,y:50},NEST_LOC={x:50,y:550};const PheromoneDecay=0.98;const MaxPheromone=100;const AntCount=25;let FoodCarried=0;function init() {A=[];for(let i=0;i<AntCount;i++)A.push({x:Math.random()*c.width,y:Math.random()*c.height,vx:Math.cos(Math.random()*Math.PI)*2+(Math.random()*4-2),vy:Math.sin(Math.random()*Math.PI)*2+(Math.random()*4-2),dir:Math.atan2(Math.sin(i*0.5)*10,Math.cos(i*0.5)*10)});A.forEach(a=>{a.energy=1;a.food=0;});Pouse.clear();for(let x=0;x<80;x++)for(let y=0;y<60;y++){Pouse.set(`${x},${y}`,Math.random()*5);}FoodCarried=0;ctx.clearRect(0,0,c.width,c.height);draw();requestAnimationFrame(loop)}function draw() {ctx.fillStyle='#333';ctx.fillRect(0,0,c.width,c.height);/* Draw Pheromone */for(let y=0;y<60;y++){for(let x=0;x<80;x++){let p=Pouse.get(`${x},${y}`)||1;ctx.fillStyle=`rgba(255,204,0,${p/MaxPheromone*0.7})`;ctx.fillRect(x*10, y*10, 10, 10)}}/* Draw Food */ctx.fillStyle='red';ctx.beginPath();ctx.arc(FOOD_LOC.x,FOOD_LOC.y,8,0,Math.PI*2);ctx.fill();/* Draw Nest */ctx.fillStyle='#006400';ctx.fillRect(NEST_LOC.x-10,NEST_LOC.y-10,20,20);/* Display Stats */ctx.fillStyle='white';ctx.font='16px Arial';ctx.fillText(`Ants: ${A.length}`,10,25);ctx.fillText(`Food: ${Math.floor(FoodCarried)}`,10,50);  }function updatePheromones() {let newPouse=new Map();for(let y=0;y<60;y++){for(let x=0;x<80;x++){let p=Pouse.get(`${x},${y}`)||1;p*=PheromoneDecay;newPouse.set(`${x},${y}`,Math.min(p,MaxPheromone));}}Pouse=newPouse}function getGridCoords(x,y){const gx=Math.floor(x/10);const gy=Math.floor(y/10);return `${gx},${gy}`;}function followPheromones(a){let maxP=0;let bestDir={dx:0,dy:0};let gridKey = getGridCoords(a.x,a.y);for(let y=-2;y<=2;y++){for(let x=-2;x<=2;x++){if(Math.abs(x*10)>15||Math.abs(y*10)>15)continue;let nx=a.x+x*10;let ny=a.y+y*10;if(nx<0 || nx>c.width || ny<0 || ny>c.height)continue;let key=getGridCoords(nx,ny);let p=Pouse.get(key)||0;if(p>maxP){maxP=p;bestDir={dx:x*10,dy:y*10};}}return bestDir;}function updateAnts() {A.forEach(a=>{/* Calculate bias */let targetDir={dx:0,dy:0};let p_dir={dx:0,dy:0};const bias = followPheromones(a);if(bias.dx!==0||bias.dy!==0){targetDir=bias;}else{/* Random walk if no pheromone detected */targetDir={{dx:(Math.random()-0.5)*20, dy:(Math.random()-0.5)*20}}};let angle = Math.atan2(targetDir.dy, targetDir.dx);a.vx=Math.cos(angle)*Math.min(4,1+a.food*0.5);a.vy=Math.sin(angle)*Math.min(4,1+a.food*0.5);/* Movement */a.x+=a.vx;a.y+=a.vy;/* Collision/Bound Check */if(a.x<0||a.x>c.width||a.y<0||a.y>c.height){a.x=Math.max(0,Math.min(c.width,a.x));a.y=Math.max(0,Math.min(c.height,a.y));}/* Food Interaction */if(!a.food&&Math.hypot(a.x-FOOD_LOC.x,a.y-FOOD_LOC.y)<15){a.food=1;a.energy+=2;A.splice(A.indexOf(a),1,Object.assign({},a,{food:1,vx:0,vy:0}));}/* Nest Interaction */if(a.food&&Math.hypot(a.x-NEST_LOC.x,a.y-NEST_LOC.y)<30){FoodCarried+=a.food;a.food=0;a.energy+=1;}/* Energy Decay and Death */a.energy-=0.05;if(a.energy<0){A.splice(A.indexOf(a),1);}else{/* Pheromone Deposit (Trail) */let key=getGridCoords(a.x,a.y);Pouse.set(key,Math.min(MaxPheromone,Pouse.get(key)||0)+0.5*a.food+0.2);}}});A=A.filter(a=>a.energy>-1);updatePheromones();
function loop() {ctx.clearRect(0,0,c.width,c.height);draw();requestAnimationFrame(loop)}init();</script></body></html>
```
llama3.1:8bERRSTATFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ant Colony Simulation</title>
<style>
canvas {
  border: 1px solid black;
}
.ant {
  position: absolute;
  width: 2px;
  height: 10px;
  background-color: red;
}
.pheromone {
  position: absolute;
  background-color: lightblue;
}
</style>
</head>
<body>
<canvas id="c" width="800" height="600"></canvas>
<script>
const c = document.getElementById('c');
const ctx = c.getContext('2d');

let nest = { x: 400, y: 50 };
let food = { x: Math.random() * 700 + 100, y: Math.random() * 500 + 150 };
let pheromone = [];
for (let i = 0; i < 200; i++) {
  let p = { x: Math.random() * 800, y: Math.random() * 600, amount: Math.random() / 100};
  pheromone.push(p);
}
let ants = [
  {
    x: nest.x,
    y: nest.y,
    dx: Math.random() * 2 - 1,
    dy: Math.random() * 2 - 1,
    speed: 0.5
  }
];

function draw() {
  c.width = c.offsetWidth;
  ctx.fillStyle = 'lightblue';
  ctx.fillRect(0, 0, c.width, c.height);
  ctx.fillStyle = 'black';
  ctx.font = '16px Arial';
  ctx.textAlign = 'left';
  ctx.textBaseline = 'top';
  ctx.fillText(`Ants: ${ants.length}`, 10, 20);
  ctx.textAlign = 'right';
  ctx.fillText(`Food home: ${food.x}x${food.y}`, c.width - 10, 20);

  for (let i = 0; i < pheromone.length; i++) {
    let p = pheromone[i];
    ctx.fillStyle = `lightblue`;
    ctx.globalAlpha = p.amount;
    ctx.fillRect(p.x, p.y, 2, 2);
  }
  globalAlpha = 1;

  for (let a of ants) {
    ctx.fillStyle = 'red';
    ctx.fillRect(a.x, a.y, 2, 10);

    let speed = Math.min(a.speed, 0.5 + pheromone.find(p => p.x === a.x && p.y === a.y).amount);
    if (a.x >= food.x && a.y >= food.y) {
      ants.pop();
      ctx.fillStyle = 'green';
      ctx.fillRect(food.x, food.y, 2, 10);
    } else {
      a.dx += Math.random() * 0.1 - 0.05;
      a.dy += Math.random() * 0.1 - 0.05;
      if (Math.abs(a.x - food.x) < speed && Math.abs(a.y - food.y) < speed) {
        a.dx = (food.x - a.x) / Math.sqrt(Math.pow(food.x - a.x, 2) + Math.pow(food.y - a.y, 2)) * speed;
        a.dy = (food.y - a.y) / Math.sqrt(Math.pow(food.x - a.x, 2) + Math.pow(food.y - a.y, 2)) * speed;
      }
      if (pheromone.length < 200) {
        let p = { x: a.x, y: a.y, amount: pheromone.find(p => p.x === a.x && p.y === a.y).amount + 0.001 };
        pheromone.push(p);
      }
    }
    a.x += a.dx;
    a.y += a.dy;

    ctx.fillStyle = 'red';
    ctx.fillRect(a.x, a.y, 2, 10);

    if (a.x < 0 || a.x > c.width || a.y < 0 || a.y > c.height) {
      ants.pop();
    }
    for (let i = 0; i < pheromone.length; i++) {
      let p = pheromone[i];
      if (Math.abs(a.x - p.x) < 5 && Math.abs(a.y - p.y) < 5) {
        p.amount *= 0.99;
      }
    }
  }

  requestAnimationFrame(draw);
}

draw();
</script>
</body>
</html>
```
qwen3-coder:30bBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ant Colony Simulation</title>
    <style>
        body { margin: 0; overflow: hidden; background-color: #111; display: flex; justify-content: center; align-items: center; height: 100vh; }
        #canvas { border: 1px solid #333; background-color: #223; }
    </style>
</head>
<body>
<canvas id="canvas"></canvas>

<script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    let W, H;
    let ants = [];
    let pheromoneGrid;
    let foodSource = {};
    let nest = { x: 50, y: 50 };
    let lastTime = 0;

    const PHERO_DECAY = 0.98; // Persistence factor for evaporation
    const PHERO_DEPOSIT = 10; // Amount deposited per step
    const MAX_PHERO = 200; // Max pheromone concentration
    const ANT_COUNT = 45;
    const FOOD_VALUE = 3;

    function resizeCanvas() {
        W = window.innerWidth * 0.9;
        H = window.innerHeight * 0.8;
        canvas.width = W;
        canvas.height = H;
        pheromoneGrid = createGrid(Math.ceil(W / 10), Math.ceil(H / 10));
    }

    function createGrid(cols, rows) {
        return Array(rows).fill(0).map(() => new Float32Array(cols).fill(0));
    }

    class Ant {
        constructor() {
            this.x = nest.x + Math.random() * 10;
            this.y = nest.y + Math.random() * 10;
            this.dx = (Math.random() - 0.5) * 2;
            this.dy = (Math.random() - 0.5) * 2;
            this.maxSpeed = 3;
            this.carryingFood = false;
            this.foodRemaining = 0; // How many steps until food is dropped/consumed
        }

        move(px, py) {
            if (this.carryingFood && this.foodRemaining > 0) {
                // Returning to nest
                const angleToNest = Math.atan2(nest.y - this.y, nest.x - this.x);
                this.dx = Math.cos(angleToNest) * this.maxSpeed;
                this.dy = Math.sin(angleToNest) * this.maxSpeed;

                if (Math.hypot(this.x - nest.x, this.y - nest.y) < 10) {
                    this.foodRemaining--;
                    this.carryingFood = false;
                    this.foodRemaining = 0; // Drop food
                    return true; // Reached nest
                }
            } else if (Math.hypot(this.x - foodSource.x, this.y - foodSource.y) < 10 && !this.carryingFood) {
                // Found food
                this.foodRemaining = FOOD_VALUE;
                this.carryingFood = true;
            } else if (Math.hypot(this.x - nest.x, this.y - nest.y) < 10 && !this.carryingFood) {
                 // Stay near nest if no food is available
            }

            if (this.foodRemaining > 0) {
                this.foodRemaining--;
            }


            // Apply movement
            this.x += this.dx;
            this.y += this.dy;

            // Boundary check
            this.x = Math.max(1, Math.min(W - 1, this.x));
            this.y = Math.max(1, Math.min(H - 1, this.y));

            return false; // Did not reach nest
        }

        // Calculates movement bias based on pheromones
        calculateMovement(px, py) {
            const col = Math.floor(this.x / 10);
            const row = Math.floor(this.y / 10);

            let totalPhero = 0;
            let dxBias = 0;
            let dyBias = 0;

            // Check neighbors (simple gradient approximation)
            for (let offsetR = -1; offsetR <= 1; offsetR++) {
                for (let offsetC = -1; offsetC <= 1; offsetC++) {
                    if (offsetR === 0 && offsetC === 0) continue;

                    const nCol = Math.min(Math.floor(W / 10) - 1, Math.max(0, col + offsetC));
                    const nRow = Math.min(Math.floor(H / 10) - 1, Math.max(0, row + offsetR));

                    if (nCol >= 0 && nRow >= 0) {
                        const pheroValue = pheromoneGrid[row][nCol];
                        totalPhero += pheroValue;

                        // Calculate direction vector difference from current spot
                        let angle = Math.atan2(Math.sin((offsetR + offsetC)/2), Math.cos((offsetR + offsetC)/2));
                        if (offsetR < 0) { angle = -Math.PI / 2; } // Up
                        else if (offsetR > 0) { angle = Math.PI / 2; } // Down
                        else if (offsetC < 0) { angle = Math.PI; } // Left
                        else if (offsetC > 0) { angle = 0; } // Right

                        // Simple heuristic for bias: prioritize the highest concentration neighbor
                        if (Math.abs(pheromoneGrid[row + offsetR][nCol + offsetC]) > totalPhero / 10) {
                             dxBias += (offsetC * Math.random() * (pheromoneGrid[row + offsetR][nCol + offsetC] / MAX_PHERO));
                             dyBias += (offsetR * Math.random() * (pheromoneGrid[row + offsetR][nCol + offsetC] / MAX_PHERO));
                        }
                    }
                }
            }

            // Fallback: Random walk if no clear bias is found or if far from trails
            if (totalPhero < 5) {
                 dxBias = (Math.random() - 0.5) * 2;
                 dyBias = (Math.random() - 0.5) * 2;
            }

            return { dx: Math.cos(angle) * (1 + dxBias/5), dy: Math.sin(angle) * (1 + dyBias/5) };
        }
    }

    function initializeSimulation() {
        resizeCanvas();
        ants = [];
        for (let i = 0; i < ANT_COUNT; i++) {
            ants.push(new Ant());
        }

        foodSource = { x: W - 50, y: H / 2 };
        nest = { x: 50, y: 50 };
    }

    function updatePheromone() {
        // Decay phase (Evaporation)
        for (let r = 0; r < pheromoneGrid.length; r++) {
            for (let c = 0; c < pheromoneGrid[r].length; c++) {
                pheromoneGrid[r][c] *= PHERO_DECAY;
            }
        }
    }

    function depositPheromone(x, y) {
        const col = Math.floor(x / 10);
        const row = Math.floor(y / 10);

        if (row >= 0 && row < pheromoneGrid.length && col >= 0 && col < pheromoneGrid[row].length) {
            pheromoneGrid[row][col] = Math.min(MAX_PHERO, pheromoneGrid[row][col] + PHERO_DEPOSIT);
        }
    }

    function updateAnts() {
        let foodArrivedCount = 0;
        for (let i = ants.length - 1; i >= 0; i--) {
            const ant = ants[i];

            // Step 1: Determine movement bias
            if (!ant.carryingFood) {
                // Bias towards food source if pheromone trail is weak, or wander randomly
                let targetX = (Math.random() < 0.2 && Math.hypot(foodSource.x - ant.x, foodSource.y - ant.y) < W * 0.8) ? foodSource.x : nest.x;
                let targetY = (Math.random() < 0.2 && Math.hypot(foodSource.y - ant.y, foodSource.y - ant.y) < H * 0.8) ? foodSource.y : nest.y;

                const { dx: biasX, dy: biasY } = ant.calculateMovement(ant.x, ant.y);
                
                // Blend random walk with pheromone/goal guidance
                let newDx = (Math.random() * 0.5 + 0.5) * Math.cos(biasX * 0.5) + biasX * 0.8;
                let newDy = (Math.random() * 0.5 + 0.5) * Math.sin(biasY * 0.5) + biasY * 0.8;

                ant.dx = newDx * ant.maxSpeed / 3;
                ant.dy = newDy * ant.maxSpeed / 3;


            } else {
                // Already calculating movement towards nest/food target
                const didMoveToNest = ant.move(0, 0);
                if (didMoveToNest) {
                    foodArrivedCount++;
                }
            }

            // Step 2: Move and Deposit Pheromones
            let moved = false;
            let newX = Math.min(W - 1, Math.max(1, ant.x + (Math.random() * 0.5 + 0.5) * (ant.dx / ant.maxSpeed)));
            let newY = Math.min(H - 1, Math.max(1, ant.y + (Math.random() * 0.5 + 0.5) * (ant.dy / ant.maxSpeed)));

             // Simple step function for movement based on calculated bias
            const actualDx = (Math.random() * 0.8 + 0.2) * Math.cos(Math.atan2(ant.dy, ant.dx));
            const actualDy = (Math.random() * 0.8 + 0.2) * Math.sin(Math.atan2(ant.dy, ant.dx));

            ant.x += actualDx;
            ant.y += actualDy;

            // Deposit pheromone at current location
            depositPheromone(ant.x, ant.y);
        }
        return foodArrivedCount;
    }


    function draw() {
        let totalFood = 0;
        for (const ant of ants) {
            totalFood += ant.carryingFood ? FOOD_VALUE : 0;
        }

        // Clear the canvas, but leave a faint trail for existing pheromone visualization
        ctx.fillStyle = 'rgba(34, 51, 62, 0.8)'; // Dark background color matching CSS
        ctx.fillRect(0, 0, W, H);


        // Draw Pheromone Grid (Heatmap effect)
        for (let r = 0; r < pheromoneGrid.length; r++) {
            for (let c = 0; c < pheromoneGrid[r].length; c++) {
                const value
deepseek-r1:14bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><body style="margin:0;padding:0;overflow:hidden;background:#000;">
<canvas id=c></canvas>
<div id=s style="position:fixed;top:10px;left:10px;color:white;font-family:sans-serif;"></div>
</body>
<script>
const c=document.getElementById('c'),s=document.getElementById('s');
const ctx=c.getContext('2d');let w=h=500,nestX=250,nestY=250,radius=40;
let ants=[],pheromones=new Map,foodSources=[],score=0,time=0,count=0;

function init(){c.width=w;c.height=h;setParams();}
function setParams(){ants.length=30;speed=1.5;evaporation=0.02;findFoodRadius=40;}

let speed,evaporation,findFoodRadius;
function updateAnts(){
  for(let a of ants){
    if(!a)return;
    let dx=nestX - a.x,dy=nestY -a.y,dir=0.1*(Math.atan2(dy,dx)+Math.PI);
    if(a.state=='wandering'){
      a.dir+=0.1*(Math.random()-0.5);a.bias=0;
      const px=a.x+pheromones.get(`${Math.floor(a.x)}|${Math.floor(a.y)}`)||0;
      if(px>0){a.bias=0.3/(px/100+1)}
    }
    a.dir+=a.bias*(Math.random()/5);
    a.dx=Math.cos(a.dir)*speed*a.bias*2 + Math.cos(a.dir)*speed;
    a.dy=Math.sin(a.dir)*speed*a.bias*2 + Math.sin(a.dir)*speed;
    a.x+=a.dx;a.y+=a.dy;

    if(!a.foundFood && checkFood(a)){a.state='returning';a.foodFound=a.currentTime;}
  }
}

function checkFood(a){
  for(let f of foodSources){
    const dx=a.x-f.x,dy=a.y-f.y;dist=Math.sqrt(dx*dx+dy*dy);
    if(dist<findFoodRadius){foodSources.splice(foodSources.indexOf(f),1);score++;count=ants.filter(a=>a.foundFood).length;
      return true;}
  }
}

function updatePheromones(){for(let [k,v]of pheromones.entries()){pheromones.set(k,v*evaporation);}}

function drawPheromone(){
  ctx.fillStyle='rgba(255,255,0,.1)';
  for(let i=0;i<w/4;i++)for(let j=0;j<h/4;j++){
    const x=i*4,y=j*4;v=pheromones.get(`${x}|${y}`)||0;
    if(v>0){ctx.fillRect(x,y,4,4);}}
}

function drawAnt(a){
  ctx.beginPath();
  a.foundFood ? ctx.fillStyle='yellow' : ctx.fillStyle='#fff';
  ctx.arc(a.x,a.y,2,0,Math.PI*2);ctx.fill();}
function drawNest(){ctx.beginPath();ctx.arc(nestX,nestY,radius,0,Math.PI*2);ctx.fillStyle='white';ctx.fill();}
function stats(){s.textContent=`Ants: ${ants.length} | Food found: ${score}`;}

let time=0;
function simulate(timestamp){
  if(!time){init();setParams();}
  ctx.clearRect(0,0,w,h);
  drawNest();
  updatePheromones();

  // Deposit pheromone from ants
  for(let a of ants){
    if(a.state=='returning' && Date.now()-a.foodFound >1000){
      const k={`${Math.floor(a.x)}|${Math.floor(a.y)}`};
      pheromones.set(k,(pheromones.get(k)||0)+40);
    }
  }

  updateAnts();
  drawPheromone();

  // Draw ants
  for(let a of [...ants].reverse()){
    if(!a.x || a.x<0 || a.x>w || a.y<0 || a.y>h){ants.splice(ants.indexOf(a),1);count--;}
    drawAnt(a);}

  stats();
  time=timestamp;
  requestAnimationFrame(simulate);
}

requestAnimationFrame(simulate);

// Initial setup
function setParams(){  
  ants=[];for(let i=0;i<30;i++)ants.push({
    x:Math.random()*w, y:Math.random()*(h-20)+10, dir:Math.random()*Math.PI*2,
    state:'wandering', foundFood:false, foodFound:0
  });
  
  const numFoods=5;for(let i=0;i<numFoods;i++)foodSources.push({
    x:i==0?nestX-40:nestX+80*i, y:h-100, size:20,
  });
}

</script>
</html>
```
qwen3:14bBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ant Colony 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: 5px; border-radius: 5px;}
    </style>
</head>
<body>
<canvas id="antCanvas"></canvas>
<div id="stats">Ants: 0 | Food Carried: 0</div>

<script>
    const canvas = document.getElementById('antCanvas');
    const ctx = canvas.getContext('2d');
    let width, height;
    
    // Global State Variables
    let pheromoneField;
    let ants = [];
    let foodSource = { x: 0, y: 0, active: false };
    let nest = { x: 0, y: 0 };
    let statsEl = document.getElementById('stats');

    // Constants (Tuning parameters)
    const PHEROMONE_DECAY = 0.98;
    const MAX_PHEROMONE = 100;
    const ANT_SPEED = 2;
    const FOOD_FOUND_RADIUS = 50;

    // --- Initialization and Resizing ---

    function init() {
        width = window.innerWidth;
        height = window.innerHeight;
        canvas.width = width;
        canvas.height = height;

        pheromoneField = document.createElement('canvas');
        pheromoneField.width = width;
        pheromoneField.height = height;
        const pCtx = pheromoneField.getContext('2d');
        pCtx.fillStyle = '#000';
        pCtx.fillRect(0, 0, width, height);

        nest = { x: width * 0.15, y: height * 0.8 };
        foodSource.x = width * 0.85;
        foodSource.y = height * 0.2;
        foodSource.active = true;

        // Initialize ants (randomly placed near the nest)
        ants = Array(10).fill(0).map(() => ({
            x: nest.x + Math.random() * 10 - 5,
            y: nest.y + Math.random() * 10 - 5,
            angle: Math.random() * Math.PI * 2,
            speed: ANT_SPEED,
            carryingFood: false,
        }));

        // Start the loop
        if (window.animationFrameId) cancelAnimationFrame(window.animationFrameId);
        gameLoop();
    }

    window.addEventListener('resize', () => {
        width = window.innerWidth;
        height = window.innerHeight;
        canvas.width = width;
        canvas.height = height;
        pheromoneField.width = width;
        pheromoneField.height = height;
        // Resetting state might be too disruptive, just resize the visual area for simplicity here.
    });

    // --- Classes/Objects Definition ---

    class Ant {
        constructor(x, y) {
            this.x = x;
            this.y = y;
            this.angle = Math.random() * Math.PI * 2;
            this.speed = ANT_SPEED;
            this.carryingFood = false;
            this.state = 'wandering'; // wandering, seeking, returning
        }

        update(pCtx) {
            let targetX, targetY;
            const pheromoneInfluence = calculatePheromones(this);

            if (this.carryingFood) {
                // State: Returning to nest
                this.state = 'returning';
                targetX = nest.x;
                targetY = nest.y;
            } else if (!foodSource.active || Math.hypot(this.x - foodSource.x, this.y - foodSource.y) > FOOD_FOUND_RADIUS * 1.5) {
                // State: Wandering/Seeking Food
                this.state = 'wandering';
            } else {
                // State: Seeking Food Source
                this.state = 'seeking';
                targetX = foodSource.x;
                targetY = foodSource.y;
            }

            let desiredAngle;

            if (this.state === 'returning') {
                desiredAngle = Math.atan2(nest.y - this.y, nest.x - this.x);
            } else if (this.state === 'seeking') {
                // Move towards food source until close enough
                const dist = Math.hypot(targetX - this.x, targetY - this.y);
                if (dist < 10) {
                    this.carryingFood = true; // Picked up
                    this.state = 'returning';
                    return;
                }
                desiredAngle = Math.atan2(targetY - this.y, targetX - this.x);
            } else {
                // State: Wandering (Random walk biased by pheromone)
                let bestInfluence = 0;
                let biasAngle = this.angle;

                for (let i = 0; i < 8; i++) {
                    const angle = Math.PI * 2 * (i / 8);
                    const testX = this.x + Math.cos(this.angle + angle) * 15;
                    const testY = this.y + Math.sin(this.angle + angle) * 15;

                    // Check pheromone strength near the potential path
                    const pValue = getPheromoneStrength(testX, testY);
                    if (pValue > bestInfluence) {
                        bestInfluence = pValue;
                        biasAngle = this.angle + angle;
                    }
                }
                desiredAngle = biasAngle;

                // If no strong pheromone found, default to random walk change
                if (Math.random() < 0.1) desiredAngle += Math.PI * Math.random() * 2;
            }

            // Steer towards the target angle
            const angleDiff = desiredAngle - this.angle;
            this.angle = this.angle + Math.min(Math.abs(angleDiff), Math.PI) * (0.15); // Smoothing factor

            // Movement
            this.x += Math.cos(this.angle) * this.speed;
            this.y += Math.sin(this.angle) * this.speed;

            // Boundary check
            if (this.x < 0 || this.x > width || this.y < 0 || this.y > height) {
                this.x = Math.max(0, Math.min(width, this.x));
                this.y = Math.max(0, Math.min(height, this.y));
            }

            // Deposit Pheromone (Always deposit when moving)
            depositPheromone(this.x, this.y);
        }
    }

    // --- Simulation Logic Functions ---

    function calculatePheromones(ant) {
        let px = Math.floor(ant.x / 5) * 5;
        let py = Math.floor(ant.y / 5) * 5;
        return getPheromoneStrength(px, py);
    }

    function getPheromoneStrength(x, y) {
        if (x < 0 || x > width || y < 0 || y > height) return 0;
        let px = Math.floor(Math.max(0, Math.min(width - 1, x)));
        let py = Math.floor(Math.max(0, Math.min(height - 1, y)));
        // Simple lookup using the pheromone data array (conceptual)
        return pheromoneField[py][px] || 0;
    }

    function depositPheromone(x, y) {
        let px = Math.floor(Math.max(0, Math.min(width - 1, x)));
        let py = Math.floor(Math.max(0, Math.min(height - 1, y)));

        if (pheromoneField[py] && pheromoneField[py][px]) {
            // Increase pheromone strength at this grid point
            pheromoneField[py][px] = Math.min(MAX_PHEROMONE, pheromoneField[py][px] + 1);
        }
    }

    function clearPheromones() {
        for (let y = 0; y < height; y++) {
            for (let x = 0; x < width; x++) {
                // Decay: Multiply by decay factor
                if (pheromoneField[y][x] > 0) {
                    pheromoneField[y][x] *= PHEROMONE_DECAY;
                } else {
                     pheromoneField[y][x] = 0;
                }
            }
        }
    }

    function drawPheromones(pCtx) {
        // Render the entire grid, simulating diffusion/blurring effect
        for (let y = 0; y < height; y++) {
            for (let x = 0; x < width; x++) {
                const strength = pheromoneField[y][x];
                if (strength > 0.1) {
                    // Color based on concentration: stronger = brighter/more red
                    const alpha = Math.min(1, strength / MAX_PHEROMONE);
                    ctx.fillStyle = `rgba(255, 100, 0, ${alpha * 0.5})`;
                    ctx.fillRect(x, y, 1, 1);
                }
            }
        }
    }

    function updateStats() {
        let totalFoodCarried = ants.filter(a => a.carryingFood && a.state === 'returning').length;
        statsEl.innerHTML = `Ants: ${ants.length} | Food Carried: ${totalFoodCarried}`;
    }

    // --- Main Loop ---

    let pheromoneField = []; // Initialize the 2D array for pheromones (Must be done before update loop)
    for (let y = 0; y < height; y++) {
        pheromoneField[y] = new Array(width).fill(0);
    }


    function gameLoop() {
        // 1. Clear and Decay Pheromones
        clearPheromones();

        // 2. Update Ant positions and deposit pheromone
        ants.forEach(ant => ant.update(ctx));

        // 3. Draw Results (Canvas must be cleared before redrawing background elements)
        ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'; // Subtle trail decay effect
        ctx.fillRect(0, 0, width, height);
        drawPheromones(ctx);

        // 4. Draw Nest and Food Source (Visual anchors)
        ctx.fillStyle = 'rgb(50, 200, 50)'; // Green for Nest
        ctx.beginPath();
        ctx.arc(nest.x, nest.y, 15, 0, Math.PI * 2);
        ctx.fill();

        ctx.fillStyle = 'rgb(255, 100, 0)'; // Orange for Food
        if (foodSource.active) {
            ctx.beginPath();
            ctx.arc(foodSource.x, foodSource.y, 10, 0, Math.PI * 2);
            ctx.fill();
        }

        // 5. Draw Ants
        ants.forEach(ant => {
            ctx.fillStyle = ant.carryingFood ? 'red' : 'white';
            ctx.beginPath();
            ctx.arc(ant.x, ant.y, 2, 0
mistral-small:24bBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ant Colony Simulation</title>
<style>body{margin:0;display:flex;justify-content:center;align-items:center;height:100vh;background:#f0f0f0;}canvas{border:2px solid #000;}</style>
</head>
<body>
<canvas id="antCanvas" width="800" height="600"></canvas>
<script>
const cvs=document.getElementById('antCanvas');
const ctx=cvs.getContext('2d');
const ants=[];
const nest={x:400,y:570};
const foodSource={x:400,y:30};
let pheromoneField=new Array(800).fill().map(()=>new Array(600).fill(0));
const antCountEl=document.createElement('div');
antCountEl.style.position='absolute';
antCountEl.style.top='10px';
antCountEl.style.left='10px';
document.body.appendChild(antCountEl);
let foodCarried=0;
function createAnt(){
    ants.push({x:nest.x,y:nest.y,target:Math.random()>0.5?foodSource:nest,direction:{x:Math.random()-.5,y:Math.random()-.5}});
}
function drawPheromone(){
ctx.fillStyle='rgba(255,0,0,.3)';
for(let x=0;x<800;x++){
    for(let y=0;y<600;y++){
        if (pheromoneField[x][y]>0){
            ctx.fillRect(x,y,1,1);
        }
    }
}
}
function evaporatePheromone(){
for(let x=0;x<800;x++){
    for(let y=0;y<600;y++){
        pheromoneField[x][y]*=.95;
    }
}
}
function depositPheromone(x,y){
if (pheromoneField[x][y]<255) {
    pheromoneField[x][y]+=10;
}
}
function updateAnts(){
for(let ant of ants){
    const target=ant.target==foodSource?foodSource:nest;
    if (Math.abs(ant.x-target.x)<1&&Math.abs(ant.y-target.y)<1){if(target==nest && ant.direction.x===undefined) {foodCarried++; antCountEl.innerHTML=`Food Carried: ${foodCarried}`;} ant.target=target==foodSource?nest:foodSource;}
    let dx=target.x-ant.x;
    let dy=target.y-ant.y;
    if(Math.random()<.1){
        dx+=Math.random()-.5;
        dy+=Math.random()-.5;
    }
    const speed=2;
    ant.x+=dx/speed;
    ant.y+=dy/speed;
    depositPheromone(Math.round(ant.x),Math.round(ant.y));
}
}
function drawAnts(){
for(let ant of ants){
    ctx.fillStyle='black';
    ctx.beginPath();
    ctx.arc(ant.x,ant.y,2,0,Math.PI*2);
    ctx.fill();
}
}
function update(){
ctx.clearRect(0,0,cvs.width,cvs.height);
drawPheromone();
updateAnts();
evaporatePheromone();
drawAnts();
if (ants.length<10) createAnt();
requestAnimationFrame(update);
}
createAnt();
update();
</script>
</body>
</html>
```
qwen3:8bharness
No answer reached us (ERR) — and the reason lies with our setup, not with the model: reasoning consumed the entire token budget and the answer stayed empty; the gateway rejects budgets above 3000 tokens Counted as a did-not-finish, but it is not evidence about this model.
qwq:32bERRBLANKLIMFORMAT
Show code
<think>

Alright, I need to create an HTML file that simulates an ant colony using a canvas. The user wants it self-contained, so all the code has to be in one file. Let me break down the requirements step by step.

First, the basic structure: I'll start with the HTML5 doctype, then a canvas element. The JavaScript will handle everything else. The key components are the ants, the pheromone trails, the nest, and the food source. 

The ants should start at the nest, wander around, and follow pheromones. When an ant finds food, it should return to the nest, leaving a trail. The pheromones need to evaporate over time, so that old paths fade away. The user also wants the count of ants and food carried home to be displayed. 

I'll need to use requestAnimationFrame for smooth animation. The simulation should start immediately and can be restarted by reloading the page. No external libraries, so everything in vanilla JS.

Let me think about the canvas setup. The canvas will draw the pheromone grid and the ants. The ants can be represented as objects with properties like position, direction, and whether they are carrying food. 

The pheromone field should be a 2D array (or a 1D array for efficiency) where each cell tracks the pheromone level. When an ant moves and is returning to the nest, it deposits pheromone along its path. Over time, each cell's pheromone decreases slightly each frame. 

For the random walk biased towards pheromones: when an ant moves, it has a random direction, but also tends towards areas with higher pheromone levels. Maybe the direction is adjusted based on the surrounding pheromone levels. Alternatively, when choosing a new direction, the ant is more likely to go towards higher concentrations. 

The food source can be a fixed point outside the nest, maybe positioned randomly each time. Or fixed coordinates? The user says "a fresh random instance when finished," so maybe on page load, the food position is randomized each time. Wait, the user says the simulation should keep running, but when finished? Maybe they meant that the simulation restarts when the food is all collected? Wait, the user says "starts immediately and keeps running (restart with a fresh random instance when finished)". Hmm, perhaps the simulation runs until some condition (like all food is gone), then restarts. Alternatively, maybe it just runs indefinitely, but when you want a new instance, you refresh the page. The wording is a bit unclear. Maybe I'll make it so that after a certain amount of time, or when the food is depleted, it resets the simulation. Let me check the requirements again.

The user wants the simulation to start immediately and keep running, but when finished, a fresh instance starts. So after finishing one run, it restarts. But what defines "finished"? Maybe after a certain time or when all food is collected. Maybe the food is a fixed amount, and when that's carried back, the simulation restarts. Alternatively, it could just loop continuously, but that's not really a restart. Hmm, perhaps I'll set a timer, say after 10 seconds, then reset everything. Alternatively, when the food reaches 0, reset. Let me think about that.

Alternatively, the user might not want a hard stop, but just have it continuously running. The "finished" part might be a misunderstanding. Maybe the user wants the simulation to automatically restart after some time, so that each time you load the page or refresh, it's a new instance. 

Anyway, proceeding with the components:

1. Canvas and context setup.
2. Pheromone grid: a 2D array, but in JS, using a 1D array for efficiency. Let's say the grid is the same size as the canvas, but maybe smaller to reduce computation. Wait, the canvas can be 400x400. If we use a grid size of, say, 20x20, each cell covers 20 pixels. So the grid is 20 units each way, so 400 pixels. That way, 20x20 grid. That might be manageable.

Wait, but the ants can be at any pixel, but pheromone is in cells. So maybe the grid is smaller than the canvas to reduce computation. Maybe the grid is 40x40 (so each cell is 10x10 pixels). That way, 400/10=40. So grid of 40x40. That's manageable.

3. Ants: Each ant has a position (x,y), direction (angle), and a food flag. When an ant is carrying food, it turns around and heads back to the nest, depositing pheromone along the way. 

4. Nest is at the center, food is at a random position. Maybe the nest is at (200,200), and the food is placed somewhere else, but randomly each time. Or fixed? The user says "fresh random instance", so probably when the simulation restarts, the food is placed randomly again.

5. Pheromone evaporation: each frame, the pheromone level of each cell decreases by a small percentage. Maybe 0.95 per frame (so 5% loss per frame). Or a fixed amount.

6. The ants' movement: each frame, the ant moves in a direction, which is adjusted based on the current pheromone levels in the surrounding cells. The direction is a vector that is a combination of a random component and a direction towards higher pheromones. 

Alternatively, when moving, the ant looks at the neighboring cells (like looking in front and to the sides) and tends to move towards areas with higher pheromones. Maybe using a gradient or something simple.

Wait, perhaps the direction is updated each step. The ant's current direction is adjusted based on the pheromone concentration in the direction they are currently moving. If there's more pheromone ahead, they continue; else, turn a bit. Or, perhaps the direction is randomly chosen with a bias towards higher pheromones.

Alternatively, the movement can be a random walk with a slight bias towards areas with higher pheromone. So, for each step, the ant calculates the average pheromone in a direction, and chooses a direction that has higher pheromone. 

Hmm, maybe a simpler approach: the direction is a vector that is a combination of a random direction plus a direction towards the highest pheromone in the nearby cells. Or, the direction is perturbed towards higher pheromones.

Alternatively, the ant has a direction, and each step it can turn a little left or right (like a random walk with some bias). The bias could be towards higher pheromone concentrations.

Alternatively, the direction is adjusted such that the ant has a tendency to follow the direction of higher pheromone in the immediate vicinity.

Hmm, perhaps each step, the ant moves forward, but each step adds a small random angle to their direction, but also adds a direction towards the pheromone.

Alternatively, the direction is updated based on the pheromone in the current cell or adjacent cells.

This might be a bit involved. Maybe a better approach is to, for each ant, when moving, calculate the direction based on the surrounding pheromone levels.

Alternatively, the ant moves with a random walk, but when pheromone is present in the vicinity, it has a higher chance to move in that direction.

Alternatively, the random walk is a step in a random direction, but multiplied by some bias based on pheromone.

Alternatively, the ant's direction is a vector, and each step it is adjusted by adding a small random vector and a vector in the direction of the strongest pheromone in the neighboring cells.

Hmm, perhaps for simplicity, the ant's direction is slightly random, but if there's a pheromone trail, the direction is adjusted towards it.

Alternatively, the movement algorithm could be:

- The ant moves forward at a certain speed.

- The direction is a vector that is a combination of a random direction (some noise) plus a direction towards areas with higher pheromone.

- The pheromone direction is calculated by looking at the surrounding grid cells and choosing the direction towards the highest pheromone in the nearby area.

Hmm, perhaps for each ant, when moving, we compute the gradient of pheromone in their vicinity. For example, look at the pheromone levels in the current cell and cells ahead/left/right? Not sure, but this might get computationally heavy.

Alternatively, the ant can look at the current cell's pheromone and the next cell's pheromone in the direction they're moving. If the next cell has more pheromone, continue in that direction; else, turn slightly. 

Alternatively, the direction is a vector that is perturbed by a random amount, but also influenced by pheromone gradients.

This is getting complicated. Maybe a simpler approach is better. Let me think of the code structure:

First, variables:

- canvas, ctx.

- pheromone array: grid of size say 40x40 (each cell is 10 px, for 400x400 canvas).

- ants array.

- nest position (fixed at center)

- food position (random position each time).

- foodCarried counter.

- antCount.

- maybe parameters like pheromone evaporation rate, ant count, etc.

Let me start coding step by step.

First, the HTML:

<html><body><canvas id="c"></canvas><script> ... </script></body></html>

Now, inside the script:

var c = document.getElementById('c');
var ctx = c.getContext('2d');

Set the canvas size:

c.width = 400;
c.height = 400;

Then, setup variables for the simulation:

var gridX = 40, gridY = 40; // 40x40 grid
var dx = c.width / gridX; //10 px per cell
var dy = c.height / gridY;

var pheromone = new Array(gridX*gridY); // flat array for grid

var ants = [];
var antCount = 50; // start with 50 ants
var maxAnts = 50; // reset to this each time?

Wait, but the user wants to show the count, so maybe the count can vary? Or it's fixed.

Wait the user says "ant count and the food carried home" to be shown. Maybe the count is the number of ants currently in the simulation, but since they respawn? Not sure. The instructions say "no user input, starts immediately and keeps running (restart with a fresh random instance when finished)". Maybe when the simulation finishes (e.g., food is gone), it restarts, resetting all parameters including ant count and food.

Hmm. Let me think: perhaps each time the simulation starts, the ants are created at the nest, food is placed randomly, and when all food is collected, the simulation restarts with new positions and ants. But how to track that?

Alternatively, the food is infinite, so the simulation runs forever, but that doesn't fit with "restart when finished". So maybe after a certain time (e.g., 20 seconds), the simulation restarts with a new setup. Alternatively, when food reaches zero, reset.

Alternatively, the food is a single source with a certain amount, say 1000 units. Each ant that reaches the food reduces it, and when it's gone, reset.

But the user didn't specify, so perhaps the simplest is to have a single food source, and when an ant reaches it, it turns around and returns to nest, leaving pheromone. The food count is just tracked as a number.

Hmm, perhaps the food is a point, and when an ant reaches within a certain radius, it "collects" food and turns back. The food is in a fixed or random position each time.

Wait, the user says "when one finds a food source it returns to the nest depositing pheromone along the way". So the food is a point, and ants can only find it by reaching it. So each time an ant reaches the food, it turns around. The food doesn't deplete, but the pheromone trail builds up.

Wait, but the user also wants to show "food carried home", so maybe each time an ant goes to the food and back, it carries some food, and the total is accumulated. So the food count is the total number of times ants have made a successful round trip.

Alternatively, each ant can carry one unit, so when they return, they add to the food count. To prevent infinite counts, maybe after returning, they go back to wandering, so the count keeps increasing. But the user might just want the total ants that have returned, but the problem says "food carried home" so it's probably the total amount.

Alternatively, the food is a fixed amount, say 100 units. Each time an ant reaches the food, it takes one unit and returns, but when food reaches zero, the simulation restarts. But the user didn't specify, so maybe it's better to have the food just be a point, and the count is how many ants have successfully returned with food. But when they return, they can go again, so the count would be infinite. Hmm.

Alternatively, maybe each ant can only carry food once, then they stop. But that complicates things.

Alternatively, the food carried home is a counter that increments each time an ant returns to the nest having found food. So it's the total number of successful trips.

Okay, moving forward.

Variables:

var nestX = 200, nestY = 200;
var foodX, foodY; // initialized randomly

var foodTotal = 0;
var foodCarried = 0;

Wait, foodTotal is the amount remaining, maybe. Let's say the food is placed at a random position (not overlapping with nest), and has 100 units. When an ant reaches it, it takes one unit, so foodTotal decreases. When it's zero, restart. But maybe that's overcomplicating.

Alternatively, the food is a point, and when an ant reaches it (within some radius), they turn around and head back. The foodCarried is the number of ants that have done this. 

Hmm, perhaps the simplest is to have the food as a point, and whenever an ant reaches it, it turns around and heads back, leaving pheromone. The foodCarried is just the count of how many ants have done this. 

So each ant has a 'hasFood' flag. When an ant moves, if they are near the food and !hasFood, they turn around and set hasFood to true, adding to foodCarried.

Now, the ants' initial positions: they start at the nest. So when the simulation starts, all ants are at nestX,nestY. But to avoid clustering, maybe they have random initial directions.

Each ant object might look like:

{
  x: nestX,
  y: nestY,
  angle: Math.random() * Math.PI*2,
  speed: 1,
  hasFood: false
}

Wait, but ants might need to move towards the nest when they have food. So their direction should be towards the nest.

Hmm. Let me structure the ant's properties:

Each ant has:

- current x,y position.

- direction (angle).

- speed.

- hasFood flag.

When hasFood is false: moving with a direction influenced by pheromones and random walk.

When hasFood is true: moving directly towards the nest, with a different speed (maybe faster? Or same).

Additionally, when moving, if they have food, they leave pheromone along the path.

Wait, the user says "when one finds a food source it returns to the nest depositing pheromone along the way". So during the return trip, they leave pheromone.

So, when hasFood is true, each step, they move towards nest, and deposit pheromone at their path.

Also, when they arrive at the nest (within some radius), they drop off the food (so hasFood becomes false again?), but then continue their random walk.

Wait, perhaps when they return to the nest, they reset their hasFood to false, and are now seeking food again. So they can go back and forth.

Thus, the foodCarried is the total number of times ants have returned with food. But that would keep increasing infinitely, so maybe the user just wants to show the total collected, which can be a counter that increments each time an ant returns to the nest with food.

Now, the pheromone: each cell in the grid holds a value. When an ant is moving towards the nest (hasFood is true), they add pheromone to their current cell.

Wait, but pheromone is deposited along the path. So each step, when moving, if hasFood is true, add to the current cell's pheromone?

Alternatively, every time the ant moves, if they have food, deposit pheromone. But when returning, maybe deposit more? Or just deposit when returning, and not when searching.

Hmm, the standard approach in ant algorithms is that ants leave pheromone on their way back to the nest after finding food. So, only when returning, they leave pheromone.

Therefore, each step when hasFood is true, the ant deposits some pheromone at their current position. Additionally, the pheromone evaporates every frame.

But how much to deposit? Maybe a small amount each step. The evaporation is a decay, so each cell's pheromone is multiplied by (1 - evapRate) each frame.

Now, the pheromone grid: each cell has a value. To access it, given an x,y on the canvas, we can compute the grid cell as:

var gx = Math.floor(x / dx);
var gy = Math.floor(y / dy);
var idx = gy * gridX + gx;

So, for any position, get the grid index.

When an ant moves, during their step, if they have food, they add to the current cell's pheromone.

But also, when searching (not having food), their movement is influenced by the pheromone. So their direction is influenced by the surrounding pheromone levels.

Wait, how to implement the direction change based on pheromone.

Ants use a form of pathing where they follow higher pheromone trails. So when moving, they might turn towards areas of higher pheromone.

Alternatively, each step, the ant picks a new direction based on the current pheromone levels in their vicinity.

Alternatively, the ant has a certain randomness in their direction, but weighted towards higher pheromone areas.

This could be complex. Maybe a simpler approach is to have the ant's direction be slightly altered by the pheromone in their current cell.

Alternatively, each time the ant moves, their direction is adjusted by a random amount, but biased towards the direction of higher pheromone.

Alternatively, for simplicity, the ants' direction changes by a small random amount each step, but when in a cell with higher pheromone, the random 'noise' is smaller, making them follow the trail.

Alternatively, perhaps the pheromone affects their turning rate.

This is getting a bit too involved. Maybe for simplicity, the ants have a random walk, but when they have food, they leave pheromone, and when they don't have food, they may be more likely to follow higher pheromone paths.

Alternatively, the direction of the ant is influenced by the average pheromone in the neighboring cells. For example, if the current cell has pheromone, the ant continues in the same direction, otherwise, it turns.

Alternatively, each step, the ant's direction is adjusted by a random angle, but the standard deviation of the random angle is inversely proportional to the current pheromone level.

Hmm, this is getting too complicated for the scope here.

Maybe a simpler way: each step, the ant moves forward in their current direction. If they don't have food, they might turn slightly left or right, but if there's a higher pheromone in one direction, they are more likely to turn towards it.

Alternatively, let's make it so that when the ant is not carrying food, their direction is influenced by the pheromone in their current cell. For example, if the current cell has pheromone, they continue straight; else, they turn a random angle.

Alternatively, the ant's direction is a random walk with a certain turning rate, but when in a cell with higher pheromone, the turning rate is lower (so they go straight more).

Alternatively, the turning angle is selected with a probability that depends on the pheromone.

This is getting too complex. Let me think of a simple way.

Perhaps for simplicity, ants have a base turning rate, say turning by a random angle between -0.1 and 0.1 radians each step. But when they are in a cell with higher pheromone, the turning rate is reduced, so they are more likely to continue straight.

Alternatively:

Each step:

- if hasFood: move directly towards nest.

- else:

   - look at current cell's pheromone.

   - turn by random angle plus some bias based on pheromone.

Alternatively, when not carrying food, the direction is a random walk with some noise, but the direction is biased toward areas with higher pheromone.

Alternatively, the direction change is influenced by the sum of pheromone from surrounding cells.

Alternatively, the direction is chosen based on the direction of the highest pheromone in a small radius around the ant.

Alternatively, the ant's direction is calculated as the average direction of the pheromone in a local area.

Hmm. To save time, perhaps just have the ants move in a random direction with a small turning step, but when going to collect food, they follow the pheromone trail.

Alternatively, perhaps it's easier to have the ants when not carrying food, their direction is determined by the current pheromone level in their cell. For example, if they are on a cell with pheromone, they continue in that direction, else, they turn randomly.

Alternatively, perhaps the ants have a tendency to continue in the same direction unless the current cell's pheromone is low, in which case they turn more.

Alternatively, just make the ants have a random walk, but when they have found food, they leave pheromone, and over time, the pheromone builds up, so more ants follow that path.

Even if the movement isn't explicitly dependent on pheromone (except for the returning ants leaving pheromone), the pheromone buildup can emerge from the returning ants, and possibly other ants will follow.

Wait, maybe that's sufficient. Let me proceed:

Each ant has a direction and speed.

When moving:

If hasFood:

   move towards nest, with direction pointing to nest.

   deposit pheromone each step.

Else:

   move in current direction with some random turn.

   every so often, if in a cell with higher pheromone, adjust direction.

Alternatively, just random walk for non-food ants.

To implement this:

In each step:

for each ant in ants:

  if (hasFood):

    // move towards nest

    let dx = nestX - ant.x;

    let dy = nestY - ant.y;

    let dist = Math.sqrt(dx*dx + dy*dy);

    if (dist < 1) { // reached nest

      hasFood = false;

      foodCarried++;

      // reset position? Or just continue?

      // maybe reset direction randomly?

    }

    // direction towards nest

    let angle = Math.atan2(dy, dx);

    ant.x += ant.speed * Math.cos(angle);

    ant.y += ant.speed * Math.sin(angle);

    // deposit pheromone

    depositPheromone(ant.x, ant.y);

  else:

    // move in current direction with some random turn

    ant.angle += Math.random()*0.3 - 0.15; // random turn between -0.15 and +0.15 radians

    // move forward

    ant.x += ant.speed * Math.cos(ant.angle);

    ant.y += ant.speed * Math.sin(ant.angle);

    // check if found food

    let dxFood = foodX - ant.x;

    let dyFood = foodY - ant.y;

    if (dxFood*dxFood + dyFood*dyFood < 100) { // within radius 10

      hasFood = true;

      // start heading back

    }

    // check boundaries? Maybe wrap around?

    // or bounce?

    // maybe not necessary for simplicity.

Wait, but the ants might go outside the canvas. So perhaps when they go outside, they reverse direction or something, but to keep it simple, let them move freely.

Now, the pheromone deposit function:

function depositPheromone(x,y){

   var gx = Math.floor(x/dx);

   var gy = Math.floor(y/dy);

   if(gx <0 || gx >= gridX || gy <0 || gy >= gridY) return;

   var idx = gy * gridX + gx;

   pheromone[idx] += 0.5;

}

And every frame, the pheromone evaporates:

for(var i =0; i < gridX*gridY; i++){

   pheromone[i] *= 0.99; // 1% evaporation

}

Now, the food position is set randomly each time the simulation restarts.

But when does the simulation restart? According to the user's instruction, it should "restart with a fresh random instance when finished". So perhaps after a certain amount of time or when the food is sufficiently used?

Alternatively, when the foodCarried reaches a certain number, but the user didn't specify.

Alternatively, the simulation runs indefinitely, but that doesn't fit "restart when finished".

Hmm, maybe the food position is randomized each time the simulation restarts, but how to trigger a restart?

Alternatively, each time the simulation starts, it runs for a certain number of steps, then restarts with new positions.

Alternatively, perhaps the user just wants a continuous simulation with the food in a fixed position, but that's not clear.

Alternatively, the problem is to create a simulation where ants start at the nest, food is placed somewhere, and ants move around, leaving pheromone on their way back, forming a path. The user wants to show the ant count and food carried home. The ants continue indefinitely, so the simulation doesn't "finish", hence perhaps the "restart when finished" is a red herring, or maybe it's a typo and the simulation should just run continuously.

Given the problem statement is a bit ambiguous here, I'll proceed with a continuous simulation where the food is placed in a fixed position (randomly chosen at initialization) and the simulation runs forever, updating the counts.

Now, putting it all together.

Initialize variables:

var c = document.getElementById('c');
var ctx = c.getContext('2d');
c.width = 400;
c.height = 400;

var gridX = 40, gridY =40;
var dx = c.width/gridX, dy = c.height/gridY;

var pheromone = new Array(gridX*gridY);
for(var i=0; i<gridX*gridY; i++) pheromone[i]=0;

var nestX=200, nestY=200;
var foodX = Math.random()*c.width; // random position
var foodY = Math.random()*c.height;
// ensure not too close to nest?

var ants = [];
var antCount = 50; // number of ants
for(var i=0; i<antCount; i++){
  ants.push({
    x: nestX,
    y: nestY,
    angle: Math.random()*Math.PI*2,
    speed: 1.5,
    hasFood: false
  });
}

var foodCarried =0;

function update(){
  // update pheromone
  for(var i=0; i<gridX*gridY; i++){
    pheromone[i] *= 0.99;
  }

  // update ants
  for(var i=0; i<ants.length; i++){
    var ant = ants[i];

    if(ant.hasFood){

      // move towards nest
      var dx = nestX - ant.x;
      var dy = nestY - ant.y;
      var dist = Math.hypot(dx, dy);

      if(dist < 1){
        ant.hasFood = false;
        foodCarried++;
        // random direction on returning
        ant.angle = Math.random()*Math.PI*2;
        // maybe add some pheromone here too?
        depositPheromone(ant.x, ant.y);
      }

      var angle = Math.atan2(dy, dx);
      ant.x += ant.speed * Math.cos(angle);
      ant.y += ant.speed * Math.sin(angle);

      depositPheromone(ant.x, ant.y);

    }else{

      // move in current direction with random turn
      ant.angle += (Math.random()-0.5)*0.3; // random turn between -0.15 and +0.15 radians

      ant.x += ant.speed * Math.cos(ant.angle);
      ant.y += ant.speed * Math.sin(ant.angle);

      // check distance to food
      var dxFood = foodX - ant.x;
      var dyFood = foodY - ant.y;
      if(dxFood*dxFood + dyFood*dyFood < 100){
        ant.hasFood = true;
      }

      // check boundaries? Maybe wrap around
      if(ant.x <0) ant.x += c.width;
      if(ant.x > c.width) ant.x -= c.width;
      if(ant.y <0) ant.y += c.height;
      if(ant.y > c.height) ant.y -= c.height;
    }
  }
}

function draw(){
  ctx.fillStyle = '#fff';
  ctx.fillRect(0,0,c.width,c.height);

  // draw pheromone
  ctx.fillStyle = 'rgba(0,0,255,0.5)';
  for(var gy=0; gy<gridY; gy++){
    for(var gx=0; gx<gridX; gx++){
      var idx = gy*gridX + gx;
      var val = pheromone[idx];
      if(val>0.1){
        ctx.fillRect(gx*dx, gy*dy, dx, dy);
      }
    }
  }

  // draw nest
  ctx.fillStyle = 'green';
  ctx.beginPath();
  ctx.arc(nestX, nestY, 10,0, Math.PI*2);
  ctx.fill();

  // draw food
  ctx.fillStyle = 'red';
  ctx.beginPath();
  ctx.arc(foodX, foodY, 10,0, Math.PI*2);
  ctx.fill();

  // draw ants
  ctx.fillStyle = 'black';
  for(var i=0; i<ants.length; i++){
    var ant = ants[i];
    ctx.fillRect(ant.x-2, ant.y-2,4,4);
  }

  // display counts
  ctx.fillStyle = 'black';
  ctx.fillText('Food carried: '+foodCarried, 10,20);
  ctx.fillText('Ant count: '+ants.length,10,40);
}

function loop(){
  update();
  draw();
  requestAnimationFrame(loop);
}

function depositPheromone(x,y){
  var gx = Math.floor(x/dx);
  var gy = Math.floor(y/dy);
  if(gx<0 || gx>=gridX || gy <0 || gy >= gridY) return;
  var idx = gy*gridX + gx;
  pheromone[idx] += 0.5;
}

// Initialize and start
loop();

This should create a simulation where ants start at the nest, explore randomly, and when they find the food (a red circle), they carry it back to the nest (green), leaving a blue trail (pheromone). The foodCarried count increases each time an ant returns.

The simulation runs indefinitely, so the "restart when finished" part may need clarification, but given the problem statement, this should suffice.

Now, let me check for any possible errors in the code.

First, in the depositPheromone function, the grid calculation is correct.

In the ant's movement:

When an ant has food, it moves towards the nest. The angle is calculated correctly with atan2(dy, dx), which gives the angle from the ant's position to the nest.

When reaching the nest (distance <1), it resets hasFood and increases the count. The angle is randomized to give a new direction upon returning, which makes sense.

For ants without food, they turn randomly by +/- 0.15 radians, which is a moderate turn.

The boundary checks wrap the ants around the screen, which is okay for simplicity.

The pheromone decay is 1% per frame, so it dissipates slowly.

The drawing code draws pheromone cells only if val>0.1, which is arbitrary but works.

The food position is set once, but maybe it should be randomized each restart. Since the simulation doesn't restart, perhaps that's okay.

Testing this code in a browser's console would be needed, but as a conceptual solution, it should work.
deepseek-r1:32bOKFORMAT
Show code
```html
<!DOCTYPE html><meta charset="utf-8"><canvas id=c></canvas><div id=d style="position:absolute;top:10px;color:white"></div>
<script>
const canvas = document.getElementById('c'), ctx = canvas.getContext('2d');
const width = 500, height = 340;
canvas.width = width; canvas.height = height;

let ants = [], food = 0, running = true;
 const nestX=width/2,nestY=height/2,speed=.7,pheromoneStrength=10,evaporationRate=0.98,searchRadius=30,foodProbability=.005,numAnts=30;

class Ant {
constructor() {this.reset()}
reset() {this.x = nestX; this.y = nestY; this.vx=0; this.vy=0; this.searching=true}
}

for(let i=0;i<numAnts;i++) ants.push(new Ant());

let pheromones = Array.from({length:width}, ()=>Array(height).fill(0));

function update() {
    if(!running) return;
    ctx.fillStyle='#123'; ctx.fillRect(0,0,width,height);
    
    // Draw nest
    ctx.fillStyle='rgba(0,255,0,.4)';
    ctx.beginPath(); ctx.arc(nestX,nestY,10,0,Math.PI*2); ctx.fill();
    
    // Update ants
    for(let ant of ants) {
        if(ant.searching) {
            // Move towards higher pheromones or random direction
            let dirX=0,dirY=0;
            for(let dx=-searchRadius;dx<=searchRadius;dx++) {
                for(let dy=-searchRadius;dy<=searchRadius;dy++) {
                    if(dx*dx+dy*dy>searchRadius*searchRadius) continue;
                    let x=Math.floor(ant.x+dx), y=Math.floor(ant.y+dy);
                    if(x>=0 &&x<width && y>=0 &&y<height) {
                        dirX += (pheromones[x][y] || 1)*(Math.sign(dx));
                        dirY += (pheromones[x][y] || 1)*(Math.sign(dy));
                    }
                }
            }
            ant.vx = (dirX + Math.random() - .5)*.2;
            ant.vy = (dirY + Math.random() - .5)*.2;
            
            // Move
            ant.x += ant.vx * speed;
            ant.y += ant.vy * speed;
            
            // Check for food
            if(Math.random()<foodProbability) {
                ant.searching=false;
                food++;
            }
        } else {
            // Return to nest with pheromone trail
            let dx = nestX - ant.x, dy = nestY - ant.y;
            ant.vx = (dx/10)/5; // Direction towards nest
            ant.vy = (dy/10)/5;
            
            ant.x += ant.vx * speed*2;
            ant.y += ant.vy * speed*2;
            
            let x1 = Math.floor(ant.x), y1=Math.floor(ant.y);
            if(x1>=0 &&x1<width && y1>=0 && y1<height) pheromones[x1][y1] += pheromoneStrength;
        }
        
        // Keep ants inside canvas
        ant.x = Math.max(0, Math.min(width-1, ant.x));
        ant.y = Math.max(0, Math.min(height-1, ant.y));
    }
    
    // Evaporate pheromones
    for(let x=0;x<width;x++) {
        for(let y=0;y<height;y++) {
            if(pheromones[x][y] > 0) pheromones[x][y] *= evaporationRate;
        }
    }
    
    // Draw ants
    ctx.fillStyle='rgba(255,192,0,.8)';
    for(let ant of ants) {
        ctx.beginPath();
        ctx.arc(ant.x, ant.y, 3, 0, Math.PI*2);
        ctx.fill();
    }
    
    // Draw pheromone field
    ctx.fillStyle='rgb(255, 94, 67)';
    for(let x=0;x<width;x++) {
        for(let y=0;y<height;y++) {
            if(pheromones[x][y] > 0) {
                let a = pheromones[x][y]/10;
                ctx.fillStyle = 'rgba(255, 94, 67, '+a+')';
                ctx.fillRect(x,y,1,1);
            }
        }
    }
    
    // Update stats
    document.getElementById('d').textContent = `Ants: ${ants.length}\nFood Delivered: ${food}`;
}

function animate() {
    update();
    requestAnimationFrame(animate);
}
animate();

// Restart when done (dummy condition)
setTimeout(() => {
    running=false;
    for(let ant of ants) ant.reset();
    pheromones = Array.from({length:width}, ()=>Array(height).fill(0));
    food=0;
    running=true;
}, 10000);
</script>
```
command-r:35bOK
Show code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ant Colony Simulation</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
        canvas {
            width: 100vw;
            height: 100vh;
        }
    </style>
</head>
<body>
    <canvas id="simulation"></canvas>

    <script>
        const canvas = document.getElementById('simulation');
        const ctx = canvas.getContext('2d');

        let ants = [];
        let foodSources = [];
        let pheromoneField = [];
        let antCount = 50;
        let foodFound = 0;

        function createAnt() {
            return {
                x: Math.random() * canvas.width,
                y: Math.random() * canvas.height,
                angle: Math.random() * 2 * Math.PI,
                speed: 1 + Math.random() * 2,
                pheromoneLevel: 0,
                findFood() {
                    this.angle = this.getAngleTo(foodSources[Math.floor(Math.random() * foodSources.length)]);
                },
                getAngleTo(target) {
                    const dx = target.x - this.x;
                    const dy = target.y - this.y;
                    return Math.atan2(dy, dx);
                }
            };
        }

        function createFoodSource() {
            return {
                x: Math.random() * canvas.width,
                y: Math.random() * canvas.height
            };
        }

        function generatePheromoneField() {
            pheromoneField = Array.from({ length: canvas.width }, () => Array(canvas.height).fill(0));
        }

        function updatePheromoneField() {
            for (let i = 0; i < ants.length; i++) {
                const ant = ants[i];
                pheromoneField[Math.floor(ant.x)][Math.floor(ant.y)] += ant.pheromoneLevel * 5;
            }

            for (let x = 0; x < canvas.width; x++) {
                for (let y = 0; y < canvas.height; y++) {
                    pheromoneField[x][y] -= 0.1; // Evaporation rate
                }
            }
        }

        function drawPheromoneField() {
            ctx.fillStyle = 'rgba(255, 0, 0, 0.3)';

            for (let x = 0; x < canvas.width; x++) {
                for (let y = 0; y < canvas.height; y++) {
                    if (pheromoneField[x][y] > 0) {
                        ctx.fillRect(x, y, 1, 1);
                    }
                }
            }
        }

        function drawAnts() {
            for (let i = 0; i < ants.length; i++) {
                const ant = ants[i];

                ctx.save();
                ctx.translate(ant.x, ant.y);
                ctx.rotate(ant.angle - Math.PI / 2); // Rotate to align with the angle

                if (ant.pheromoneLevel > 0) {
                    ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
                    ctx.fillRect(-3, -10, 6, 4);
                } else {
                    ctx.fillStyle = '#00FF00'; // Green for ants without pheromone
                    ctx.beginPath();
                    ctx.arc(0, -8, 4, 0, 2 * Math.PI);
                    ctx.fill();
                }

                ctx.restore();
            }
        }

        function updateAnts() {
            for (let i = 0; i < ants.length; i++) {
                const ant = ants[i];

                // Update pheromone level based on food found
                if (ant.pheromoneLevel > 0) {
                    ant.pheromoneLevel -= 0.1; // Evaporation rate
                } else if (foodFound > 0) {
                    ant.pheromoneLevel = 1; // Full pheromone level when returning with food
                    foodFound--; // Decrement carried food count
                }

                // Move the ant based on its angle and speed
                ant.x += Math.cos(ant.angle) * ant.speed;
                ant.y += Math.sin(ant.angle) * ant.speed;

                if (ant.x < 0 || ant.x >= canvas.width || ant.y < 0 || ant.y >= canvas.height) {
                    // If the ant goes out of bounds, teleport it to a random location near the nest
                    ant.x = Math.random() * 10 + canvas.width / 2 - 5;
                    ant.y = Math.random() * 10 + canvas.height / 2 - 5;
                }

                // Bias movement towards food sources based on pheromone levels
                for (let j = 0; j < foodSources.length; j++) {
                    const food = foodSources[j];
                    const dx = food.x - ant.x;
                    const dy = food.y - ant.y;
                    const distance = Math.sqrt(dx * dx + dy * dy);

                    if (distance > 10) continue; // Ignore far away food sources

                    const angleToFood = Math.atan2(dy, dx);
                    ant.angle += (angleToFood - ant.angle) / 8;
                }
            }
        }

        function drawStats() {
            ctx.font = '16px Arial';
            ctx.fillStyle = '#FFFFFF'; // White text color

            ctx.fillText(`Ants: ${ants.length}`, 20, 20);
            ctx.fillText(`Food Found: ${foodFound}`, 20, 40);
        }

        function init() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;

            generatePheromoneField();

            for (let i = 0; i < antCount; i++) {
                ants.push(createAnt());
            }

            setInterval(() => {
                foodSources.push(createFoodSource());

                // Remove old/out of bounds food sources
                foodSources = foodSources.filter(food => {
                    return food.x > 0 && food.x < canvas.width && food.y > 0 && food.y < canvas.height;
                });
            }, 2000);

            update();
        }

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

            drawPheromoneField();
            drawAnts();
            updatePheromoneField();
            updateAnts();
            drawStats();

            requestAnimationFrame(update);
        }

        init();
    </script>
</body>
</html>
Outside the Brain cluster — same task, same character budget, collected through their own tooling (response times not comparable)
GPT-5.5 (Codex)OKMINIFIED
Show code
<!doctype html><html><head><meta charset=utf-8><title>Ant Colony</title><style>html,body{margin:0;height:100%;background:#10130f;overflow:hidden;color:#e8e0c8;font:15px system-ui}canvas{display:block;width:100vw;height:100vh}#h{position:fixed;left:12px;top:10px;background:#0008;padding:7px 10px;border-radius:6px}</style></head><body><canvas id=c></canvas><div id=h></div><script>
let C=c.getContext('2d'),W,H,GW=120,GH=80,S,P,A,N,F,home,food,left;
function R(a=1){return Math.random()*a}function reset(){W=c.width=innerWidth;H=c.height=innerHeight;S=Math.min(W/GW,H/GH);P=new Float32Array(GW*GH);N={x:W*.23,y:H*.5,r:22};F={x:W*(.62+R(.25)),y:H*(.2+R(.6)),r:28};home=0;food=190;left=0;A=[];for(let i=0;i<95;i++)A.push({x:N.x+R(10)-5,y:N.y+R(10)-5,a:R(6.28),v:1.2+R(.9),q:0})}
function at(x,y){let gx=x/S|0,gy=y/S|0;return gx<0||gy<0||gx>=GW||gy>=GH?0:gy*GW+gx}
function sniff(a,o){let d=24,x=a.x+Math.cos(a.a+o)*d,y=a.y+Math.sin(a.a+o)*d;return P[at(x,y)]||0}
function step(a){let dx,dy,d;if(a.q){dx=N.x-a.x;dy=N.y-a.y;d=Math.hypot(dx,dy);a.a=Math.atan2(dy,dx)+(R()-.5)*.55;let k=at(a.x,a.y);P[k]=Math.min(255,P[k]+8);if(d<N.r){a.q=0;home++;left--;a.a+=3.14+R(1)-.5}}else{let l=sniff(a,-.65),m=sniff(a,0),r=sniff(a,.65);a.a+=(r-l)*.006+(R()-.5)*.65+(m<2?(R()-.5)*.25:0);dx=F.x-a.x;dy=F.y-a.y;d=Math.hypot(dx,dy);if(food>0&&d<F.r){a.q=1;food--;left++;a.a=Math.atan2(N.y-a.y,N.x-a.x)}}a.x+=Math.cos(a.a)*a.v;a.y+=Math.sin(a.a)*a.v;if(a.x<2||a.x>W-2){a.a=Math.PI-a.a;a.x=Math.max(2,Math.min(W-2,a.x))}if(a.y<2||a.y>H-2){a.a=-a.a;a.y=Math.max(2,Math.min(H-2,a.y))}}
function draw(){C.fillStyle='#10130f';C.fillRect(0,0,W,H);for(let i=0;i<P.length;i++){P[i]*=.996;if(P[i]>.7){let x=i%GW*S,y=(i/GW|0)*S,a=Math.min(.7,P[i]/150);C.fillStyle='rgba(72,194,105,'+a+')';C.fillRect(x,y,S+1,S+1)}}let g=C.createRadialGradient(N.x,N.y,4,N.x,N.y,N.r*2);g.addColorStop(0,'#e9d18b');g.addColorStop(1,'#7d5b2400');C.fillStyle=g;C.beginPath();C.arc(N.x,N.y,N.r*2,0,7);C.fill();C.fillStyle='#d0a44e';C.beginPath();C.arc(N.x,N.y,N.r,0,7);C.fill();C.fillStyle=food?'#7ee06b':'#293828';C.beginPath();C.arc(F.x,F.y,F.r,0,7);C.fill();C.fillStyle='#cfff8c';C.font='12px system-ui';C.textAlign='center';C.fillText(food,F.x,F.y+4);for(const a of A){step(a);C.save();C.translate(a.x,a.y);C.rotate(a.a);C.fillStyle=a.q?'#f4cf53':'#1b120b';C.beginPath();C.ellipse(0,0,4,2.4,0,0,7);C.fill();C.fillStyle='#090604';C.beginPath();C.arc(4,0,2,0,7);C.fill();C.restore()}h.textContent='ants '+A.length+'   food carried home '+home;if(food<=0&&!left)setTimeout(reset,700)}
function loop(){draw();requestAnimationFrame(loop)}onresize=reset;reset();loop();
</script></body></html>
Show code
<!DOCTYPE html><html><head><meta charset=utf8><title>Ants</title><style>
html,body{margin:0;background:#0c0c10;overflow:hidden}
canvas{display:block}
#u{position:fixed;top:8px;left:8px;color:#8f8;font:13px monospace;text-shadow:0 0 4px #000}
</style></head><body>
<canvas id=c></canvas><div id=u></div>
<script>
(function(){
var W,H,cols,rows,cs=8,c=document.getElementById('c'),x=c.getContext('2d'),u=document.getElementById('u');
var nest,food,pf,ph,ants,carried,tick;
function init(){
 W=c.width=innerWidth;H=c.height=innerHeight;
 cols=Math.ceil(W/cs);rows=Math.ceil(H/cs);
 pf=new Float32Array(cols*rows);ph=new Float32Array(cols*rows);
 nest={x:W*0.5,y:H*0.5};
 food={x:Math.random()*W*0.8+W*0.1,y:Math.random()*H*0.8+H*0.1};
 while(Math.hypot(food.x-nest.x,food.y-nest.y)<Math.min(W,H)*0.35){
  food={x:Math.random()*W*0.8+W*0.1,y:Math.random()*H*0.8+H*0.1};
 }
 ants=[];
 var n=80+Math.floor(Math.random()*40);
 for(var i=0;i<n;i++)ants.push({x:nest.x,y:nest.y,a:Math.random()*6.28,st:0});
 carried=0;tick=0;
}
function idx(px,py){
 var cx=px/cs|0,cy=py/cs|0;
 if(cx<0||cy<0||cx>=cols||cy>=rows)return -1;
 return cy*cols+cx;
}
function sense(px,py,ang,grid){
 var i=idx(px+Math.cos(ang)*cs*2,py+Math.sin(ang)*cs*2);
 return i<0?-1:grid[i];
}
function step(){
 tick++;
 for(var i=0;i<pf.length;i++){pf[i]*=0.99;ph[i]*=0.99;}
 var ni=idx(nest.x,nest.y);if(ni>=0)ph[ni]=250;
 var fi=idx(food.x,food.y);if(fi>=0)pf[fi]=250;
 for(var k=0;k<ants.length;k++){
  var a=ants[k],grid=a.st?ph:pf;
  var dl=sense(a.x,a.y,a.a-0.5,grid),dc=sense(a.x,a.y,a.a,grid),dr=sense(a.x,a.y,a.a+0.5,grid);
  var turn=(Math.random()-0.5)*0.6;
  if(dl>dc&&dl>dr)turn-=0.35;else if(dr>dc&&dr>dl)turn+=0.35;
  a.a+=turn;
  a.x+=Math.cos(a.a)*1.7;a.y+=Math.sin(a.a)*1.7;
  if(a.x<0){a.x=0;a.a=3.14-a.a;}
  if(a.x>W){a.x=W;a.a=3.14-a.a;}
  if(a.y<0){a.y=0;a.a=-a.a;}
  if(a.y>H){a.y=H;a.a=-a.a;}
  var di=idx(a.x,a.y);
  if(di>=0){if(a.st)pf[di]=Math.min(250,pf[di]+35);else ph[di]=Math.min(250,ph[di]+35);}
  if(!a.st){
   if(Math.hypot(a.x-food.x,a.y-food.y)<10){a.st=1;a.a+=3.14;}
  }else{
   if(Math.hypot(a.x-nest.x,a.y-nest.y)<10){a.st=0;a.a+=3.14;carried++;}
  }
 }
}
function draw(){
 x.fillStyle='#0c0c10';x.fillRect(0,0,W,H);
 for(var cy=0;cy<rows;cy++){
  for(var cx=0;cx<cols;cx++){
   var i=cy*cols+cx,v1=pf[i],v2=ph[i];
   if(v1<1&&v2<1)continue;
   x.fillStyle='rgba('+Math.min(255,v1*1.2|0)+','+Math.min(255,v2*1.2|0)+',50,0.55)';
   x.fillRect(cx*cs,cy*cs,cs,cs);
  }
 }
 x.fillStyle='#5cf';x.beginPath();x.arc(nest.x,nest.y,11,0,6.3);x.fill();
 x.fillStyle='#fc5';x.beginPath();x.arc(food.x,food.y,8,0,6.3);x.fill();
 for(var k=0;k<ants.length;k++){
  var a=ants[k];
  x.fillStyle=a.st?'#ffdd66':'#fff';
  x.fillRect(a.x-1.5,a.y-1.5,3,3);
 }
 u.textContent='Ants: '+ants.length+'   Food carried: '+carried;
}
function loop(){
 step();draw();
 if(tick>3600)init();
 requestAnimationFrame(loop);
}
init();loop();
})();
</script></body></html>
Show code
<!DOCTYPE html><html><head><title>Ant Colony</title></head><body style="margin:0;background:#000;display:flex;justify-content:center;align-items:center;height:100vh"><canvas id="c"></canvas><div id="i" style="position:absolute;top:10px;left:10px;color:#ff8;font-family:mono;font-size:10px"></div><script>
const c=document.getElementById('c'),x=c.getContext('2d'),i=document.getElementById('i');c.width=c.height=400;
const w=400,h=400,gs=10,ph=Array(gs*gs).fill(0);let ants=[],food=0;
for(let j=0;j<50;j++){ants.push({x:w/2+Math.random()*20-10,y:h/2+Math.random()*20-10,dx:Math.random()-0.5,dy:Math.random()-0.5,carry:0});}
const fx=350,fy=150;
function d(){x.fillStyle='#000';x.fillRect(0,0,w,h);for(let j=0;j<ph.length;j++)ph[j]*=0.95;x.fillStyle='#440';x.fillRect(fx-10,fy-10,20,20);for(let a of ants){if(Math.hypot(a.x-fx,a.y-fy)<15){a.carry=1;}if(Math.hypot(a.x-w/2,a.y-h/2)<15&&a.carry){food++;a.carry=0;}const px=Math.floor(a.x/gs),py=Math.floor(a.y/gs);if(px>=0&&px<gs&&py>=0&&py<gs){const idx=py*gs+px;ph[idx]+=1;if(a.carry===0&&Math.random()<0.1){const nx=Math.floor((w/2-a.x)*0.001),ny=Math.floor((h/2-a.y)*0.001);a.dx=a.dx*0.9+nx*0.1;a.dy=a.dy*0.9+ny*0.1;}else if(a.carry===0){a.dx+=Math.random()-0.5;a.dy+=Math.random()-0.5;const len=Math.hypot(a.dx,a.dy);if(len>0){a.dx/=len;a.dy/=len;}}else{a.dx=(fx-a.x)*0.01;a.dy=(fy-a.y)*0.01;}}a.x+=a.dx;a.y+=a.dy;a.x=Math.max(0,Math.min(w,a.x));a.y=Math.max(0,Math.min(h,a.y));}for(let j=0;j<gs;j++){for(let k=0;k<gs;k++){x.fillStyle=`rgba(255,128,0,${Math.min(ph[j*gs+k]*0.1,0.8)})`;x.fillRect(k*10,j*10,10,10);}}x.fillStyle='#0f0';for(let a of ants)x.fillRect(a.x-1,a.y-1,2,2);i.textContent=`Ants: ${ants.length} | Food: ${food}`;}(function a(){d();requestAnimationFrame(a);})();
</script></body></html>
Results at a glance— every model in this round with score, response time and status.

Who wrote what

ModelBlind scoreLatencyStatus
gemma4:26b harness
qwen3.5:9b 35.1 sOK
llama3.1:8b 117.6 sOK
qwen3-coder:30b 38.6 sOK
deepseek-r1:14b 34.9 sOK
qwen3:14b 40.6 sOK
mistral-small:24b 117.9 sOK
qwen3:8b harness
qwq:32b 234.1 sOK
deepseek-r1:32b 85.9 sOK
command-r:35b 152.1 sOK