Overview › Code › R71
Code · blind round

R71 · Flood fill on a pixel grid

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.

A frontier reference answered the same task (Claude Opus 5) — outside the field and deliberately unscored, further down the page.

Show task
Create ONE self-contained HTML file (STRICT LIMIT: max 120 lines total) that animates a flood fill on a 60x40 grid of coloured cells drawn on a <canvas>. Generate a few random blobs of colour, pick a start cell, and expand the fill one frontier step at a time so the growing region is clearly visible. Show the number of cells filled and the current frontier size. 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)
mistral-small:24bOKFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Flood Fill Animation</title>
    <style>
        canvas { border: 1px solid black; }
        #stats { position: absolute; top: 10px; left: 10px; color: white; font-size: 20px; }
    </style>
</head>
<body style="background-color: black;">
    <canvas id="canvas" width="600" height="400"></canvas>
    <div id="stats">Filled: 0, Frontier: 0</div>

<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const gridWidth = 60;
const gridHeight = 40;
const cellSize = 10;

let floodFillQueue = [];
let filledCells = new Set();
let frontierSize = 0;
let filledCount = 0;

function drawGrid() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    for (let x = 0; x < gridWidth; x++) {
        for (let y = 0; y < gridHeight; y++) {
            const color = Math.random() * 256 >> 0;
            ctx.fillStyle = `rgb(${color},${color},${color})`;
            ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
        }
    }
}

function getRandomColor() {
    return `rgb(${Math.random() * 256 >> 0},${Math.random() * 256 >> 0},${Math.random() * 256 >> 0})`;
}

function floodFill(x, y) {
    if (x < 0 || x >= gridWidth || y < 0 || y >= gridHeight || filledCells.has(`${x},${y}`)) return;

    const color = `rgb(${Math.random() * 256 >> 0},${Math.random() * 256 >> 0},${Math.random() * 256 >> 0})`;
    ctx.fillStyle = color;
    ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);

    filledCells.add(`${x},${y}`);
    floodFillQueue.push([x-1,y]);
    floodFillQueue.push([x+1,y]);
    floodFillQueue.push([x,y-1]);
    floodFillQueue.push([x,y+1]);
}

function animate() {
    if (floodFillQueue.length === 0) {
        setTimeout(() => {
            location.reload();
        }, 500);
        return;
    }

    frontierSize = floodFillQueue.length;

    const [x, y] = floodFillQueue.shift();
    floodFill(x,y);

    filledCount++;
    updateStats();

    requestAnimationFrame(animate);
}

function updateStats() {
    document.getElementById('stats').innerText = `Filled: ${filledCount}, Frontier: ${frontierSize}`;
}

drawGrid();
floodFillQueue.push([Math.floor(Math.random() * gridWidth), Math.floor(Math.random() * gridHeight)]);
requestAnimationFrame(animate);
</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.
qwen3:14bSTATLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Flood Fill Animation</title>
    <style>body { background: #111; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; flex-direction: column;} canvas { border: 2px solid #444; }</style>
</head>
<body>
    <canvas id="grid"></canvas>
    <div id="stats">Filled Cells: 0 | Frontier Size: 0</div>

    <script>
        const canvas = document.getElementById('grid');
        const ctx = canvas.getContext('2d');
        const GRID_W = 60;
        const GRID_H = 40;
        canvas.width = GRID_W * 8;
        canvas.height = GRID_H * 8;

        let grid = [];
        let startX, startY;
        let queue = [];
        let isAnimating = false;

        function initializeGrid() {
            grid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(null));
            for (let y = 0; y < GRID_H; y++) {
                for (let x = 0; x < GRID_W; x++) {
                    grid[y][x] = '#000'; // Default background color
                }
            }

            const blobsToDraw = Math.floor(Math.random() * 3) + 2;
            for (let i = 0; i < blobsToDraw; i++) {
                let startX_b = Math.floor(Math.random() * GRID_W);
                let startY_b = Math.floor(Math.random() * GRID_H);
                let color = `hsl(${Math.random() * 360}, 70%, ${Math.random() * 40 + 50}%)`;
                const blobSize = Math.max(1, Math.floor(Math.random() * 8) + 2);

                for (let dy = -blobSize; dy <= blobSize; dy++) {
                    for (let dx = -blobSize; dx <= blobSize; dx++) {
                        const x = startX_b + dx;
                        const y = startY_b + dy;

                        if (x >= 0 && x < GRID_W && y >= 0 && y < GRID_H) {
                            grid[y][x] = color;
                        }
                    }
                }
            }

            // Pick a random starting cell that is not the background color
            do {
                startX = Math.floor(Math.random() * GRID_W);
                startY = Math.floor(Math.random() * GRID_H);
            } while (grid[startY][startX] === null || grid[startY][startX].startsWith('#000'));

            queue = [ { x: startX, y: startY } ];
        }

        function drawGrid() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            for (let y = 0; y < GRID_H; y++) {
                for (let x = 0; x < GRID_W; x++) {
                    ctx.fillStyle = grid[y][x];
                    ctx.fillRect(x * 8, y * 8, 8, 8);
                }
            }
        }

        function animateStep() {
            if (queue.length === 0) {
                isAnimating = false;
                document.getElementById('stats').innerHTML = 'Flood Fill Complete!';
                setTimeout(() => { initializeGrid(); requestAnimationFrame(gameLoop); }, 1500);
                return;
            }

            const nextQueue = [];
            let frontierCoords = [];
            let filledCount = 0;

            // Process the current queue (the cells to fill in this step)
            for (let i = 0; i < queue.length; i++) {
                const { x, y } = queue[i];
                if (!grid[y][x].startsWith('#FILL')) {
                    grid[y][x] = '#FILL'; // Mark as filled
                    filledCount++;
                }

                // Check neighbors for the new frontier
                const neighbors = [[0, 1], [0, -1], [1, 0], [-1, 0]];
                for (let [dx, dy] of neighbors) {
                    const nx = x + dx;
                    const ny = y + dy;

                    if (nx >= 0 && nx < GRID_W && ny >= 0 && ny < GRID_H && grid[ny][nx].startsWith('#BLOB') && !grid[ny][nx].startsWith('#FILL')) {
                        frontierCoords.push({ x: nx, y: ny });
                    }
                }
            }

            // Update queue and draw
            queue = frontierCoords;
            drawGrid();

            const frontierSize = queue.length;
            document.getElementById('stats').innerHTML = `Filled Cells: ${filledCount} | Frontier Size: ${frontierSize}`;

            if (isAnimating) {
                requestAnimationFrame(gameLoop);
            }
        }

        function gameLoop() {
            animateStep();
        }

        // Start the animation immediately
        initializeGrid();
        requestAnimationFrame(gameLoop);
    </script>
</body>
</html>
```
qwen3.5:9bSTATLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head>
<title>Flood Fill Animation</title>
<style>body {background:#111;display:flex;justify-content:center;align-items:center;min-height:100vh;margin:0;color:white;}canvas {border:2px solid #333;}</style>
</head>
<body>
<canvas id="canvas" width="60"*50" height="40"*50"></canvas>

<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let GRID_W = 60;
let GRID_H = 40;
let CELL_SIZE = 50 / 60; // Scale down slightly for fit

// Grid state: 0=Empty, 1=Target Color, 2=Filled
let grid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(0));
let colorGrid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(null));

function randomColor() {
    const letters = '0123456789ABCDEF';
    let color = '#';
    for (let i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

function initializeGrid() {
    grid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(0));
    colorGrid = Array(GRID_H).fill(0).map(() => Array(GRID_W).fill(null));
    const numBlobs = 5;
    let filledCount = 0;

    for (let i = 0; i < numBlobs; i++) {
        let startX = Math.floor(Math.random() * GRID_W);
        let startY = Math.floor(Math.random() * GRID_H);
        let color = randomColor();

        for (let y = 0; y < GRID_H; y++) {
            for (let x = 0; x < GRID_W; x++) {
                if (!colorGrid[y][x] && Math.random() > 0.8) {
                    colorGrid[y][x] = color;
                    grid[y][x] = 1; // Mark as colored cell
                }
            }
        }
    }
    // Select a target starting point (a random colored cell)
    let startY, startX;
    do {
        startY = Math.floor(Math.random() * GRID_H);
        startX = Math.floor(Math.random() * GRID_W);
    } while (!colorGrid[startY][startX]);

    return { startX, startY, targetColor: colorGrid[startY][startX] };
}

let state = initializeGrid();
let isRunning = true;

function drawGrid(filledCells) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    for (let y = 0; y < GRID_H; y++) {
        for (let x = 0; x < GRID_W; x++) {
            const color = colorGrid[y][x];
            ctx.fillStyle = color || '#111';
            ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE - 0.5, CELL_SIZE - 0.5);

            if (grid[y][x] === 2) { // Filled state indicator
                ctx.strokeStyle = 'rgba(0, 150, 255, 0.8)';
                ctx.lineWidth = 3;
                ctx.strokeRect(x * CELL_SIZE + 1, y * CELL_SIZE + 1, CELL_SIZE - 2, CELL_SIZE - 2);
            }
        }
    }

    // Draw the current frontier (cells about to be filled)
    if (filledCells && filledCells.length > 0) {
        ctx.fillStyle = 'rgba(0, 255, 0, 0.6)';
        for (const [y, x] of filledCells) {
             ctx.fillRect(x * CELL_SIZE + 1, y * CELL_SIZE + 1, CELL_SIZE - 2, CELL_SIZE - 2);
        }
    }
}

function animateFill() {
    if (!isRunning) return;

    let startY = state.startY;
    let startX = state.startX;
    const targetColor = state.targetColor;
    const frontier = new Set(); // Stores [y, x] coordinates for the next step
    const visited = new Set(); // Tracks cells already in queue or processed

    // Initial setup: Queue for BFS/Frontier search
    let currentQueue = [[startY, startX]];
    frontier.add([startY, startX]);
    visited.add(`${startY},${startX}`);
    
    // Optimization: Instead of full BFS every step, we maintain the frontier boundary explicitly
    // To keep complexity down for line count, we use a simplified queue-based expansion.

    let currentFrontier = [[startY, startX]];
    let filledCount = 1;
    let maxSteps = GRID_W * GRID_H * 0.2; // Limit steps to prevent infinite loop/slowness

    // We need a loop structure that processes step-by-step and updates the state object
    if (state._currentStep === undefined) {
        state._currentQueue = [[startY, startX]];
        state._visited = new Set([`${startY},${startX}`]);
        state._fillCount = 1;
    }

    let queue = state._currentQueue || [];
    let newlyFilledFrontier = [];
    
    if (queue.length > 0) {
        const nextQueue = [];
        
        for (const [y, x] of queue) {
            // Check neighbors (N, S, E, W)
            [[0, 1], [0, -1], [1, 0], [-1, 0]].forEach(([dy, dx]) => {
                let ny = y + dy;
                let nx = x + dx;

                if (ny >= 0 && ny < GRID_H && nx >= 0 && nx < GRID_W) {
                    const key = `${ny},${nx}`;
                    // Check if it matches the target color, is not filled, and hasn't been processed
                    if (!state._visited.has(key) && colorGrid[ny][nx] === targetColor) {
                        newlyFilledFrontier.push([ny, nx]);
                        nextQueue.push([ny, nx]);
                        state._visited.add(key);
                    }
                }
            });
        }
        
        if (newlyFilledFrontier.length > 0) {
            // Process the step: Change state and update metrics
            const currentNeighbors = newlyFilledFrontier;
            
            currentNeighbors.forEach(([y, x]) => {
                grid[y][x] = 2; // Mark as filled
            });

            state._fillCount += newlyFilledFrontier.length;
            state._currentQueue = nextQueue;

            // Redraw with the new frontier
            drawGrid(newlyFilledFrontier);

            document.getElementById('stats').innerHTML = `Cells: ${state._fillCount} | Frontier: ${newlyFilledFrontier.length}`;
        } else {
             // Fill finished
             isRunning = false;
             document.getElementById('stats').innerHTML = `Finished! Total Cells Filled: ${state._fillCount}`;
        }
    }

    if (isRunning) {
        requestAnimationFrame(animateFill);
    }
}


// Initialization and setup for the first run/restart
function startAnimation() {
    const statsDiv = document.createElement('div');
    statsDiv.id = 'stats';
    statsDiv.style.position = 'absolute';
    statsDiv.style.top = '20px';
    statsDiv.style.left = '50%';
    statsDiv.style.transform = 'translate(-50%, 0)';
    statsDiv.style.fontSize = '24px';
    document.body.appendChild(statsDiv);

    // Reset state for fresh run
    state = initializeGrid();
    state._currentQueue = [];
    state._visited = new Set();
    state._fillCount = 0;

    drawGrid(null); // Clear and draw initial colors
    document.getElementById('stats').innerText = "Starting Animation...";
    animateFill();
}

startAnimation();
</script>

<div id="stats" style="position: absolute; top: 20px; left: 50%; transform: translate(-50%, 0); font-size: 24px;"></div>

</body>
</html>
```
llama3.1:8bSTATFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flood Fill Animation</title>
</head>
<body>
    <canvas id="grid" width="600" height="400"></canvas>
    <script>
        const canvas = document.getElementById('grid');
        const ctx = canvas.getContext('2d');
        let grid = Array(40).fill().map(() => Array(60).fill(null));
        let frontier = [];
        let filled = 0;
        let step = 0;

        function drawGrid() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            for (let i = 0; i < grid.length; i++) {
                for (let j = 0; j < grid[0].length; j++) {
                    if (grid[i][j] !== null) {
                        ctx.fillStyle = grid[i][j];
                        ctx.fillRect(j * 10, i * 10, 10, 10);
                    }
                }
            }
        }

        function start() {
            for (let i = 0; i < 5; i++) {
                const x = Math.floor(Math.random() * 60);
                const y = Math.floor(Math.random() * 40);
                grid[y][x] = `hsl(${Math.random() * 360}, 100%, 50%)`;
            }
            grid[Math.floor(Math.random() * 40)][Math.floor(Math.random() * 60)] = 'black';
            drawGrid();
        }

        function floodFill(x, y) {
            if (x >= 0 && x < 60 && y >= 0 && y < 40 && grid[y][x] === null) {
                frontier.push([x, y]);
                grid[y][x] = 'black';
                filled++;
            }
        }

        function animate() {
            step++;
            ctx.fillStyle = 'white';
            ctx.font = '24px Arial';
            ctx.textAlign = 'left';
            ctx.textBaseline = 'top';
            ctx.fillText(`Filled: ${filled}, Frontier: ${frontier.length}`, 10, 10);

            for (let i = frontier.length - 1; i >= 0; i--) {
                const [x, y] = frontier[i];
                if (grid[y][x + 1] === null) floodFill(x + 1, y);
                if (grid[y + 1][x] === null) floodFill(x, y + 1);
                if (grid[y][x - 1] === null) floodFill(x - 1, y);
                if (grid[y - 1][x] === null) floodFill(x, y - 1);

                grid[y][x] = 'black';
                frontier.splice(i, 1);
            }

            drawGrid();
            requestAnimationFrame(animate);
        }
        start();
        animate();
    </script>
</body>
</html>
```
qwen3-coder:30bSTATLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head>
<title>Flood Fill Animation</title>
<style>
    body { background-color: #111; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }
    canvas { border: 1px solid #333; image-rendering: pixelated; }
    #info { color: white; font-family: monospace; position: absolute; top: 20px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.6); padding: 10px; border-radius: 5px;}
</style>
</head>
<body>

<canvas id="gameCanvas" width="600" height="400"></canvas>
<div id="info">Cells Filled: 0 | Frontier Size: 0</div>

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

    let GRID_WIDTH = 60;
    let GRID_HEIGHT = 40;
    let CELL_SIZE = 10;
    let grid = [];
    
    // Color constants
    const BACKGROUND_COLOR = [20, 20, 30]; // Dark background
    const BLOB_COLORS = ["#FF6B6B", "#4ECDC4", "#5F9EA0", "#8D6E63", "#A1C4FD"];

    let currentGridState;
    let startX, startY, targetColor;
    let queue = [];
    let running = false;
    let filledCount = 0;

    function initializeGrid() {
        grid = new Array(GRID_WIDTH).fill(0).map(() => new Array(GRID_HEIGHT).fill(null));

        // Initialize background (simulate an empty canvas)
        for (let x = 0; x < GRID_WIDTH; x++) {
            for (let y = 0; y < GRID_HEIGHT; y++) {
                grid[x][y] = BACKGROUND_COLOR.join(',');
            }
        }

        // Generate random blobs and set target color
        const blobCount = Math.floor(Math.random() * 3) + 2;
        let potentialTargetColor = null;

        for (let i = 0; i < blobCount; i++) {
            let startX_blob = Math.floor(Math.random() * GRID_WIDTH);
            let startY_blob = Math.floor(Math.random() * GRID_HEIGHT);
            let color = BLOB_COLORS[Math.floor(Math.random() * 5)];

            if (!potentialTargetColor) potentialTargetColor = color;

            // Draw a blob (filling connected area with the same random color)
            const tempBlobGrid = JSON.parse(JSON.stringify(grid));
            let queueBlob = [[startX_blob, startY_blob]];
            tempBlobGrid[startX_blob][startY_blob] = color;
            
            while (queueBlob.length > 0) {
                const [x, y] = queueBlob.shift();

                [[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]].forEach(([nx, ny]) => {
                    if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT && tempBlobGrid[nx][ny] === null) {
                        tempBlobGrid[nx][ny] = color;
                        queueBlob.push([nx, ny]);
                    }
                });
            }

            // Merge the blob into the main grid
            for (let x = 0; x < GRID_WIDTH; x++) {
                for (let y = 0; y < GRID_HEIGHT; y++) {
                    if (tempBlobGrid[x][y] !== null) {
                        grid[x][y] = tempBlobGrid[x][y];
                    }
                }
            }
        }

        // Select starting point and target color
        startX = Math.floor(Math.random() * GRID_WIDTH);
        startY = Math.floor(Math.random() * GRID_HEIGHT);
        targetColor = grid[startX][startY];

        // Reset state
        currentGridState = JSON.parse(JSON.stringify(grid));
        queue = [];
        filledCount = 0;
        running = true;
    }

    function drawGrid() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        for (let x = 0; x < GRID_WIDTH; x++) {
            for (let y = 0; y < GRID_HEIGHT; y++) {
                const color = currentGridState[x][y];
                ctx.fillStyle = color;
                ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
            }
        }
    }

    function updateCanvas() {
        // Draw the underlying grid state first
        drawGrid(); 
        
        // Highlight the current frontier cells (the queue)
        if (queue.length > 0) {
             ctx.strokeStyle = 'rgba(255, 255, 0, 0.8)';
             ctx.lineWidth = 3;
             for (const [x, y] of queue) {
                 ctx.strokeRect(x * CELL_SIZE + 1, y * CELL_SIZE + 1, CELL_SIZE - 2, CELL_SIZE - 2);
             }
        }

        // Update stats display
        infoDiv.innerHTML = `Cells Filled: ${filledCount} | Frontier Size: ${queue.length}`;
    }

    function findFrontier() {
        if (queue.length === 0) return [];
        let frontier = [];
        for(const [x, y] of queue) {
            [[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]].forEach(([nx, ny]) => {
                if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT) {
                    // Check if it's the target color and hasn't been processed/queued already
                    const cell = grid[nx][ny];
                    if (cell === targetColor && !queue.some(q => q[0] === nx && q[1] === ny)) {
                        frontier.push([nx, ny]);
                    }
                }
            });
        }
        return frontier;
    }

    function stepFloodFill() {
        if (!running) return;

        // 1. Update the queue with all potential next cells (the true frontier)
        let potentialFrontier = [];
        for(const [x, y] of queue) {
            [[x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]].forEach(([nx, ny]) => {
                if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT) {
                    const cell = grid[nx][ny];
                    // Only add valid target cells that are not already in the queue or filled
                    if (cell === targetColor && !queue.some(q => q[0] === nx && q[1] === ny)) {
                        potentialFrontier.push([nx, ny]);
                    }
                }
            });
        }

        // 2. Select a random cell from the frontier to fill (simulating guided growth)
        if (potentialFrontier.length === 0) {
             running = false; // Finished filling
             return;
        }
        const randomIndex = Math.floor(Math.random() * potentialFrontier.length);
        const [nextX, nextY] = potentialFrontier[randomIndex];

        // 3. Process the step: Fill and update queue/count
        if (currentGridState[nextX][nextY] === targetColor) {
            // Update state
            currentGridState[nextX][nextY] = '#00FFFF'; // Filled color
            filledCount++;

            // Add neighbors of the newly filled cell to the queue for the next step's frontier calculation
            [[nextX + 1, nextY], [nextX - 1, nextY], [nextX, nextY + 1], [nextX, nextY - 1]].forEach(([nx, ny]) => {
                if (nx >= 0 && nx < GRID_WIDTH && ny >= 0 && ny < GRID_HEIGHT) {
                    const neighborColor = grid[nx][ny];
                    // Only add viable candidates to the queue
                    if (neighborColor === targetColor && !queue.some(q => q[0] === nx && q[1] === ny)) {
                        queue.push([nx, ny]);
                    }
                }
            });

        } else {
             // Should not happen if logic is correct, but handles safety break
             running = false; 
             return;
        }
    }

    function animate() {
        if (running) {
            stepFloodFill();
            updateCanvas();
        } else {
            // Restart sequence when finished
            setTimeout(() => {
                initializeGrid();
                animate();
            }, 500); 
        }

        if (running) {
             requestAnimationFrame(animate);
        }
    }

    window.onload = () => {
        initializeGrid();
        // Initial draw before the animation starts
        drawGrid();
        updateCanvas();
        animate();
    };

</script>
</body>
</html>
```
deepseek-r1:14bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><title>Flood Fill Animation</title><style>canvas{border:solid 2px #000;margin:10px auto;display:block;}#stats{position:fixed;top:0;left:0;background:#fff;padding:5px;color:#000;font-family:Arial;text-align:center;}</style></head>
<body><h1>Flood Fill</h1><canvas id="c"></canvas><div id="stats">Filled: 0 | Frontier: 0</div>
<script>
const c = document.getElementById('c'), ctx=c.getContext('2d');
const GRID_W=60,GRID_H=40,COLS=8,ROWS=8;
let stats=document.getElementById('stats');
let grid=[],queue=[],currentColorIndex=0,filledCount=0;

function init(){
    grid=[];
    queue=[];
    currentColorIndex=0;
    filledCount=0;
    
    // Create random colored blobs
    const colors=['#FF6B6B','#4ECDC4','#45B7D1','#96CEB4','#FFEEAD','#D4A5A5','#CFCFCF','#8E8E8E'];
    for(let y=0;y<GRID_H;++y){
        grid[y]=[];
        for(let x=0;x<GRID_W;++x){
            grid[y][x]={
                color:colors[Math.floor(Math.random()*colors.length)],
                visited:false
            };
        }
    }
    
    // Generate some random regions
    const numBlobs=5;
    for(let i=0;i<numBlobs;++i){
        setupBlob();
    }
}

function setupBlob(){
    const x=Math.floor(Math.random()*(GRID_W-4)),y=Math.floor(Math.random()*(GRID_H-4));
    const size=20+Math.random()*20,angle=Math.random()*360;
    
    // Create a blob shape
    for(let dy=-size/2;dy<size/2;++dy){
        for(let dx=-size/2;dx<size/2;++dx){
            if(Math.sqrt(dx*dx+dy*dy)<size && Math.random()>0.5){
                const yIndex=y+Math.round(dy),xIndex=x+Math.round(dx);
                if(xIndex<GRID_W && xIndex>=0 && yIndex<GRID_H && yIndex>=0){
                    grid[yIndex][xIndex].color=colors[currentColorIndex];
                }
            }
        }
    }
    
    currentColorIndex++;
}

function update(){
    if(queue.length>0){
        const head=queue.shift();
        
        for(let [dx,dy] of [[-1,0],[1,0],[0,-1],[0,1]]){
            let nx=head.x+dx,ny=head.y+dy;
            if(nx>=0 && nx<GRID_W && ny>=0 && ny<GRID_H){
                if(!grid[ny][nx].visited){
                    grid[ny][nx].visited=true;
                    queue.push({x:ny,y:nx});
                    filledCount++;
                }
            }
        }
        
        stats.textContent=`Filled: ${filledCount} | Frontier: ${queue.length}`;
    }else{
        init();
    }
}

function draw(){
    ctx.clearRect(0,0,c.width,c.height);
    for(let y=0;y<GRID_H;++y){
        for(let x=0;x<GRID_W;++x){
            const cell=grid[y][x];
            ctx.fillStyle=cell.color;
            ctx.fillRect(x*COLS,y*ROWS,COLS-1,ROWS-1);
        }
    }
}

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

init();
animate();

</script></body></html>
```
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.
command-r:35bSTATLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flood Fill Animation</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f4f4f4;
        }
        canvas {
            border: 2px solid #333;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="600" height="400"></canvas>

    <script>
        const canvas = document.getElementById('myCanvas');
        const ctx = canvas.getContext('2d');
        
        let gridSize = 10; 
        let cellSize = canvas.width / gridSize;
        let cells = Array(gridSize).fill().map(() => Array(gridSize).fill()); // Grid of color codes

        function randomInt(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }
        
        function getRandomColor() {
            const letters = '0123456789ABCDEF';
            let color = '#';
            for (let i = 0; i < 6; i++) {
                color += letters[randomInt(0, 15)];
            }
            return color;
        }
        
        function drawGrid() {
            ctx.fillStyle = 'white';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            for (let x = -1; x < gridSize + 1; x++) {
                ctx.strokeStyle = '#eee';
                ctx.beginPath();
                ctx.moveTo(x * cellSize, 0);
                ctx.lineTo(x * cellSize, canvas.height);
                ctx.stroke();
            }
            
            for (let y = -1; y < gridSize + 1; y++) {
                ctx.strokeStyle = '#eee';
                ctx.beginPath();
                ctx.moveTo(0, y * cellSize);
                ctx.lineTo(canvas.width, y * cellSize);
                ctx.stroke();
            }
        }
        
        function drawCells() {
            for (let x = 0; x < gridSize; x++) {
                for (let y = 0; y < gridSize; y++) {
                    if (cells[x][y]) {
                        ctx.fillStyle = cells[x][y];
                        ctx.fillRect(x * cellSize + 1, y * cellSize + 1, cellSize - 2, cellSize - 2);
                    }
                }
            }
        }
        
        function floodFill(startX, startY, color) {
            const stack = [[startX, startY]];
            let frontierCount = 0;
            while (stack.length > 0) {
                const [x, y] = stack.pop();
                
                if (!cells[x][y]) {
                    ctx.fillStyle = color;
                    ctx.fillRect(x * cellSize + 1, y * cellSize + 1, cellSize - 2, cellSize - 2);
                    cells[x][y] = color;
                    frontierCount++;
                }
                
                if (x > 0 && !cells[x-1][y]) stack.push([x-1, y]);
                if (x < gridSize-1 && !cells[x+1][y]) stack.push([x+1, y]);
                if (y > 0 && !cells[x][y-1]) stack.push([x, y-1]);
                if (y < gridSize-1 && !cells[x][y+1]) stack.push([x, y+1]);
            }
            
            return frontierCount;
        }
        
        function animate() {
            const startColor = getRandomColor();
            let randomCells = [];
            for (let i = 0; i < 5; i++) {
                const color = getRandomColor();
                randomCells.push([randomInt(0, gridSize-1), randomInt(0, gridSize-1), color]);
                cells[randomCells[i][0]][randomCells[i][1]] = color;
            }
            
            let startCell = randomCells[Math.floor(Math.random() * randomCells.length)];
            const filledCountDisplay = document.createElement('p');
            filledCountDisplay.innerHTML = `Filled: 0, Frontier: ${floodFill(startCell[0], startCell[1], startColor)}`;
            canvas.parentNode.appendChild(filledCountDisplay);
            
            drawGrid();
            drawCells();

            let animationFrame = requestAnimationFrame(animate);
            
            function update() {
                const frontierSize = floodFill(startCell[0], startCell[1], startColor);
                filledCountDisplay.innerHTML = `Filled: ${cells.flat().filter(cell => cell).length}, Frontier: ${frontierSize}`;
                
                drawGrid();
                drawCells();

                if (frontierSize === 0) {
                    cancelAnimationFrame(animationFrame);
                    setTimeout(() => location.reload(), 1500); // Restart after a short delay
                } else {
                    animationFrame = requestAnimationFrame(update);
                }
            }
            
            update();
        }
        
        animate();
    </script>
</body>
</html>
```
deepseek-r1:32bBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head><style>canvas{border:1px solid black} #controls {position:absolute;top:0;right:0;padding:5px}</style></head>
<body>
<canvas id="grid" width="600" height="400"></canvas>
<div id="controls">
    Filled: <span id="filled">0</span><br>
    Frontier: <span id="frontier">0</span>
</div>
<script>
const canvas = document.getElementById('grid');
const ctx = canvas.getContext('2d');
const cellSize = 10;
const width = canvas.width / cellSize;
const height = canvas.height / cellSize;
let grid = [];
let frontier = [];
let colors = [];
let filling = false;
const iterationsPerFrame = 4;

class Color {
    constructor(r, g, b) { this.r = r; this.g = g; this.b = b; }
    static random() {
        return new Color(Math.random(), Math.random(), Math.random());
    }
}

function init() {
    grid = [];
    frontier = [];
    colors = [];
    const numBlobs = Math.floor(Math.random() * 5) + 1;
    for (let i = 0; i < numBlobs; i++) {
        const x = Math.floor(Math.random() * width);
        const y = Math.floor(Math.random() * height);
        colors.push(Color.random());
        grid[x + ',' + y] = { filled: true, colorIdx: colors.length - 1 };
    }
    if (colors.length === 0) colors.push(Color.random());
    let startX = Math.floor(Math.random() * width);
    let startY = Math.floor(Math.random() * height);
    while ((startX + ',' + startY) in grid) {
        startX = Math.floor(Math.random() * width);
        startY = Math.floor(Math.random() * height);
    }
    grid[startX + ',' + startY] = { filled: true, colorIdx: 0 };
    frontier.push({x: startX, y: startY});
    document.getElementById('filled').textContent = '1';
    document.getElementById('frontier').textContent = frontier.length;
    filling = true;
    requestAnimationFrame(animate);
}

function generateBlobs() {
    for (let i = 0; i < Math.floor(Math.random() * 5); i++) {
        const x = Math.floor(Math.random() * width);
        const y = Math.floor(Math.random() * height);
        if (!(x + ',' + y in grid)) {
            colors.push(Color.random());
            grid[x + ',' + y] = { filled: true, colorIdx: colors.length - 1 };
        }
    }
}

function drawGrid() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    // Draw background
    const bufferCanvas = document.createElement('canvas');
    const bufferCtx = bufferCanvas.getContext('2d');
    bufferCanvas.width = width * cellSize;
    bufferCanvas.height = height * cellSize;
    bufferCtx.fillStyle = '#ffffff';
    bufferCtx.fillRect(0, 0, bufferCanvas.width, bufferCanvas.height);
    
    // Draw initial blobs
    for (const [key, value] of Object.entries(grid)) {
        const [x, y] = key.split(',').map(Number);
        if (value.colorIdx !== undefined) {
            ctx.fillStyle = `rgb(${Math.floor(colors[value.colorIdx].r * 255)}, ${Math.floor(colors[value.colorIdx].g * 255)}, ${Math.floor(colors[value.colorIdx].b * 255)})`;
            ctx.fillRect(x * cellSize, y * cellSize, cellSize - 1, cellSize - 1);
        }
    }

    // Draw filled area
    bufferCtx.fillStyle = 'rgba(0,0,0,0.8)';
    for (const {x, y} of frontier) {
        const bufferX = x * cellSize;
        const bufferY = y * cellSize;
        bufferCtx.fillRect(bufferX, bufferY, cellSize - 1, cellSize - 1);
    }
    
    ctx.drawImage(bufferCanvas, 0, 0);

    // Debug info
    ctx.fillStyle = 'white';
    ctx.font = '12px Arial';
    ctx.fillText(`Filled: ${Object.keys(grid).length}`, 10, 20);
    ctx.fillText(`Frontier: ${frontier.length}`, 10, 35);
}

function animate() {
    if (!filling) return;
    for (let i = 0; i < iterationsPerFrame; i++) {
        if (frontier.length === 0) {
            filling = false;
            setTimeout(() => init(), 500);
            break;
        }
        const cell = frontier.shift();
        ctx.fillStyle = 'rgba(0,0,0,0.8)';
        ctx.fillRect(cell.x * cellSize, cell.y * cellSize, cellSize - 1, cellSize - 1);
        
        // Check neighbors
        for (let dx = -
qwq:32bSTAT
Show code
<think>

Okay, I need to create a self-contained HTML file that animates a flood fill on a 60x40 grid using a canvas. The user wants random blobs of color, a start cell, and the fill to expand step by step. Also, display the number of filled cells and frontier size. It has to use requestAnimationFrame for smooth animation and restart automatically when finished. No external libraries, and the code should be under 120 lines.

First, the HTML structure. I'll start with the basic HTML5 template. Inside the body, a canvas element with id 'canvas', and some divs to show the stats. The canvas should have width and height attributes set to the grid size multiplied by the cell size. Wait, the grid is 60x40, but the cell size? Maybe each cell can be 10px, so the canvas would be 600x400. That seems reasonable.

Next, the JavaScript part. I'll need to handle the canvas context. Let me think about the steps:

1. Initialize the grid. Each cell can have a color. The initial grid should have some random blobs. How to create random blobs? Maybe start by randomly placing seeds and growing them with a certain probability to form regions. But that might be too complex. Alternatively, for simplicity, I can color each cell with random colors, then in the flood fill, find connected regions. Hmm, but the user mentioned "random blobs of color", so perhaps first step is to generate regions with connected colors?

Wait, perhaps the idea is to first create a grid where each cell has a random color (forming blobs), then pick a starting cell and flood fill from there, replacing the original color with a new one. Wait, but the user says "expand the fill one frontier step at a time". So maybe the flood fill is expanding the current color into the neighboring cells. Wait, no, perhaps the initial grid has some colors, and the flood fill starts at a point, and tries to replace the target color with the new color, expanding step by step. But the user says "Generate a few random blobs of colour, pick a start cell, and expand the fill one frontier step at a time so the growing region is clearly visible."

Hmm, perhaps the initial grid has some regions (blobs) of colors, and the flood fill starts at a cell, and replaces the surrounding cells of the same color, but expanding step by step. But maybe the flood fill is starting with a new color and replacing the original color's connected region step by step. Alternatively, maybe the blobs are the initial random colors, and the flood fill is from a start point, changing the color step by step, with the frontier being the next layer.

Alternatively, perhaps the user wants to show the flood fill algorithm in action, where the fill starts at a point and expands to all reachable cells of the same color, one layer at a time. The animation should show each step of the expansion.

So the steps:

- Create a grid (60x40). Each cell has a color (maybe randomized into blobs). Wait, how to make blobs? Maybe first assign random colors to each cell, then for some iterations, blur or smooth the colors to create blobs. Alternatively, use a cellular automaton approach to generate regions. Alternatively, a better approach for simplicity might be to first choose a starting color, then randomly fill adjacent cells to form a blob, but that could be computationally heavy.

Alternatively, for the initial grid, assign each cell a random color, but then apply a thresholding or clustering algorithm, but that might be overcomplicated. Alternatively, maybe the initial grid is filled with random colors, and the flood fill starts at a point, and the target color is the original color of that point. Then, the flood fill will expand to connected cells of the original color, replacing them with a new color (like white or another color chosen for the flood). The animation would show each step of that expansion.

Wait, the user says "expand the fill one frontier step at a time", so the animation should show each step. The flood fill algorithm typically uses a queue; each step processes the current frontier (the edges of the filled region) and adds the next layer to the frontier.

Therefore, the steps are:

Initialize grid with random colors.

Pick a starting cell (maybe random? Or center? The user didn't specify, so perhaps random).

The flood fill will start at that cell, and replace the original color with a new color (like white). The frontier is the list of cells adjacent to the filled region that are of the target color (original color). Each frame processes one step (i.e., takes the current frontier, processes each cell in the current frontier, then adds their adjacent cells to the new frontier).

So in code:

We need to track:

- grid: 2D array for color (maybe as RGB values or just indices for colors)

- filled: another 2D array (or part of the grid) to track filled status?

Alternatively, the grid can be a 2D array where each cell has its current color, and once filled, it's set to the target fill color.

But the flood fill's target color is the original color of the starting cell. So first, get the original color of the starting cell. Then, any cell of that original color is a candidate to be filled.

So the algorithm steps:

Initialize grid with random colors.

Pick a random starting point (x,y).

OriginalColor = grid[x][y]

The flood color can be a new color, say white (or another color not used in the initial grid, but maybe random each time).

Frontier starts as the starting cell's neighbors of OriginalColor.

Wait, actually, the flood fill should start with the starting cell itself, then expand. Wait, the standard flood fill algorithm is:

Initialize a queue with the starting cell.

While queue not empty:

- current cell = dequeue

- if cell's color is original color:

- set it to new color

- add its neighbors to the queue (if they are original color)

But to animate it step by step, each frame processes one step (one cell from the queue?), but that would be slow. Alternatively, process each layer (all current frontier cells) as one step. Wait, perhaps the frontier is stored as a list, and each step processes all current frontier cells, and adds their neighbors to the next frontier.

Wait, maybe using BFS, where each step processes all elements in the current frontier, and the next frontier is built from their neighbors.

Thus, each animation frame, we process the current frontier's cells, mark them as filled, and then compute the next frontier as the neighbors of those cells that are of the original color and not yet filled.

Therefore, variables needed:

- grid: 2D array of colors (maybe stored as numbers for simplicity)

- filled: 2D array of booleans? Or track via color change.

Wait, perhaps the grid can hold the color, and once filled, it becomes the new color. The original color is stored separately. So during the flood, any cell of the original color adjacent to the current filled area becomes part of the next frontier.

Thus, the steps:

Initialize grid:

for each cell (x,y):

grid[x][y] = random color (maybe a random hex or a value between 0 and some number)

Then pick a starting point (x0,y0).

originalColor = grid[x0][y0]

fillColor = some other color (maybe white, or random)

frontier starts with [x0,y0]?

Wait, actually, the starting cell is the first to be filled, so the frontier is initially empty? Hmm.

Wait, let me think again
Outside the Brain cluster — same task, same character budget, collected through their own tooling (response times not comparable)
GPT-5.5 (Codex)frontier referenceOK
Show code
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Flood Fill</title>
<style>
html,body{margin:0;height:100%;background:#111;color:#eee;font:16px system-ui,sans-serif;display:grid;place-items:center}
#wrap{width:min(96vw,1100px)}
canvas{width:100%;aspect-ratio:3/2;display:block;background:#000;image-rendering:pixelated}
#stats{display:flex;gap:24px;justify-content:center;padding:14px 0;color:#ddd}
b{color:#fff}
</style>
</head>
<body>
<div id="wrap">
<canvas id="c" width="900" height="600"></canvas>
<div id="stats">Filled: <b id="filled">0</b> Frontier: <b id="frontier">0</b></div>
</div>
<script>
const W=60,H=40,C=document.getElementById("c"),x=C.getContext("2d"),cw=C.width/W,ch=C.height/H;
const filledEl=document.getElementById("filled"),frontEl=document.getElementById("frontier");
let grid,seen,frontier,filled,target,fillColor,last=0,wait=45;
const palette=["#ef4444","#f97316","#eab308","#22c55e","#14b8a6","#3b82f6","#8b5cf6","#ec4899"];
function rnd(n){return Math.floor(Math.random()*n)}
function blob(g,cx,cy,r,col){
 for(let y=0;y<H;y++)for(let x=0;x<W;x++){
  let dx=x-cx,dy=y-cy,d=Math.hypot(dx,dy);
  if(d<r*(.65+Math.random()*.65))g[y][x]=col;
 }
}
function setup(){
 grid=Array.from({length:H},()=>Array.from({length:W},()=>palette[rnd(palette.length)]));
 for(let i=0;i<18;i++)blob(grid,rnd(W),rnd(H),4+rnd(10),palette[rnd(palette.length)]);
 seen=Array.from({length:H},()=>Array(W).fill(false));
 let sx=rnd(W),sy=rnd(H);
 target=grid[sy][sx];
 fillColor="#f8fafc";
 frontier=[[sx,sy]];
 seen[sy][sx]=true;
 filled=0;
 draw();
}
function draw(){
 for(let y=0;y<H;y++)for(let x0=0;x0<W;x0++){
  x.fillStyle=seen[y][x0]?fillColor:grid[y][x0];
  x.fillRect(x0*cw,y*ch,cw-1,ch-1);
 }
 x.fillStyle="#111827";
 for(const [fx,fy] of frontier)x.fillRect(fx*cw+cw*.2,fy*ch+ch*.2,cw*.6,ch*.6);
 filledEl.textContent=filled;
 frontEl.textContent=frontier.length;
}
function step(){
 if(!frontier.length){setTimeout(setup,450);return}
 let next=[];
 for(const [cx0,cy0] of frontier){
  filled++;
  for(const [dx,dy] of [[1,0],[-1,0],[0,1],[0,-1]]){
   let nx=cx0+dx,ny=cy0+dy;
   if(nx>=0&&nx<W&&ny>=0&&ny<H&&!seen[ny][nx]&&grid[ny][nx]===target){
    seen[ny][nx]=true;
    next.push([nx,ny]);
   }
  }
 }
 frontier=next;
 draw();
}
function loop(t){
 if(t-last>wait){step();last=t}
 requestAnimationFrame(loop);
}
setup();
requestAnimationFrame(loop);
</script>
</body>
</html>
Claude Sonnet 5frontier referenceOK
Show code
<!DOCTYPE html><html><head><meta charset="utf8"><title>Flood Fill</title><style>
body{margin:0;background:#111;color:#eee;font-family:monospace}canvas{display:block;margin:20px auto;background:#181818}
</style></head><body>
<canvas id="c" width="900" height="620"></canvas>
<script>
const cv=document.getElementById('c'),cx=cv.getContext('2d');
const W=60,H=40,cell=13,ox=15,oy=50;
let grid,fillColor,startX,startY,visited,frontier,filled,frame,phase,pause;
function key(x,y){return x+','+y}
function reset(){
 let base=Math.floor(Math.random()*360);
 grid=[];for(let x=0;x<W;x++){grid.push(new Array(H).fill(0))}
 let blobCount=5+Math.floor(Math.random()*4);
 for(let b=0;b<blobCount;b++){
  let bx=Math.floor(Math.random()*W),by=Math.floor(Math.random()*H);
  let hue=Math.floor(Math.random()*8);
  let r=4+Math.floor(Math.random()*7);
  for(let x=Math.max(0,bx-r);x<Math.min(W,bx+r);x++)
   for(let y=Math.max(0,by-r);y<Math.min(H,by+r);y++)
    if((x-bx)*(x-bx)+(y-by)*(y-by)<r*r)grid[x][y]=hue;
 }
 startX=Math.floor(Math.random()*W);startY=Math.floor(Math.random()*H);
 fillColor=grid[startX][startY];
 visited={};frontier=[[startX,startY]];visited[key(startX,startY)]=true;
 filled=1;frame=0;phase='fill';pause=0
}
function stepFill(){
 let next=[];
 for(let[x,y]of frontier){
  for(let[dx,dy]of[[1,0],[-1,0],[0,1],[0,-1]]){
   let nx=x+dx,ny=y+dy;
   if(nx<0||nx>=W||ny<0||ny>=H)continue;
   let k=key(nx,ny);
   if(visited[k])continue;
   if(grid[nx][ny]!==fillColor)continue;
   visited[k]=true;next.push([nx,ny]);filled++
  }
 }
 frontier=next;
 if(frontier.length===0){phase='done';pause=110}
}
function colFor(h,filledFlag){
 if(filledFlag)return'#fff';
 return'hsl('+(h*45)+',65%,45%)'
}
function draw(){
 cx.fillStyle='#181818';cx.fillRect(0,0,cv.width,cv.height);
 for(let x=0;x<W;x++)for(let y=0;y<H;y++){
  let isFilled=visited[key(x,y)];
  cx.fillStyle=isFilled?'#fff':'hsl('+(grid[x][y]*45)+',60%,40%)';
  cx.fillRect(ox+x*cell,oy+y*cell,cell-1,cell-1)
 }
 if(phase==='fill'){
  cx.fillStyle='#f33';
  for(let[x,y]of frontier)cx.fillRect(ox+x*cell,oy+y*cell,cell-1,cell-1)
 }
 cx.fillStyle='#0af';cx.fillRect(ox+startX*cell,oy+startY*cell,cell-1,cell-1);
 cx.fillStyle='#fff';cx.font='18px monospace';cx.textAlign='left';
 cx.fillText('Cells filled: '+filled+'   Frontier size: '+frontier.length,20,25);
 if(phase==='done')cx.fillText('Flood fill complete',400,25);
}
function loop(){
 frame++;
 if(phase==='fill'){if(frame%4===0)stepFill()}
 else if(phase==='done'){pause--;if(pause<=0)reset()}
 draw();
 requestAnimationFrame(loop)
}
reset();loop();
</script></body></html>
Claude Haiku 4.5frontier referenceOK
Show code
<!DOCTYPE html><html><head><title>r71</title></head><body><canvas id="c"></canvas><script>
let c=document.getElementById('c'),x=c.getContext('2d');c.width=800;c.height=600;
let W=60,H=40,g=Array(H).fill(0).map(()=>Array(W).fill(0));
let cols=["#f00","#0f0","#00f","#ff0","#f0f","#0ff"];
for(let i=0;i<5;i++){let cx=Math.random()*W,cy=Math.random()*H;
  for(let j=0;j<Math.random()*30+10;j++){let nx=cx+Math.random()*8-4,ny=cy+Math.random()*8-4;
    if(nx>=0&&nx<W&&ny>=0&&ny<H)g[Math.floor(ny)][Math.floor(nx)]=i+1;
  }
}
let sx=Math.floor(Math.random()*W),sy=Math.floor(Math.random()*H);
let tgt=g[sy][sx],q=[{x:sx,y:sy}],vis=new Set(),fill=0,front=1;
function draw(){
  x.fillStyle="#fff";x.fillRect(0,0,800,600);
  let s=Math.floor(750/W);
  // Grid
  for(let i=0;i<H;i++)for(let j=0;j<W;j++){
    if(vis.has(j+","+i))x.fillStyle="#888";else x.fillStyle=tgt===g[i][j]&&g[i][j]>0?cols[g[i][j]-1]:"#ddd";
    x.fillRect(j*s,i*s,s,s);
  }
  // Frontier
  for(let n of q){x.fillStyle="#f0f";x.fillRect(n.x*s,n.y*s,s,s);}
  // Step
  if(q.length){let cur=q.shift();vis.add(cur.x+","+cur.y);fill++;
    for(let[dx,dy]of[[1,0],[-1,0],[0,1],[0,-1]]){
      let nx=cur.x+dx,ny=cur.y+dy;
      if(nx>=0&&nx<W&&ny>=0&&ny<H&&!vis.has(nx+","+ny)&&g[ny][nx]===tgt){q.push({x:nx,y:ny});}
    }
  }else if(Math.random()>0.95){g=Array(H).fill(0).map(()=>Array(W).fill(0));
    for(let i=0;i<5;i++){let cx=Math.random()*W,cy=Math.random()*H;
      for(let j=0;j<Math.random()*30+10;j++){let nx=cx+Math.random()*8-4,ny=cy+Math.random()*8-4;
        if(nx>=0&&nx<W&&ny>=0&&ny<H)g[Math.floor(ny)][Math.floor(nx)]=i+1;
      }
    }
    sx=Math.floor(Math.random()*W);sy=Math.floor(Math.random()*H);tgt=g[sy][sx];q=[{x:sx,y:sy}];vis=new Set();fill=0;
  }
  x.fillStyle="#000";x.font="14px mono";x.fillText("Filled:"+fill+" Frontier:"+q.length,500,50);
  requestAnimationFrame(draw);
}draw();
</script></body></html>
Results at a glance— every model in this round with score, response time and status.

Who wrote what

ModelBlind scoreLatencyStatus
mistral-small:24b —99.4 sOK
qwen3:8b ——harness
qwen3:14b —19.4 sOK
qwen3.5:9b —33.3 sOK
llama3.1:8b —95.3 sOK
qwen3-coder:30b —34.6 sOK
deepseek-r1:14b —98.7 sOK
gemma4:26b ——harness
command-r:35b —30.3 sOK
deepseek-r1:32b —151.2 sOK
qwq:32b —85.9 sOK

Frontier reference — outside the blind field

These models answered the identical prompt outside the blind field. They are deliberately not scored and not part of the blind comparison — they are there so you can see where a frontier model lands on the same task.

Collected differently from the blind field: the local models run through a plain API harness, the frontier references through a context-free agent, one shot, no retries. Response times are therefore not comparable and are not shown. On two English tasks the reference answer came back in German — an artefact of that harness, flagged on the affected rounds.
Claude Opus 5frontier reference
Show code
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Flood Fill — 60×40</title>
<style>
html,body{height:100%;margin:0;background:#080b12;color:#dbe4f0;font:14px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;display:flex;align-items:center;justify-content:center}
.wrap{display:flex;flex-direction:column;gap:10px;padding:16px;max-width:100%}
canvas{background:#05070c;border-radius:8px;box-shadow:0 0 0 1px #1d2635,0 18px 50px -20px #000;width:100%;height:auto;image-rendering:pixelated}
.hud{display:flex;flex-wrap:wrap;gap:8px}
.chip{background:#111827;border:1px solid #202b3d;border-radius:6px;padding:6px 10px;letter-spacing:.04em}
.chip b{color:#7dd3fc;font-weight:600}
.chip.f b{color:#fff}
</style>
</head>
<body>
<div class="wrap">
<canvas id="c" width="960" height="640"></canvas>
<div class="hud">
<div class="chip">filled <b id="a">0</b></div>
<div class="chip f">frontier <b id="b">0</b></div>
<div class="chip">step <b id="d">0</b></div>
<div class="chip">region <b id="e">0</b></div>
</div>
</div>
<script>
const W=60,H=40,S=16,c=document.getElementById('c'),x=c.getContext('2d');
const base=document.createElement('canvas');base.width=c.width;base.height=c.height;
const bx=base.getContext('2d');
const PAL=['#16233a','#22405c','#2e6f7a','#3f8f6b','#7fae4b','#c9a227','#c86b3c','#a03e5a','#5b3a7e','#3d5a8c'];
const A=document.getElementById('a'),B=document.getElementById('b'),D=document.getElementById('d'),E=document.getElementById('e');
let grid,seen,depth,frontier,filled,step,total,done,hold,acc,last=0;
function region(s,mark){
  const q=[s],v=new Uint8Array(W*H);v[s]=1;let n=0,col=grid[s];
  while(q.length){const p=q.pop();n++;if(mark)mark[p]=1;
    const i=p%W,j=(p/W)|0;
    if(i>0&&!v[p-1]&&grid[p-1]===col){v[p-1]=1;q.push(p-1)}
    if(i<W-1&&!v[p+1]&&grid[p+1]===col){v[p+1]=1;q.push(p+1)}
    if(j>0&&!v[p-W]&&grid[p-W]===col){v[p-W]=1;q.push(p-W)}
    if(j<H-1&&!v[p+W]&&grid[p+W]===col){v[p+W]=1;q.push(p+W)}}
  return n;
}
function gen(){
  const n=7+((Math.random()*5)|0),seeds=[];
  for(let i=0;i<n;i++)seeds.push({x:Math.random()*W,y:Math.random()*H,c:PAL[(Math.random()*PAL.length)|0],
    w:.65+Math.random()*.9,f:2+((Math.random()*4)|0),p:Math.random()*6.283,a:.14+Math.random()*.3});
  grid=new Array(W*H);
  for(let j=0;j<H;j++)for(let i=0;i<W;i++){
    let bd=1e9,bc=PAL[0];
    for(const s of seeds){
      const dx=i+.5-s.x,dy=j+.5-s.y;
      const d=Math.hypot(dx,dy)*(1+s.a*Math.sin(Math.atan2(dy,dx)*s.f+s.p))/s.w;
      if(d<bd){bd=d;bc=s.c}}
    grid[j*W+i]=bc;
  }
  bx.fillStyle='#05070c';bx.fillRect(0,0,base.width,base.height);
  for(let j=0;j<H;j++)for(let i=0;i<W;i++){bx.fillStyle=grid[j*W+i];bx.fillRect(i*S,j*S,S-1,S-1)}
  let start=0,bestN=-1;
  for(let t=0;t<28;t++){
    const s=(Math.random()*W*H)|0,sz=region(s);
    if(sz>bestN){bestN=sz;start=s}
    if(bestN>=260)break;
  }
  seen=new Uint8Array(W*H);depth=new Int16Array(W*H).fill(-1);
  seen[start]=1;depth[start]=0;frontier=[start];filled=1;step=0;total=bestN;done=false;hold=0;acc=0;
}
function advance(){
  const col=grid[frontier[0]],next=[];
  for(const p of frontier){
    const i=p%W,j=(p/W)|0,nb=[];
    if(i>0)nb.push(p-1);if(i<W-1)nb.push(p+1);if(j>0)nb.push(p-W);if(j<H-1)nb.push(p+W);
    for(const q of nb)if(!seen[q]&&grid[q]===col){seen[q]=1;depth[q]=step+1;next.push(q);filled++}
  }
  frontier=next;step++;
  if(!frontier.length)done=true;
}
function frame(t){
  const dt=Math.min(80,t-last);last=t;
  if(done){hold+=dt;if(hold>1000)gen()}
  else{acc+=dt;while(acc>=42&&!done){acc-=42;advance()}}
  x.drawImage(base,0,0);
  for(let p=0;p<W*H;p++){
    if(!seen[p])continue;
    const i=p%W,j=(p/W)|0,d=depth[p];
    x.fillStyle='hsl('+((196+d*4+t*.02)%360)+' 92% '+(48+8*Math.sin(d*.4+t*.003))+'%)';
    x.fillRect(i*S,j*S,S-1,S-1);
  }
  x.fillStyle='#fff';
  for(const p of frontier){const i=p%W,j=(p/W)|0;x.fillRect(i*S,j*S,S-1,S-1)}
  x.fillStyle='rgba(255,255,255,.28)';
  for(const p of frontier){const i=p%W,j=(p/W)|0;x.fillRect(i*S-2,j*S-2,S+3,S+3)}
  A.textContent=filled;B.textContent=frontier.length;D.textContent=step;E.textContent=total;
  requestAnimationFrame(frame);
}
gen();requestAnimationFrame(frame);
</script>
</body>
</html>