OverviewCode › R82
Code · blind round

R82 · Conway's Game of Life with seeded patterns

blind round 3/8 local models answered

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

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

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

Show task
Create ONE self-contained HTML file (STRICT LIMIT: max 7000 characters in total — this is a budget on characters, not on lines, so removing line breaks does not help) that runs Conway's Game of Life on a 120x80 grid drawn on a <canvas>. Seed it with a few known patterns — at least one glider and one oscillator — plus random noise, and let it evolve. Colour cells by how long they have been alive so trails and stable structures become visible. Show the generation number and the live-cell count, and reseed when the population stops changing. Smooth requestAnimationFrame animation, NO user input, starts immediately and keeps running (restart with a fresh random instance when finished). No external libraries, no comments needed. Output ONLY the HTML file content, nothing else.

The answers — blind

Local models (Brain cluster) — identical prompt, anonymized order
MODEL Agemma4:26bDNF
No usable answer reached the harness (TIMEOUT). Counted as a did-not-finish.
MODEL Bqwen3-coder:30bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Conway's Game of Life</title>
<style>body{background:#111;color:white;font-family:monospace;display:flex;flex-direction:column;align-items:center;margin:0;padding-top:20px;}canvas{border:1px solid #333;background:#000;}</style>
</head>
<body><canvas id="lifeCanvas" width="600" height="480"></canvas><div id="info">Gen: 0 | Live: 0</div><script>
const c=document.getElementById('lifeCanvas');
const ctx=c.getContext('2d');
let W=120, H=80;
c.width=W*5; c.height=H*5; // Draw at 5px per cell

// State arrays: (Cell state, Age trail)
let grid=[[0],[0]];
let ageGrid=[[0],[0]];

const A=Math.floor(Math.random);

function init() {
    grid = Array.from({length:H}, (_,y) => new Array(W).fill(0));
    ageGrid = Array.from({length:H}, (_,y) => new Array(W).fill(0));

    // Seed 1: Glider (example offset adjusted for 120x80)
    for(let y=5; y<=9; ++y) {
        if (y < H && y >= 0) {
            grid[y][2] = grid[y][3] = grid[y][4] = 1; // Row 5, cols 2-4
            ageGrid[y][2] = ageGrid[y][3] = ageGrid[y][4] = 1;
        }
    }
    // Seed 2: Blinker (period 2 oscillator)
    for(let y=15; ++y) {
         if (y < H && y >= 0) {
            grid[y][8] = grid[y][9] = grid[y][10] = 1; // Row 15, cols 8-10
            ageGrid[y][8] = ageGrid[y][9] = ageGrid[y][10] = 1;
        }
    }

    // Seed 3: Random Noise (approx 5% density)
    for(let y=0; y<H; ++y) {
        for(let x=0; x<W; ++x) {
            if (A(100) < 5) {
                grid[y][x] = 1;
                ageGrid[y][x] = 1;
            }
        }
    }

    document.getElementById('info').innerHTML = 'Gen: 0 | Live: 0';
    draw();
    requestAnimationFrame(step);
}

function getNeighbors(y, x) {
    let count=0;
    for (let dy=-1; dy<=1; ++dy) {
        for (let dx=-1; dx<=1; ++dx) {
            if (Math.abs(dy)+Math.abs(dx)>0) {
                const ny = y+dy;
                const nx = x+dx;
                if (ny >= 0 && ny < H && nx >= 0 && nx < W) {
                    count += grid[ny][nx];
                }
            }
        }
    }
    return count;
}

function nextState() {
    let newGrid = Array.from({length:H}, (_,y) => new Array(W).fill(0));
    let newAgeGrid = JSON.parse(JSON.stringify(ageGrid)); // Deep copy for age tracking
    let liveCount=0;

    for (let y=0; y<H; ++y) {
        for (let x=0; x<W; ++x) {
            const neighbors=getNeighbors(y, x);
            const isAlive=grid[y][x];

            if (isAlive) {
                // Survival or Death by Under/Overpopulation
                if (neighbors==2) {
                    newGrid[y][x] = 1;
                    newAgeGrid[y][x] = newAgeGrid[y][x] + 1; // Increment age
                    liveCount++;
                } else {
                    newGrid[y][x] = 0;
                    newAgeGrid[y][x] = 0;
                }
            } else {
                // Reproduction (Birth)
                if (neighbors==3) {
                    newGrid[y][x] = 1;
                    newAgeGrid[y][x] = 1; // New cell, age 1
                    liveCount++;
                } else {
                    newAgeGrid[y][x] = 0;
                }
            }
        }
    }

    grid = newGrid;
    ageGrid = newAgeGrid;
    return liveCount;
}

function draw() {
    ctx.clearRect(0, 0, c.width, c.height);
    for (let y=0; y<H; ++y) {
        for (let x=0; x<W; ++x) {
            if (grid[y][x]) {
                const age = ageGrid[y][x];
                // Background color is based on age (max 15 generations for smooth visible gradient)
                ctx.fillStyle=`hsl(${age * 20 % 360},70%,${Math.min(90, age*8)}%)`;
                ctx.fillRect(x*5, y*5, 5, 5);
            }
        }
    }
}

let generation=0;
let lastLiveCount=0;

function step() {
    const currentLiveCount = nextState();
    generation++;

    draw();
    document.getElementById('info').innerHTML=`Gen: ${generation} | Live: ${currentLiveCount}`;

    // Check for stabilization (population count hasn't changed)
    if(currentLiveCount === lastLiveCount && generation > 10) {
        console.log("Stabilized. Restarting...");
        setTimeout(() => {
            init(); // Reset and restart the simulation
        }, 500);
    }

    lastLiveCount = currentLiveCount;
    requestAnimationFrame(step);
}

init();
</script></body></html>
```
MODEL Cqwen3:14bERRSTATLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Game of Life</title>
    <style>body { background: #111; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; flex-direction: column; } canvas { border: 2px solid #555; image-rendering: pixelated; } #stats { color: white; font-family: monospace; margin-top: 10px; }</style>
</head>
<body>
    <canvas id="gameCanvas" width="600" height="480"></canvas>
    <div id="stats">Generation: 0 | Population: 0</div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const W = 120;
        const H = 80;
        const CELL_SIZE = Math.min(canvas.width, canvas.height) / Math.max(W, H);

        let grid = [];
        let generation = 0;
        let previousGrid = null;
        let running = true;

        // Setup initial random/seeded grid
        function initializeGrid() {
            grid = Array(H).fill(0).map(() => Array(W).fill(null));
            previousGrid = JSON.parse(JSON.stringify(grid)); // Deep copy for restart check

            for (let y = 0; y < H; y++) {
                for (let x = 0; x < W; x++) {
                    // Initialize all cells as dead, age 0
                    grid[y][x] = { a: false, e: 0 }; 
                }
            }

            // Seed Patterns (Glider and Blinker)
            const seed = (startX, startY, state) => {
                if (startX >= 0 && startX < W && startY >= 0 && startY < H) {
                    grid[startY][startX] = { a: state, e: Math.max(1, grid[startY][startX]?.e || 0) };
                }
            };

            // Glider (x, y offsets relative to top-left corner)
            seed(5 * CELL_SIZE + 2, 5 * CELL_SIZE + 3, true);
            seed(5 * CELL_SIZE + 3, 5 * CELL_SIZE + 4, true);
            seed(5 * CELL_SIZE + 4, 5 * CELL_SIZE + 3, true);
            seed(5 * CELL_SIZE + 5, 5 * CELL_SIZE + 4, true);
            seed(5 * CELL_SIZE + 6, 5 * CELL_SIZE + 5, true);

            // Blinker (Oscillator)
            seed(W / 2 - 10, H / 2, true);
            seed(W / 2, H / 2, true);
            seed(W / 2 + 10, H / 2, true);

            // Random Noise (approx 5% density)
            for (let y = 0; y < H; y++) {
                for (let x = 0; x < W; x++) {
                    if (Math.random() < 0.03) {
                        grid[y][x] = { a: true, e: Math.max(1, grid[y][x]?.e || 0) };
                    }
                }
            }

            // If the initial state was all zero due to overwrite, ensure some cells exist.
            if (grid[H/2][W/2] === null) {
                 grid[Math.floor(H/2)][Math.floor(W/2)] = { a: true, e: 1 };
            }
        }

        // Calculates state for the next generation based on Moore neighborhood rules
        function computeNextGeneration() {
            let newGrid = Array(H).fill(0).map(() => Array(W).fill(null));
            let liveCount = 0;

            for (let y = 0; y < H; y++) {
                for (let x = 0; x < W; x++) {
                    let neighbors = 0;
                    // Check 8 neighbors (compact loop)
                    for (let dy = -1; dy <= 1; dy++) {
                        for (let dx = -1; dx <= 1; dx++) {
                            if (dx === 0 && dy === 0) continue;
                            const ny = y + dy;
                            const nx = x + dx;

                            // Boundary check
                            if (ny >= 0 && ny < H && nx >= 0 && nx < W) {
                                if (grid[ny][nx].a) {
                                    neighbors++;
                                }
                            }
                        }
                    }

                    let newState = { a: false, e: 0 }; // Default to dead state

                    if (grid[y][x].a) {
                        // Rule 1 & 2: Survival
                        if (neighbors === 2 || neighbors === 3) {
                            newState.a = true;
                            newState.e = grid[y][x].e + 1; // Age increases
                        } else {
                            // Death by under/overpopulation, age resets to 0 implicitly
                        }
                    } else {
                        // Rule 4: Birth
                        if (neighbors === 3) {
                            newState.a = true;
                            newState.e = 1; // New cell always starts at age 1
                        }
                    }
                    newGrid[y][x] = newState;

                    if (newState.a) {
                        liveCount++;
                    }
                }
            }
            grid = newGrid;
            return liveCount;
        }


        // Drawing function using age-based coloring
        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            for (let y = 0; y < H; y++) {
                for (let x = 0; x < W; x++) {
                    const cell = grid[y][x];
                    if (cell && cell.a) {
                        // Age coloring logic: Older cells get different colors/brightness
                        // Use a simple color mapping based on age modulo some value for visible cycling
                        let hue = (cell.e * 10 % 360); // Cycle through hues
                        ctx.fillStyle = `hsl(${hue}, 80%, ${Math.min(85, 40 + cell.e*2)}%)`;
                        ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE - 1, CELL_SIZE - 1);
                    } else {
                         // Draw background/dead cells (optional: solid dark pixel)
                         ctx.fillStyle = '#090909';
                         ctx.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE - 1, CELL_SIZE - 1);
                    }
                }
            }
        }

        function updateStats(liveCount) {
            const statsDiv = document.getElementById('stats');
            statsDiv.innerHTML = `Generation: ${generation} | Population: ${liveCount}`;
        }
        
        // Main loop
        function gameLoop() {
            if (!running) return;

            let currentLiveCount = 0;
            const newPopulationStructure = computeNextGeneration();
            currentLiveCount = newPopulationStructure;

            draw();
            updateStats(currentLiveCount);

            generation++;

            // Check for stable state (no change in population structure OR zero cells)
            let hasChanged = false;
            for (let y = 0; y < H; y++) {
                for (let x = 0; x < W; x++) {
                    const current = grid[y][x];
                    const previous = previousGrid[y][x];

                    if (current.a !== previous.a) {
                        hasChanged = true;
                        break;
                    }
                }
            }

            // If no structure change AND the population is stable/zero, restart
            if (!hasChanged && (currentLiveCount === 0 || currentLiveCount > 0)) {
                 console.log("Stable state reached or death detected. Restarting...");
                 running = false; // Stop the recursion temporarily
                 setTimeout(() => {
                     initializeGrid();
                     gameLoop(); // Start over recursively
                 }, 500);
                 return;
            }

            // Update previous grid state for next comparison
            for (let y = 0; y < H; y++) {
                previousGrid[y] = [...grid[y]];
            }

            requestAnimationFrame(gameLoop);
        }


        // Start the simulation
        initializeGrid();
        gameLoop();
    </script>
</body>
</html>
```
MODEL Dqwen3:8bDNF
No usable answer reached the harness (ERR). Counted as a did-not-finish.
MODEL Ellama3.1:8bDNF
No usable answer reached the harness (TIMEOUT). Counted as a did-not-finish.
MODEL Fqwen3.5:9bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><title>Game of Life</title></head><style>body{background:#111;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;color:#fff;font-family:monospace;}canvas{border:2px solid #333;}</style></head><body><canvas id="gameCanvas" width="600" height="480"></canvas><script>
const C = document.getElementById('gameCanvas');
const CTX = C.getContext('2d');

let W = 120, H = 80; // Grid dimensions
let CELL_SIZE = Math.min(600 / W, 480 / H);

// State grids: [age, alive]
let gridA = Array(W).fill(0).map(() => Array(H).fill([1, false]));
let gridB = Array(W).fill(0).map(() => Array(H).fill([1, false]));
let currentGrid, nextGrid;

let generation = 0;
const MAX_AGE = 50; // Max age for color cycling

function initGrids() {
    currentGrid = gridA;
    nextGrid = gridB;
}

// Helper to get cell state safely (handles boundaries)
function getState(grid, x, y) {
    if (x < 0 || x >= W || y < 0 || y >= H) return [1, false];
    return grid[x][y];
}

// Initializes the grid with specific patterns and random noise
function seedGrid() {
    generation = 0;
    for(let i=0; i<W; i++) for(let j=0; j<H; j++) {
        currentGrid[i][j] = [1, false];
    }

    // --- Seed Patterns (Glider and Oscillator) ---
    const setCell = (x, y, state) => { 
        if (x >= 0 && x < W && y >= 0 && y < H) currentGrid[x][y] = [1, state]; 
    };

    // Glider: (5, 10), (6, 11), (7, 10), (8, 11), (9, 12)
    setCell(5, 10, true); setCell(6, 11, true); setCell(7, 10, true); setCell(8, 11, true); setCell(9, 12, true);

    // Oscillator (Blinker): Vertical
    setCell(W/3, H/4 - 1, true);
    setCell(W/3, H/4, true);
    setCell(W/3, H/4 + 1, true);

    // Add random noise (approx 5% density)
    for(let i=0; i<W; i++) {
        for(let j=0; j<H; j++) {
            if (Math.random() < 0.05 && !currentGrid[i][j][1]) {
                currentGrid[i][j] = [1, true];
            }
        }
    }
}

// Conway's Game of Life rules implementation
function updateGrid() {
    let changes = 0;
    for(let i=0; i<W; i++) {
        for(let j=0; j<H; j++) {
            const neighbors = [
                getState(currentGrid, i-1, j-1), getState(currentGrid, i, j-1), getState(currentGrid, i+1, j-1),
                getState(currentGrid, i-1, j), getState(currentGrid, i+1, j), // Skip (i, j) itself
                getState(currentGrid, i-1, j+1), getState(currentGrid, i, j+1), getState(currentGrid, i+1, j+1)
            ].filter((s, k) => s[1]).length;

            const [age, alive] = currentGrid[i][j];
            let newAge = 0;
            let nextAlive = false;

            if (alive && (neighbors < 2 || neighbors > 3)) {
                // Rule 1 & 3: Death by under/overpopulation
                nextAlive = false;
                newAge = 0; // Reset age upon death
            } else if (!alive && neighbors === 3) {
                // Rule 4: Reproduction
                nextAlive = true;
                newAge = 1; // Newly born cell starts at age 1
            } else if (alive) {
                // Rule 2: Survival & Aging
                nextAlive = true;
                newAge = Math.min(age + 1, MAX_AGE);
            }

            const [oldAge, oldAlive] = currentGrid[i][j];
            if (newAge !== oldAge || nextAlive !== oldAlive) {
                 changes++;
            }

            nextGrid[i][j] = [newAge, nextAlive];
        }
    }

    // Swap grids for the next iteration
    [currentGrid, nextGrid] = [nextGrid, currentGrid];
    return changes;
}

function drawGrid() {
    CTX.clearRect(0, 0, C.width, C.height);
    for(let i=0; i<W; i++) {
        for(let j=0; j<H; j++) {
            const [age, alive] = currentGrid[i][j];
            if (alive) {
                // Color fading based on age/generation count (Hue cycling approximation)
                // Use a consistent color palette shifted by age
                let hue = (Math.floor((age / MAX_AGE) * 0.6 + Math.sin(generation * 0.1)) * 360 / MAX_AGE) % 360;
                let saturation = 80;
                let lightness = Math.min(70, 40 + (age / MAX_AGE) * 20);

                CTX.fillStyle = `hsl(${hue}, ${saturation}%, ${lightness}%`;
                CTX.fillRect(i * CELL_SIZE, j * CELL_SIZE, CELL_SIZE - 1, CELL_SIZE - 1);
            }
        }
    }
}

function calculateStats() {
    let liveCount = 0;
    for(let i=0; i<W; i++) {
        for(let j=0; j<H; j++) {
            if (currentGrid[i][j][1]) liveCount++;
        }
    }
    return liveCount;
}

function loop() {
    const changes = updateGrid();
    drawGrid();

    // Display Stats
    let stats = document.getElementById('stats');
    if (!stats) {
        stats = document.createElement('div');
        stats.id = 'stats';
        stats.style.marginTop='20px';
        document.body.appendChild(stats);
    }
    
    const liveCount = calculateStats();
    stats.innerHTML = `Gen: ${generation++}<br>Pop: ${liveCount}`;

    if (changes > 0) {
        requestAnimationFrame(loop);
    } else {
        // Population stabilized, reseed and restart cycle
        setTimeout(() => {
            seedGrid();
            initGrids(); // Reset pointers for new state
            requestAnimationFrame(loop);
        }, 1000);
    }
}

// Start the simulation
window.onload = () => {
    seedGrid();
    initGrids();
    loop();
};
</script></body></html>
```
MODEL Gdeepseek-r1:14bDNF
No usable answer reached the harness (TIMEOUT). Counted as a did-not-finish.
No usable answer reached the harness (TIMEOUT). Counted as a did-not-finish.
Reveal the models— compare the answers first, then open. Names, blind scores and latencies are hidden until you do.

Who wrote what

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