Overview › Code › R88
Code · blind round

R88 · L-system tree growing in wind

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 grows a fractal tree from an L-system on a <canvas>: expand a rewriting rule over several generations, then draw the branch structure so the tree appears branch by branch rather than all at once, and once it is complete let it sway in a wind that changes strength over time. Show the generation depth and the number of branches. 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)
deepseek-r1:14bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><style>canvas{position:fixed; margin:0 auto;top:50vh;left:50%;transform:translate(-50%, -50%)}.info{position:fixed;top:20px;right:20px;color:#fff;font-family:sans-serif}</style></head><body>
<canvas id=c width=600 height=800></canvas>
<div class="info" id=i>Gen: 0, Branches: 0</div>
<script>
let c=document.getElementById('c'), ctx=c.getContext('2d'), w=c.width, h=c.height;
let depth=5, branches=0, angle=90, len=100, wind=0;
function generateLSys(depth){return depth>0 ? generateLSys(depth-1).replace(/X/g,Y+X).replace(/F/g,F+F) : 'X';}
function parse(s){return s.split('').map(c=>c=='+'?{t:'angle',val:2}:c=='-'?{t:'angle',val:-2}:c=='Y'?{t:'store'}:{t:'line',x:1}))}
function draw(cmds,x,y,a,l){cmds.forEach(c=>{
  ctx.save();
  if(c.t=='line'){ctx.beginPath();ctx.moveTo(x,y);let nx=x+l*Math.cos(a), ny=y+l*Math.sin(a);ctx.lineTo(nx,ny);ctx.strokeStyle='#fff';ctx.lineWidth=2;ctx.stroke();}
  else if(c.t=='angle') a +=c.val * Math.PI/180;
});
}
function animate(){
  ctx.fillStyle='rgba(0,0,0,.3)';ctx.fillRect(0,0,w,h);
  let s=generateLSys(depth), cmds=parse(s.split('')));
  branches=cmds.filter(c=>c.t=='line').length;
  ctx.translate(w/2,h/4);angle=Math.PI/2;len=150;
  cmds.forEach((cmd,i)=>{if(i%3==0)ctx.beginPath();draw(cmd,i?0:0,0,angle,len)});
  wind=(Date.now()/100)%360;
  cmds.forEach(c=>c.t=='line' && c.x && (len=80/(c.x+2)));
  cmds.forEach((cmd,i)=>{if(cmd.t=='line') {let d=i%4; ctx.translate(w/2,h/4);}});
  document.getElementById('i').textContent=`Gen: ${depth}, Branches: ${branches}`;
  requestAnimationFrame(animate);
}
ctx.fillStyle='#000';animate();
</script>
</body></html>
```
qwen3:14bOKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>L-System Fractal Tree</title>
    <style>body {margin:0;overflow:hidden;background:#111;}canvas {display:block;}</style>
</head>
<body>
<canvas id="treeCanvas"></canvas>
<script>
(function() {
    const canvas = document.getElementById('treeCanvas');
    const ctx = canvas.getContext('2d');
    let W, H;

    // System State Variables
    let currentGeneration = 0;
    let maxGenerations = 6;
    let lSystemRules = {};
    let axiom = "";
    let sequence = "";
    let branchCount = 0;
    let isDrawingPhase = true;
    let drawingStep = 0;
    let currentBranch = []; // Stores segment information for the next draw step

    // Wind Simulation Variables (for stabilization after growth)
    let windStrength = 0.1;
    let timeOffset = Math.random() * 2 * Math.PI;
    const WIND_SPEED = 0.03;

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

    // --- L-System Setup and Generation ---

    function setupLSystem() {
        lSystemRules = {
            'F': 'FF+[+F-F-F]-[-F-F]', // A common fractal rule (e.g., Bush/Dragon)
        };
        axiom = "F";
        maxGenerations = 6;
        currentGeneration = 0;

        sequence = axiom;
        for (let i = 0; i < maxGenerations; i++) {
            let nextSequence = "";
            for (const char of sequence) {
                nextSequence += lSystemRules[char] || char;
            }
            sequence = nextSequence;
            currentGeneration++;
        }
    }

    function parseSequence(seq) {
        branchCount = 0;
        let stack = [];
        const segments = []; // Stores the path for drawing: [{x, y}, angle, length]

        // Start position (bottom center)
        let x = W / 2;
        let y = H - 50;
        let currentAngle = Math.PI * (-Math.PI / 16); // Pointing up slightly

        for (const char of seq) {
            if (char === 'F') {
                // Move forward and record segment
                let newX = x + Math.cos(currentAngle) * 2;
                let newY = y - Math.sin(currentAngle) * 2; // Y is inverted for canvas
                segments.push({ start: {x, y}, end: {x: newX, y: newY}, angle: currentAngle });
                x = newX;
                y = newY;
            } else if (char === '+') {
                currentAngle += Math.PI / 6; // Turn right
            } else if (char === '-') {
                currentAngle -= Math.PI / 6; // Turn left
            } else if (char === '[') {
                // Push state: [x, y, angle]
                stack.push({ x: x, y: y, a: currentAngle });
            } else if (char === ']') {
                // Pop state
                const state = stack.pop();
                if (state) {
                    x = state.x;
                    y = state.y;
                    currentAngle = state.a;
                }
            }
        }
        return segments;
    }

    // --- Drawing and Animation Logic ---

    let pathSegments = []; // The full list of segment data

    function drawTree(segments) {
        ctx.clearRect(0, 0, W, H);
        ctx.save();
        ctx.strokeStyle = '#532c18';
        ctx.lineCap = 'round';
        let currentDepth = 0;

        for (const segment of segments) {
            // Draw the segment
            ctx.beginPath();
            ctx.moveTo(segment.start.x, segment.start.y);
            ctx.lineTo(segment.end.x, segment.end.y);
            ctx.stroke();

            // Simple depth scaling/color change (optional)
        }
        ctx.restore();
    }


    function stepAnimation() {
        if (!isDrawingPhase && drawingStep === 0) {
            // Phase 2: Wind Simulation (Continuous animation)
            animationLoop(true);
            return;
        }

        if (drawingStep < pathSegments.length) {
            // Phase 1: Step-by-step Drawing
            const segment = pathSegments[drawingStep];

            // Calculate current wind influence (Sine wave based on time/progress)
            const t = performance.now() / 500;
            let swayFactor = Math.sin(t * WIND_SPEED + timeOffset);
            let adjustedAngle = segment.angle + swayFactor * 0.1;

            // Apply wind deviation to the drawing path (only noticeable on later, thinner branches)
            let startX = segment.start.x;
            let startY = segment.start.y;
            let endX = segment.end.x + Math.cos(adjustedAngle - segment.angle) * 5 * swayFactor;
            let endY = segment.end.y - Math.sin(adjustedAngle - segment.angle) * 5 * swayFactor;

            // Redraw the canvas, drawing only up to the current step
            ctx.clearRect(0, 0, W, H);
            ctx.save();
            ctx.strokeStyle = '#532c18';
            ctx.lineCap = 'round';

            for (let i = 0; i <= drawingStep; i++) {
                const s = pathSegments[i];
                // Re-simulate the winding effect for previous steps slightly, making it look continuous
                ctx.beginPath();
                ctx.moveTo(s.start.x, s.start.y);
                ctx.lineTo(s.end.x * (1 + 0.05 * Math.sin((i / pathSegments.length) * 2)) , s.end.y);
                ctx.stroke();
            }
            ctx.restore();

            drawingStep++;
        } else {
            // Phase End: Drawing Complete, transition to wind phase
            isDrawingPhase = false;
            drawingStep = 0; // Reset step counter for continuous loop
            animationLoop(true);
            return;
        }

        requestAnimationFrame(stepAnimation);
    }

    function animationLoop(continuous) {
        ctx.clearRect(0, 0, W, H);
        if (!isDrawingPhase && continuous) {
             // Wind simulation redraw logic (re-draw the full path with wind effect)
            ctx.save();
            ctx.strokeStyle = '#532c18';
            ctx.lineCap = 'round';

            const t = performance.now() / 500;
            let currentX = W/2;
            let currentY = H-50;
            let stack = [];
            let angle = Math.PI * (-Math.PI / 16);

            // Re-execute the parsing logic to draw the full tree structure every frame, applying wind deviation
            for (const char of sequence) {
                if (char === 'F') {
                    let sinAngle = Math.sin(angle + t * WIND_SPEED * 0.5);
                    let cosAngle = Math.cos(angle + t * WIND_SPEED * 0.5);

                    let newX = currentX + cosAngle * 2;
                    let newY = currentY - sinAngle * 2;

                    ctx.beginPath();
                    ctx.moveTo(currentX, currentY);
                    ctx.lineTo(newX, newY);
                    ctx.stroke();

                    currentX = newX;
                    currentY = newY;
                } else if (char === '+') {
                    angle += Math.PI / 6;
                } else if (char === '-') {
                    angle -= Math.PI / 6;
                } else if (char === '[') {
                    stack.push({ x: currentX, y: currentY, a: angle });
                } else if (char === ']') {
                    const state = stack.pop();
                    if (state) {
                        currentX = state.x;
                        currentY = state.y;
                        angle = state.a;
                    }
                }
            }

        }
        requestAnimationFrame(() => animationLoop(continuous));
    }


    function startSystem() {
        // 1. Setup L-system and generate sequence
        setupLSystem();

        // 2. Parse the sequence into drawable segments (for step-by-step drawing)
        pathSegments = parseSequence(sequence);

        // 3. Start Animation
        isDrawingPhase = true;
        drawingStep = 0;
        requestAnimationFrame(stepAnimation);
    }

    startSystem();
})();
</script>
</body>
</html>
```
qwen3-coder:30bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>LSystem Tree Growth</title>
    <style>body{margin:0;overflow:hidden;background:#111}canvas{display:block}</style>
</head>
<body>
<canvas id="treeCanvas"></canvas>
<script>
const canvas = document.getElementById('treeCanvas');
const ctx = canvas.getContext('2d');

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

let state = {
    maxGenerations: 8,
    currentGeneration: 0,
    systemRules: [],
    axiom: "",
    string: ""
};

function initLSystem() {
    // Basic rules for a fractal tree structure (e.g., Plant/Bush)
    state.systemRules = ["F", "FF+", "F-[-F+F]+[-F-F]"]; 
    state.axiom = "F";
    state.string = state.axiom;
}

function generateNextString() {
    let newString = "";
    for (let char of state.string) {
        if (char === 'F') { // Simple rule: F expands to a sequence
            newString += state.systemRules[0]; 
        } else if (char === '+' || char === '-' || char === '[' || char === ']') {
             // Pass through drawing characters
            newString += char;
        } else {
            newString += char;
        }
    }
    state.string = newString;
}

function drawTree(str, isWindPhase) {
    ctx.clearRect(0, 0);
    ctx.save();
    ctx.translate(canvas.width / 2, canvas.height);
    ctx.rotate(Math.PI / 2); // Start pointing up

    // Wind variable (time-dependent offset)
    let windOffset = isWindPhase ? Math.sin(Date.now() * 0.001) * 0.3 : 0;

    const stack = [];
    let x = 0;
    let y = 0;
    ctx.strokeStyle = '#4CAF50';
    ctx.lineWidth = 1;

    for (let i = 0; i < str.length; i++) {
        let char = str[i];

        if (char === 'F') {
            // Calculate current drawing position considering wind
            const effectiveX = x + Math.sin(y * 0.1) * windOffset;
            const effectiveY = y;

            ctx.beginPath();
            ctx.moveTo(effectiveX, effectiveY);
            let newY = effectiveY - 1; // Step down by 1 unit
            
            // Draw the segment
            ctx.lineTo(effectiveX + Math.sin((effectiveY - newY) * 0.1) * windOffset * 0.5, effectiveY - 1);
            ctx.stroke();

            x = effectiveX;
            y -= 1; // Move down (or up in canvas coords due to initial rotation)
        } else if (char === '+') {
            const angleChange = Math.PI / 4;
            ctx.rotate(angleChange);
        } else if (char === '-') {
            const angleChange = -Math.PI / 4;
            ctx.rotate(angleChange);
        } else if (char === '[') {
            stack.push({ x: x, y: y, rotation: ctx.getTransform().a }); // Save state 
        } else if (char === ']') {
            const saved = stack.pop();
            if (saved) {
                ctx.setTransform(1, 0, 0, 1, saved.x, saved.y);
                // Restore previous rotation and position
                ctx.rotate(0); 
                ctx.translate(canvas.width / 2, canvas.height);
            }
        } else {
            continue;
        }
    }
    ctx.restore();
}

function updateStats() {
    const depth = state.currentGeneration;
    const branches = Math.max(1, parseInt(state.string.split(/[\+\-]/).join('').length) / 20); // Rough estimate
    document.title = `Gen: ${depth}/${state.maxGenerations} | Branches: ${branches}`;
}

function loop(time) {
    if (state.currentGeneration <= state.maxGenerations) {
        // --- GROWTH PHASE ---
        const currentString = state.string;
        drawTree(currentString, false); 
        updateStats();

        if (state.currentGeneration < state.maxGenerations) {
            generateNextString();
            state.currentGeneration++;
            requestAnimationFrame(loop);
        } else {
            // --- WIND PHASE (Complete) ---
            console.log("Growth Complete. Entering Wind Phase.");
            state.isGrowing = false; 
            animateWind(time);
        }
    } else {
        // Keep running wind animation if it was already in progress
        if (!state.isGrowing && typeof animateWind === 'function') {
             requestAnimationFrame(loop);
        }
    }
}

let lastTime = 0;
const WIND_SPEED = 0.0015;

function animateWind(time) {
    // Redraw the tree structure using a continuous time input for wind offset
    drawTree(state.string, true); 
    requestAnimationFrame(() => {
        setTimeout(() => requestAnimationFrame(animateWind), 16); // ~60 FPS loop
    });
}

document.addEventListener('DOMContentLoaded', () => {
    initLSystem();
    // Start the process by setting current state and calling the loop
    state.isGrowing = true;
    requestAnimationFrame(loop);
});
</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.
llama3.1:8bERRBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html>
<head><title>Fractal Tree</title></head>
<body>
<canvas id="c" width=600 height=400></canvas>
<script>
let c = document.getElementById('c');
let ctx = c.getContext('2d');
ctx.font='10px Arial';
document.body.onload=start;
var wind = 0; var windmax = 3; var windinc = 1;
function start() {
  let r = Math.random()*Math.PI*2; let x = 300; let y = 200;
  ctx.moveTo(x,y);
  drawTree(r,x,y,200,100,10,6,0.5,.9,'F','X');
  requestAnimationFrame(drawWind);
}
function drawTree(a,x,y,l,w,a1,i,fac,scale,p,c) {
  if (i==0) return;
  ctx.beginPath();
  let nx = x + l * Math.cos(a), ny = y - l * Math.sin(a);
  ctx.lineTo(nx,ny);
  a += a1; let nl = l * fac;
  ctx.strokeStyle='#' + c[0].toString(16).padStart(2,'0') +
                  c[1].toString(16).padStart(2,'0') +
                  c[2].toString(16).padStart(2,'0');
  ctx.lineWidth=w*(i/10);
  ctx.stroke();
  ctx.strokeStyle='#' + r.toString(16).padStart(2,'0') +
                  g.toString(16).padStart(2,'0') +
                  b.toString(16).padStart(2,'0');
  if (Math.random()<.1) c = ['0','0','0'];
  let n = Math.floor(Math.random() * i + 2);
  drawTree(a,nx,ny,nl,w,a1,i-1,fac,scale,p,c);
}
function drawWind(t) {
  ctx.clearRect(0,0,600,400);
  let x = c.width/2; let y = c.height/2;
  c.fillStyle='#'+Math.floor(Math.random()*10).toString(16)
                    + Math.floor(Math.random()*10).toString(16)
                    + Math.floor(Math.random()*10).toString(16);
  ctx.fillRect(x,y,1,1);
  for (let i=0; i<10; i++) {
    let a = Math.PI * 2 * Math.random();
    let l = c.width/20;
    let xa = x + l * Math.cos(a), ya = y - l * Math.sin(a);
    ctx.beginPath(); ctx.moveTo(xa,ya); ctx.lineTo(x+Math.cos(t*wind)*l, y-Math.sin(t*wind)*l);
    if (t<0 || t>100) ctx.strokeStyle='black';
    else ctx.strokeStyle='#'+Math.floor(Math.random()*10).toString(16)
                          + Math.floor(Math.random()*10).toString(16)
                          + Math.floor(Math.random()*10).toString(16);
    ctx.lineWidth=2;
    ctx.stroke();
  }
  if (windmax-wind>1) wind+=windinc;
  else if (windmax-wind<-1) wind-=windinc;
  if (wind>30) { windmax = Math.floor(Math.random()*40)+20; windinc *= -1;}
  c.font='10px Arial';
  c.fillStyle='black'; c.fillText(`${Math.floor(t)}`, 10,10);
  c.fillText(`Depth: ${10}, Branches: ${9}`, 10,30);
  requestAnimationFrame(drawWind);
}
</script>
</body></html>
```
mistral-small:24bBLANKFORMAT
Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Fractal Tree</title>
<style>
body {margin: 0; overflow: hidden;}
canvas {display:block;}
</style>
</head>
<body>
<canvas id="treeCanvas"></canvas>
<script>
function Lsystem(axiom, rules, generations) {
this.axiom = axiom;
this.rules = rules;
this.generations = generations;
this.currentString = axiom;
for (let i = 0; i < generations; i++) this.generate();
}
Lsystem.prototype.generate = function() {
let nextString = '';
for (let c of this.currentString) nextString += this.rules[c] || c;
this.currentString = nextString;
};
function drawTree(canvas, ctx, instructions) {
let stack = [];
let pushState = {x: 0, y: 0, angle: 0};
for (let i = 0; i < instructions.length; i++) {
let cmd = instructions[i];
if (cmd === 'F') {
ctx.moveTo(pushState.x, pushState.y);
pushState.x += 10 * Math.cos(pushState.angle);
pushState.y -= 10 * Math.sin(pushState.angle);
ctx.lineTo(pushState.x, pushState.y);
} else if (cmd === '+') {
pushState.angle += Math.PI / 6;
} else if (cmd === '-') {
pushState.angle -= Math.PI / 6;
} else if (cmd === '[') {
stack.push({...pushState});
} else if (cmd === ']') {
pushState = stack.pop();
}
ctx.strokeStyle = '#008000';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(pushState.x, pushState.y);
ctx.stroke();
}
};
const canvas = document.getElementById('treeCanvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext('2d');
let lsystem = new Lsystem('F', {F: 'FF+[+F-F-F]-[-F+F+F]', '+': '+', '-': '-', '[': '[', ']': ']'}, 5);
let instructions = lsystem.currentString;
const branchCount = () => instructions.split('').filter(c => c === 'F' || c === '-' || c === '+').length
document.getElementById('treeCanvas').width = window.innerWidth;
 document.getElementById('treeCanvas').height = window.innerHeight;
drawTree(canvas, ctx, instructions);
let angle = 0;
let windStrength = 1;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
angle += windStrength * Math.PI / 360;
windStrength *= (Math.random() > 0.5) ? 1.1 : 0.9;
drawTree(canvas, ctx, instructions);
requestAnimationFrame(animate);
}
animate();
</script>
<body></html>
```
qwen3.5:9bERRBLANKLIMFORMAT
Show code
```html
<!DOCTYPE html>
<html><head><title>L-System Tree</title></head><style>body{margin:0;overflow:hidden;background:#111}{canvas{display:block}}#status{position:absolute;top:10px;left:10px;color:#ccc;font-family:monospace;padding:5px;background:#000b1133;border-radius:5px}</style><body><canvas id="treeCanvas"></canvas><div id="status">Generating...</div><script>
const canvas = document.getElementById('treeCanvas');
const ctx = canvas.getContext('2d');
let W, H;
function resize() {W=canvas.width=window.innerWidth;H=canvas.height=window.innerHeight;ctx.fillStyle='#000';ctx.fillRect(0,0,W,H); }
window.addEventListener('resize',resize);
resize();

const L_RULES = ['F', 'FF+[+F%-]']; // A classic fractal rule
let currentString = '';
let generation = 0;
let maxGenerations = 6;
let branchesDrawn = 0;
let isBuilding = true;
let animationTime = 0;

struct State {
    x: number, y: number, angle: number, length: number, stack: string[]
}

function initializeSystem() {
    currentString = L_RULES[0];
    generation = 0;
    branchesDrawn = 0;
    isBuilding = true;
    animationTime = 0;
    document.getElementById('status').innerHTML = `Generation: ${generation}/6 | Branches: 0`;
}

function expand() {
    if (generation >= maxGenerations) return false;
    currentString = "";
    for (const char of currentString) {
        if (char === 'F') { // Simple rewrite for this example
            currentString += L_RULES[1].replace(/[+%-]/g, '').split('').join(''); 
        } else if (L_RULES.includes(char)) {
             currentString = char;
        }
    }
    generation++;
    document.getElementById('status').innerHTML = `Generation: ${generation}/${maxGenerations} | Branches: ${branchesDrawn}`;

    if (generation < maxGenerations) {
        requestAnimationFrame(buildTree);
    } else {
        setTimeout(() => {
            isBuilding = false;
            document.getElementById('status').innerHTML = `Complete! Total Generations: ${generation}. Swaying...`;
            animateWind();
        }, 100);
    }
    return true;
}

function drawBranch(s) {
    const state = [];
    let p = { x: W/2, y: H-50 };
    let angle = -Math.PI / 2;
    state.push({...p, angle, length: 1}); // Initial state (root)

    for (let i = 0; i < s.length; i++) {
        const char = s[i];
        if (char === 'F') {
            const nextP = { x: p.x + Math.cos(angle) * p.length, y: p.y + Math.sin(angle) * p.length };
            p = nextP;
            ctx.strokeStyle = '#1a3300';
            ctx.lineWidth = 2;
            ctx.beginPath();
            ctx.moveTo(state[state.length - 1].x, state[state.length - 1].y);
            ctx.lineTo(p.x, p.y);
            ctx.stroke();

        } else if (char === '+') {
            // Increase angle (right)
            angle += Math.PI / 4;
        } else if (char === '-') {
            // Decrease angle (left)
            angle -= Math.PI / 4;
        } else if (char === '[') {
            state.push({...p, angle: angle, length: p.length}); // Push state
        } else if (char === ']') {
            const lastState = state.pop();
            p = {...lastState};
            angle = lastState.angle;
            // Recalculate position based on the popped state's origin
            state[state.length - 1].x = p.x + Math.cos(angle) * 0.5; // Simple correction for segment start
            state[state.length - 1].y = p.y + Math.sin(angle) * 0.5;

        } else if (char === '|') { 
             // This character is used as a marker for new segments/branches, handled by structure instead of simple append
        }
    }
}

let segments_in_progress = [];

function buildTree() {
    if (!isBuilding) return;

    const chars = currentString.split('');
    segments_in_progress = []; 

    // Simplified interpretation focusing on segment drawing logic rather than complex stack traversal for size constraints
    // We iterate through the string and store potential branches
    let p = { x: W/2, y: H-50 };
    let angle = -Math.PI / 2;
    const segments = [];

    for (let i = 0; i < chars.length; i++) {
        const char = chars[i];
        if (char === 'F') {
            segments.push({x: p.x, y: p.y, length: 10}); // Store start point and basic segment data
            p.x += Math.cos(angle) * 10;
            p.y += Math.sin(angle) * 10;
        } else if (char === '+') {
            angle += Math.PI / 4;
        } else if (char === '-') {
            angle -= Math.PI / 4;
        } else if (char === '[') {
             // In a real L-system, this would push the full state. Here we just track depth for branch counting.
             segments_in_progress.push(true);
        } else if (char === ']') {
             segments_in_progress.pop();
        }
    }

    if (!segments[0]) { // Initial draw phase needs to happen once per generation step
         ctx.clearRect(0, 0, W, H);
         ctx.save();
         // Simple drawing of the current state's path (approximation)
         let x = W/2; let y = H-50; let a = -Math.PI / 2;
         ctx.strokeStyle = '#1a3300';
         ctx.lineWidth = 4 * (generation > 0 ? 0.8 : 1);
         ctx.beginPath();
         ctx.moveTo(x, y);

         for(let i=0; i<chars.length; i++){
             const char = chars[i];
             if(char === 'F'){
                 x += Math.cos(a) * 10;
                 y += Math.sin(a) * 10;
                 ctx.lineTo(x, y);
             } else if (char === '+') { a += Math.PI/4; } 
             else if (char === '-') { a -= Math.PI/4; }
         }
         ctx.stroke();
    }

    // Increment branches drawn based on the complexity of the current structure
    branchesDrawn = Math.min(100 + generation * 5, 300);
}


function animateWind() {
    let t = animationTime;
    const windStrength = 0.02 + 0.01 * Math.sin(t / 400);

    ctx.clearRect(0, 0, W, H);
    ctx.save();
    ctx.translate(W/2, H - 150); // Base anchor point
    ctx.rotate(-Math.PI / 2); // Start pointing up

    // Recursive function to draw and apply wind physics
    function drawAndSway(segment, angleOffset, scale) {
        if (scale < 0.1) return;

        const length = segment.length * scale;
        ctx.strokeStyle = `rgba(26, 51, 0, ${scale*0.8 + 0.2})`;
        ctx.lineWidth = Math.max(1, 3 * scale);
        
        // Apply wind influence (horizontal force proportional to time and scale)
        const swayX = length * Math.sin(angleOffset * 0.5 + t / 400 * windStrength);
        const swayY = length * Math.cos(angleOffset * 0.5 + t / 400 * windStrength);

        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(swayX, swayY);
        ctx.stroke();

        // Recursive calls (simplified tree branching structure)
        if (segment.branches && segment.branches.length > 0) {
            for (let i = 0; i < segment.branches.length; i++) {
                const b = segment.branches[i];
                drawAndSway(b, angleOffset + b.angle * scale / Math.max(1, scale), scale * 0.6);
            }
        }
    }

    // Since we don't store the full tree structure for physics in this size-constrained version, 
    // we just draw a simplified visualization based on generation count.
    const simSegments = [];
    for(let i=0; i<generation; i++){
        simSegments.push({length: Math.pow(10, -i*0.2), branches: Array(Math.min(5, 3+i)).fill({})});
    }

    drawAndSway(simSegments[0] || {length: 10}, 0, 1);
    ctx.restore();


    animationTime += 16; // Assuming ~60fps frame rate
    requestAnimationFrame(animateWind);
}


function run() {
    initializeSystem();
    // Step-by-step building animation loop
    const buildTree = () => {
        if (generation < maxGenerations) {
            buildTree();
        } else {
            setTimeout(() => {
                isBuilding = false;
                animateWind();
            }, 100);
        }
    };
    requestAnimationFrame(buildTree);
}

run();
</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.
qwq:32bSTATLIM
Show code
<think>

Okay, I need to create a self-contained HTML file that draws a fractal tree using L-systems. The user wants it to grow branch by branch, then sway with wind, show generation depth and branch count, use requestAnimationFrame, and restart automatically. Let me think through the steps.

First, the L-system setup. The axiom is probably something like F, with rules like F → F[+F][-F]. The angle and parameters need to be defined. Each generation expands the string, so I'll need a function to apply the rewriting rules over multiple generations.

Next, drawing on a canvas. I'll need to use 2D context. The tree starts at the bottom, so maybe draw upwards. Each F is a line segment. The brackets [ and ] save and restore the state (position and angle) to handle branches.

The animation should have two phases: growing the tree incrementally and then swaying. For growing, I'll need to track the current step, drawing up to that point each frame until the full string is drawn. Then switch to the swaying phase.

Wind effect: the angle of each branch can be adjusted slightly based on a sine wave or similar function that changes over time, creating a swaying motion. The wind strength could vary sinusoidally over time to make it look natural.

Generation depth and branch count: need to count how many times the rule is applied (generations) and the number of branches, which is the number of F's in the final string? Or maybe the number of segments? Not sure yet. Maybe parse the string to count F's.

RequestAnimationFrame loop: the main loop that runs the animation. It should handle both phases. When in growth phase, each frame increments the step until it reaches the length of the string. Then, enters the swaying phase where it updates angles based on wind.

Restarting: after swaying for a while, reset everything—generate a new L-system string with a random seed? Or just randomize parameters? Wait, the user said "fresh random instance", so maybe change the angle or some part of the rule? Hmm, perhaps the starting angle or some parameters can be randomized each time. Alternatively, just rerun the setup with new parameters. Maybe the initial angle or the wind parameters can be randomized each restart.

Canvas size: set to full window initially, but maybe fixed. Let's go with fixed for simplicity, like 600x600.

Variables I need: current generation, current string, angle, step for growth, wind strength over time.

Structure outline:

- HTML with canvas element and meta tags.
- JavaScript in script tags:
  - Setup variables: ctx, canvas size, currentGen, currentString, angle, step, generationCount, branchCount, etc.
  - L-system functions: generateString based on generations, expanding each step.
  - Drawing functions: parse the string, handle F, +, -, [, ] commands. For each F, draw a line, then maybe in growth phase only draw up to step.
  - Wind function: modulate the angle based on time and a sine wave.
  - Animation loop: animate() handles the requestAnimationFrame loop. Toggles between growth and sway phases, updates the display.
  - Restart: after sway phase, reset variables and regenerate the string with new parameters (maybe new angle or rule variation? Or just a different random seed).

Wait, the user specified "fresh random instance"—maybe the starting parameters like the initial angle or the angle of branching can be randomized each restart. So on each restart, the tree might have a slightly different structure or angle.

Wait, the L-system rules might stay the same, but maybe the angle parameter can be randomized? The angle in the L-system is part of the production rules. Or perhaps the starting angle of the tree (like the initial direction) can be randomized each time. Alternatively, the number of generations can vary? Hmm, the user wants to show the generation depth, so maybe generations are fixed but the initial direction is randomized. Or maybe the generations are fixed, and each restart uses the same number of generations but different random parameters like angle.

Alternatively, the generation depth could be randomized each time, but the user says "show the generation depth". So perhaps the generation count is a parameter that is fixed per instance, but varies each time? Maybe the generations are set to a random value between, say, 4 to 7 each time. But the user example might have a fixed number, like 7 generations. Wait, the user hasn't specified, so perhaps I should just set a fixed generation, but when restarting, randomly change it. Let me think again.

The main points are: the HTML must be self-contained, under 7000 characters. The code needs to be efficient. Let me proceed step by step.

First, the L-system setup:

Axiom: F

Rules: F → F[+F][-F] (assuming this produces a binary tree, each F splits into two branches with angle changes). The angle for + and - would be something like 25 degrees, but radians are better for calculations.

The growth phase: each frame draws one more character in the string, so step is the current index up to which to draw.

Drawing: Each F draws a line forward, then turns left/right when + or -, and [ saves the current state (position and angle), ] restores.

Wind: during the sway phase, the angle of each segment is adjusted by a small delta based on a sine wave, making the branches move. The angle delta could be something like sin(time * speed) * strength, where strength decreases over time.

Now, the code structure.

Variables:

- ctx: canvas context
- canvas: the canvas element
- generationCount: number of generations (maybe 5?)
- step: current drawing step (starts at 0, increments each frame until reaches string length)
- currentGen: the current string
- angle: the turning angle (e.g., 25 degrees converted to radians)
- windTime: time variable for wind effect
- isGrowing: flag to indicate phase

Functions:

generateString(generations) to build the string from axiom. Each iteration applies the rules to each character.

The drawing function would parse the string, and for each character, decide how to draw. In growth phase, stops at step.

The stack for handling branches: stack saves the current position and angle.

Wind effect: during sway phase, when drawing each F, add a slight angle adjustment based on sin(windTime) or similar.

Now, putting it all together in code.

Wait, the code must be as concise as possible. Let me outline the variables and functions.

In the script:

var ctx, canvas, gen = 5, step = 0, currentString = '', angle = Math.PI * 25 / 180, windTime = 0, isGrowing = true, branchCount = 0;

Wait, but branch count is needed. Hmm, maybe count the number of F's in the string. Or during parsing, count each F.

Wait, in the L-system string, each F is a segment, so the number of branches could be the number of F's. But actually, each F might be part of a branch. Alternatively, each [ ] pair creates a new branch. Hmm, perhaps the branch count can be counted as the number of F's in the string, but that might overcount. Alternatively, the number of segments. Let me think, the initial F becomes F[+F][-F], so each F in the rule becomes three F's (the original F plus two in the brackets). So after n generations, the number of F's is 2^n * initial? Not sure, but maybe it's easier to just count the number of F's in the string when generated.

So, when generating the string, count the number of 'F's.

In the generateString function:

function generateString(gens) {
  let str = 'F';
  for(let g=0; g<gens; g++) {
    let newStr = '';
    for(let c of str) {
      if(c == 'F') newStr += 'F[+F][-F]';
      else newStr += c;
    }
    str = newStr;
  }
  branchCount = (str.match(/F/g) || []).length;
  return str;
}

Wait, but this is for a specific rule. The user's rule might be like F → F[+F][-F], so every F is replaced with that. So over generations, this creates a binary tree each time.

Now, the drawing function:

We need a stack to handle the [ and ] commands. The state (x, y, angle) must be stored when [ is encountered and restored when ].

Let me outline the draw function:

function draw() {
  // reset canvas
  ctx.clearRect(0, 0, cw, ch);
  ctx.strokeStyle = '#2c5';
  ctx.lineWidth = 0.5;
  ctx.beginPath();
  let stack = [];
  let x = cw/2, y = ch - 50; // starting at base
  let angle = 0; // initial direction upward is negative y?
  let len = 5; // length of each segment
  let currentStep = step;
  let str = currentString;
  ctx.moveTo(x, y);
  for(let i=0; i<str.length && i<=currentStep; i++) {
    let c = str[i];
    switch(c) {
      case 'F':
        let nx = x + Math.cos(angle) * len;
        let ny = y - Math.sin(angle) * len; // assuming angle is direction upwards?
        ctx.lineTo(nx, ny);
        ctx.stroke();
        x = nx; y = ny;
        break;
      case '+':
        angle += this.angle; // wait, this.angle is the fixed angle (25 degrees)
        break;
      case '-':
        angle -= this.angle;
        break;
      case '[':
        stack.push({x:x, y:y, angle:angle});
        break;
      case ']':
        let s = stack.pop();
        x = s.x; y = s.y; angle = s.angle;
        ctx.beginPath();
        ctx.moveTo(x, y);
        break;
    }
  }
  // After drawing, maybe update step if in growth phase
}

Wait, but this code is inside the animation loop. Also, the direction may need to be adjusted for the wind in the sway phase.

Hmm, perhaps in the sway phase, each segment's angle is adjusted by a wind delta.

Alternatively, during drawing each segment, if in sway phase, we add an angle perturbation based on time.

Wait, but that would require tracking each segment's path. Maybe it's too complex for a simple approach. Alternatively, during the sway phase, each branch's angle is adjusted by a sine wave, so when drawing, the angle is modified by sin(windTime) * some strength.

Alternatively, perhaps when in sway phase, the angle for each F is modified.

But this might require tracking each segment's angle and position, which complicates the code.

An alternative approach for wind: when drawing each F, instead of using the original angle, add a small random angle. But over time, the random angle could be a function of time, so it's sine based.

Alternatively, add a variable windDelta that oscillates based on time.

Let me think of the overall structure:

The animation loop function animate():

function animate() {
  if(isGrowing) {
    if(step < currentString.length) {
      step++;
      // draw up to step
    } else {
      isGrowing = false;
      // start swaying
      step = 0; // maybe not needed
    }
  } else {
    // sway phase: update angles with wind
    // but how?
  }
  // drawing code here
  // then draw the text for generation and branches
  ctx.fillText(`Gen: ${gen} | Branches: ${branchCount}`, 10, 20);
  requestAnimationFrame(animate);
}

Wait, but in the drawing phase, during the sway phase, each segment's angle is changed by some function.

Alternatively, during the sway phase, each turn (like + and -) has an added angle based on time.

Hmm, perhaps to simplify, during sway phase, we can introduce a small delta to the angle when drawing each segment. For example, each time we draw a segment, the angle is adjusted by Math.sin(windTime) * windStrength, where windTime increments each frame.

Wait, but how to track the angle changes properly. Maybe in the drawing loop, when in sway phase, each F's direction is perturbed by a value that depends on the current wind.

Alternatively, when drawing each F, the angle is the original angle plus a perturbation based on time and the position in the string.

Alternatively, just have a global variable that adds a sine wave to the angle, so all angles are shifted slightly. But that might not look natural.

This might be getting too complicated for the character limit. Maybe the wind can be a simple oscillation of the base angle.

Another idea: in the sway phase, the initial angle (the direction the tree is growing) is set to a base angle plus a sine wave. For example, the initial angle (the starting direction) is 90 degrees (up), but during sway, it's 90 + Math.sin(windTime) * 10 degrees. This way, the entire tree sways left and right. But that might not look like wind affecting individual branches.

Alternatively, each branch has its own perturbation based on their depth in the stack. Maybe higher branches sway more? Not sure.

Alternatively, during the sway phase, each segment's angle is adjusted by a small amount. To do this, perhaps during drawing each segment, after calculating the angle, add a delta. The delta could be based on windTime and the length of the string. For example, delta = Math.sin(windTime + i * 0.1) * 2; where 'i' is the current index in the string. This would make each segment's angle oscillate slightly, creating a wind effect.

But this requires modifying the angle while drawing each segment. Let me see:

In the draw loop:

for each character:

if sway phase:

angle += Math.sin(windTime + i) * 0.1; // adjust angle

Wait, but this would have to be part of the angle calculation for each segment.

Alternatively, in the sway phase, when drawing each F, the angle is adjusted by a small value that changes over time.

Hmm, maybe the following approach:

During the sway phase, each F command has its angle perturbed by a value that depends on the current time and the position of the character in the string. So, for each F at position i in the string, the angle is:

alpha = original_angle + Math.sin( windTime + i * 0.1 ) * 5 * Math.sin(windTime * 0.3);

This way, each segment has a small variation based on its position and the overall wind time.

Alternatively, the perturbation could be a function of the current time and some random value for that segment, but without storing data for each segment.

Alternatively, the entire tree's angle can be modulated by a sine wave, making the whole tree sway back and forth. That's simpler:

In the sway phase:

var swayAngle = Math.sin(windTime) * 5 * Math.PI / 180; // 5 degrees

Then, when calculating the direction for each segment's movement, add this swayAngle to the angle.

Wait, but the initial direction is upwards. Let me think about the coordinate system:

Assuming the canvas has (0,0) at top-left. So, moving upwards is negative Y direction.

The initial angle is 0 radians (pointing to the right?), but we want to draw upwards. Wait, perhaps the initial direction should be upwards, so the angle is π/2 radians (90 degrees). So the initial angle when drawing is π/2, meaning moving upwards.

So, each 'F' moves in the direction of the current angle.

So, the sway would be adding a small angle to the base angle.

Wait, in the sway phase, for each F's drawing, the angle is the original angle plus a sine wave component.

So during the sway phase, when drawing each F:

nx = x + Math.cos(angle + swayDelta) * len;
ny = y - Math.sin(angle + swayDelta) * len;

where swayDelta is based on windTime.

Alternatively, in code:

In the animate function, during sway phase:

swayDelta = Math.sin(windTime) * (Math.PI * 5 / 180); // 5 degrees sine wave
windTime += 0.01; // increases over time

Then, in the draw loop:

if (isGrowing) {
  // normal drawing
} else {
  // sway phase
  // modify angle for each segment's direction
  // but how?

Wait, perhaps adding the swayDelta to the angle each time. Wait, no, because the angle is being tracked for each segment's direction. So when in sway phase, every turn (+ or -) is still normal, but the base direction is perturbed.

Alternatively, the swayDelta is added to the initial angle and also to each turn's angle? Not sure. This is getting a bit tangled.

Perhaps a simpler way: when in sway phase, add a small random angle to each segment's direction. The random angle is a function of the current time and the position in the string.

Alternatively, just have the entire tree sway left and right by adding a sine wave to the base angle.

Let me try this approach:

In the animate function:

windTime += 0.02; // increases each frame

then, in the drawing loop:

if (!isGrowing) {
  const swayAngle = Math.sin(windTime) * Math.PI * 0.2; // 12 degrees
  angle += swayAngle;
}

Wait, but angle is the current direction of the segment. So maybe before calculating nx and ny, add the swayAngle to the current angle.

Wait, but angle is the accumulated angle from turns and the initial direction.

Hmm, this might be too confusing. Let me think of a base direction.

The initial angle is π/2 (up). During the sway phase, this is adjusted by a sine wave.

Wait, perhaps the sway is applied to the initial direction. For example:

In the draw function, when starting to draw, set the initial angle to π/2 + Math.sin(windTime) * 0.2 radians.

This would make the entire tree sway left and right. That's simple and might look okay for the effect.

Let me try to implement that:

Inside the draw loop:

if (isGrowing) {
  // normal drawing
} else {
  // add sway to the initial angle
  const baseAngle = Math.PI/2;
  const swayAngle = Math.sin(windTime) * 0.2; // 0.2 radians is about 11 degrees
  angle = baseAngle + swayAngle;
}

Wait, but angle is being changed by '+' and '-' commands in the string. The initial angle for the first segment is set by this, but subsequent turns would still add/subtract the fixed angle.

Hmm, perhaps the sway is only applied to the initial angle, so that the entire tree's main stem sways, while the branches continue to have their relative angles.

Alternatively, the entire tree's base angle is swayed, so all angles are offset by the swayAngle.

This would mean that every turn (like '+') would be relative to the base angle plus the swayAngle.

Hmm, perhaps the sway should be added to the angle variable when starting the drawing.

Wait, in the draw function:

// starting angle is π/2 (up)
let angle = Math.PI/2;

if (!isGrowing) {
  angle += Math.sin(windTime) * 0.2;
}

Then, as the drawing progresses, the angle is modified by '+' and '-' as usual.

This way, the entire tree's direction is offset by the sway, while the relative angles of the branches remain the same.

This might produce a good effect.

So during the sway phase, the entire tree sways left and right, which can look like wind.

This approach is simpler and might work within the character limit.

Now, putting all this together.

First, the setup:

We need to:

1. Generate the L-system string for the fractal plant.
2. Draw the fractal, either growing step by step or swaying.
3. Display generation and branch count.

But since the problem says "Create an algorithm to visualize a fractal using an L-system where the fractal appears to sway under the influence of wind", maybe the L-system is predefined as a plant.

Typically, a plant-like L-system has rules like:

Variables : X F
Constants : + −
Start : X
Rules : (X → F+[[X]-X]-F[-FX]+X), (F → FF)
Angle : 25 degrees.

But to simplify, maybe use a simpler example.

Alternatively, let's set up a simple L-system for a fractal plant:

Start: F
Rules:
F → F+F--F+F

This creates a Koch-like curve, but maybe not a plant. Alternatively, use the standard:

Start: F
Rules: F → F[-F]F[+F]F

With angle 25 degrees. That might create a fractal plant structure.

But for simplicity, maybe use a simpler example, but the exact L-system might not be critical here. The key is to have the fractal draw step by step and then sway.

But given the problem, perhaps the user expects the code to be in JavaScript (since it mentions canvas), but the question is to write the algorithm, not the code. Wait, the user says "Create an algorithm to visualize a fractal using L-system...", so the answer should outline the steps, not code.

Wait, the initial instruction says "put your final answer within \boxed{}". Maybe the user wants the algorithm steps outlined, but given the mention of "sway under the influence of wind", and L-systems, perhaps a code sketch.

Wait the user might have intended to get an algorithm description. Let me read again the problem.

The user says:

"Create an algorithm to visualize a fractal using an L-system where the fractal appears to sway under the influence of wind. The algorithm should include steps for generating the fractal using an L-system, rendering it on a canvas, and applying a wind-like motion effect using trigonometric functions."

So the algorithm must have three parts: generating the fractal with L-system, rendering, and applying wind effect.

So steps could be:

1. **Generate the fractal using an L-system:**
   a. Define the L-system with an axiom (starting string), rules, and angle.
      Example: Axiom = "F", Rules: F → F[-F][+F], Angle = 25°
   b. Iteratively apply the rules for a certain number of iterations to generate the final string.

2. **Rendering the fractal on a canvas:**
   a. Initialize a canvas element with a drawing context.
   b. Parse the generated string and interpret each character to draw lines and turn directions.
   c. Use trigonometry to calculate the direction of each line segment based on the current angle.
   d. Start at a base position (e.g., center bottom of the canvas).

3. **Apply wind-like motion effect:**
   a. Introduce a time-dependent variable (e.g., windTime) that increases over time.
   b. For each line segment, perturb its direction by a small random angle or a sine function dependent on windTime and the segment’s position.
   c. The perturbation should create a swaying motion, possibly animating the fractal by redrawing each frame with updated angles.

But to be more precise, the algorithm needs to outline how the wind effect is applied.

Alternatively, here's a more detailed algorithm:

ALGORITHM:

**Initialization:**
1. Define the L-system parameters:
   - Axiom: "F"
   - Rules: 
     - F → F[+F]F[-F][F]
     - (Or another suitable rule for branching)
   - Angle: 25 degrees
   - Iterations: 4 (adjustable)
   - Start position: (canvasWidth/2, canvasHeight)
   - Start direction: π/2 radians (upward)

2. Generate the L-system string through iterative substitution:
   a. Start with the axiom.
   b. For each iteration, replace each character in the string according to the rules.

**Rendering and Animation:**
3. Set up a canvas context and animation loop (e.g., using requestAnimationFrame).

4. In each frame:
   a. Clear the canvas.
   b. Calculate the wind effect by a sine wave function of time:
      - windAngle = sin(currentTime * speed) * amplitude
      (e.g., amplitude is 0.2 radians, speed is 0.01)
   c. Parse the L-system string to draw the fractal:
      i. Maintain a stack for saving positions and angles (for branches).
      ii. For each character in the string:
          - 'F': draw a line forward, updating current position.
          - '+': turn clockwise by angle + windAngle (or apply sway)
          - '-': turn counterclockwise by angle - windAngle
          - '[': push current state (position, angle) to stack
          - ']': pop state from stack, reset to that position and angle
      iii. Apply the wind sway by adding windAngle to all turning angles or the initial direction.

   d. Draw the fractal based on the current windAngle.

**Wind Effect Implementation:**
5. To simulate swaying:
   a. The primary angle (direction of the fractal’s main stem) is offset by windAngle, which oscillates over time.
   b. Alternatively, each segment’s turn may have a slight random variation to mimic wind turbulence.

**Optional Enhancements:**
- Increase the effect based on the depth of recursion (higher branches sway more).
- Use a noise function for more natural-looking motion.

This provides a structured approach to achieve the requirements. The key idea is to modulate the direction angles with a time-varying sine function to create the illusion of wind.

Since the problem asks for the algorithm, here's the boxed answer summarizing the key steps:

The algorithm involves:
1. **L-system Initialization**: Define axiom, rules, angle, and iterations.
2. **String Generation**: Expand the axiom using rules for the specified iterations.
3. **Rendering with Wind Effect**: 
   a. In each frame, compute a wind angle using a trigonometric function of time.
   b. Parse the L-system string, applying the wind angle perturbation to direction changes to simulate swaying.
   c. Draw the fractal on the canvas, updating the wind angle over time for animation.

Final Answer:
\boxed{
\begin{aligned}
&\textbf{1. L-system Setup:} \\
&\quad \text{Define axiom, rules, angle, and iterations.} \\
&\textbf{2. Fractal Generation:} \\
&\quad \text{Expand axiom iteratively using rules.} \\
&\textbf{3. Rendering with Wind Sway:} \\
&\quad \text{For each frame:} \\
&\quad\quad \text{Compute wind angle as } \sin(\text{time} \times \text{speed}) \times \text{amplitude}. \\
&\quad\quad \text{Parse L-system string, adjusting angles with wind effect.} \\
&\quad\quad \text{Draw fractal using canvas, updating angles dynamically.}
\end{aligned}
}
deepseek-r1:32bBLANKFORMAT
Show code
```html
<!DOCTYPE html><canvas id="c"></canvas><div id="i" style="position:absolute;top:10px;left:10px;color:#fff;font-family:monospace;"></div><script>
const c=document.getElementById("c"),ctx=c.getContext("2d");
let generations=0,branches=0,maxGen=5,t=0,lastTime=0;
let stack=[],rules={F:"FF+[+F-F]-[-F+F]",'+':"+",'-':'-'};
let production="F",angle=15*Math.PI/180,len=10,windOffset=0;

c.width=window.innerWidth,c.height=window.innerHeight;
ctx.lineCap='round';
let x=c.width/2,y=c.height-100,dx=0,dy=-len;save=()=>stack.push({x,y,dx,dy});restore=()=>{
let s=stack.pop();
x=s.x,y=s.y,dx=s.dx,dy=s.dy;
};

function produce(s){return s.split('').map(c=>rules[c]||c).join('');}
function drawBranch(l){
if(generations<maxGen||branches<1)ctx.beginPath(),ctx.moveTo(x,y);
switch(l){
case'F':ctx.lineTo(x+dx*l,y+dy*l);x+=dx*l;y+=dy*l;break;
case'+':save(),dx=Math.cos(angle),dy=-Math.sin(angle);break;
case'-':save(),dx=Math.cos(-angle),dy=-Math.sin(-angle);break;
default:break;
}
ctx.strokeStyle='#4d3b1c';
}

function animate(t){
requestAnimationFrame(animate);
let dt=t-lastTime;lastTime=t;
if(generations<maxGen&&t>500*generations){
generations++;
production=produce(production);
branches=production.match(/F/g).length;
}
if(generations>=maxGen){
windOffset=Math.sin(t/100)*2;
for(let i=0;i<stack.length;i++){
let s=stack[i];
s.angle+=Math.cos(windOffset+i*.5)*.1;
dx=Math.cos(s.angle),dy=-Math.sin(s.angle);
}
}
ctx.clearRect(0,0,c.width,c.height);
ctx.save();
x=c.width/2,y=c.height-100,dx=0,dy=-len;stack=[];branches=0;
production.split('').forEach(c=>drawBranch(c));
if(generations<maxGen){
generations++;
}else{
windOffset+=dt*.05;
}
document.getElementById("i").innerHTML=`Generation: ${Math.min(maxGen,generations)}\nBranches: ${branches}`;
if(generations>=maxGen&&t>lastTime+1000*60){reset();}
}

function reset(){
generations=0;branches=0;stack=[];production="F";angle=15*Math.PI/180+len*(Math.random());
x=c.width/2,y=c.height-100,dx=0,dy=-len;
lastTime=t;maxGen=3+Math.floor(Math.random()*4);
}

reset();
animate(0);
</script>
```
command-r:35bBLANK
Show code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Fractal Tree</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <canvas id="fractal-tree"></canvas>

    <script>
        const LSystem = {
            axiom: 'X',
            rules: {
                X: 'F+[[X]+]FX--FX',
                F: 'FF'
            },
            angle: Math.PI / 3, // Angle between branches
            stepSize: 50,       // Length of each branch segment
        };

        class Node {
            constructor(x, y) {
                this.x = x;
                this.y = y;
                this.dx = Math.cos(LSystem.angle);
                this.dy = Math.sin(LSystem.angle);
                this.branches = [];
            }

            addBranch() {
                const branch = new Node(this.x, this.y + LSystem.stepSize);
                this.branches.push(branch);
                return branch;
            }
        }

        function drawTree(context, node, generation) {
            context.save();
            context.translate(node.x, node.y);

            if (generation === 0) {
                // Draw stem
                context.beginPath();
                context.moveTo(0, 0);
                context.lineTo(0, -LSystem.stepSize * 2);
                context.strokeStyle = 'black';
                context.lineWidth = 5;
                context.stroke();
            } else {
                // Draw branches
                for (const branch of node.branches) {
                    drawTree(context, branch, generation - 1);
                }
            }

            context.restore();
        }

        function animate() {
            const canvas = document.getElementById('fractal-tree');
            const context = canvas.getContext('2d');

            let currentRule = LSystem.rules[LSystem.axiom];
            let generations = 0;
            let nodes = [new Node(canvas.width / 2, canvas.height)];

            function growTree() {
                for (const char of currentRule) {
                    if (char === 'F') {
                        const newNode = nodes[nodes.length - 1].addBranch();
                        drawTree(context, newNode, generations);
                    } else if (char === '+') {
                        nodes[nodes.length - 1].dx += Math.cos(LSystem.angle);
                        nodes[nodes.length - 1].dy += Math.sin(LSystem.angle);
                    } else if (char === '-') {
                        nodes[nodes.length - 1].dx -= Math.cos(LSystem.angle);
                        nodes[nodes.length - 1].dy -= Math.sin(LSystem.angle);
                    } else if (char === '[') {
                        nodes.push(new Node(0, 0));
                    } else if (char === ']') {
                        const parent = nodes.pop();
                        nodes[nodes.length - 1].x += parent.dx * LSystem.stepSize;
                        nodes[nodes.length - 1].y += parent.dy * LSystem.stepSize;
                    }
                }

                generations++;
            }

            function swayTree() {
                const windStrength = Math.random() * 0.2 + 0.5; // Wind strength between 0.5 and 0.7
                for (const node of nodes) {
                    node.x += (Math.random() - 0.5) * windStrength;
                    node.y += (Math.random() - 0.5) * windStrength;
                }
            }

            function updateAndDraw() {
                growTree();  // Grow the tree with one generation
                swayTree(); // Sway the tree in the wind

                context.clearRect(0, 0, canvas.width, canvas.height);
                drawTree(context, nodes[0], generations);  // Draw the current state of the tree

                requestAnimationFrame(updateAndDraw);
            }

            updateAndDraw();
        }

        animate();
    </script>
</body>
</html>
Outside the Brain cluster — same task, same character budget, collected through their own tooling (response times not comparable)
Claude Opus 5frontier referenceOK
Show code
<!doctype html>
<html><head><meta charset="utf-8"><title>L-system tree in wind</title>
<style>
html,body{margin:0;height:100%;background:#0a0d14;overflow:hidden}
canvas{display:block;width:100vw;height:100vh}
#hud{position:fixed;left:12px;top:11px;font:13px ui-monospace,monospace;color:#d8e8c8;
background:rgba(8,12,20,.6);padding:5px 9px;border-radius:5px}
</style></head><body>
<canvas id="c"></canvas><div id="hud">depth 0</div>
<script>
const cv=document.getElementById('c'),g=cv.getContext('2d'),hud=document.getElementById('hud');
let W,H;
function fit(){W=cv.width=innerWidth;H=cv.height=innerHeight}
fit();addEventListener('resize',fit);

const DEPTH=5,ANGLE=24*Math.PI/180;
let word='F';
for(let i=0;i<DEPTH;i++){
  let out='';
  for(const ch of word) out += ch==='F' ? 'F[+F]F[-F]F' : ch;
  word=out;
}

function build(wind){
  const segs=[];
  const step=Math.min(W,H)*.012;
  let x=W/2,y=H*.97,ang=-Math.PI/2,depth=0;
  const stack=[];
  for(const ch of word){
    if(ch==='F'){
      const nx=x+Math.cos(ang)*step, ny=y+Math.sin(ang)*step;
      segs.push([x,y,nx,ny,depth]);
      x=nx;y=ny;
    } else if(ch==='+'){ ang+=ANGLE+wind*(depth+1)*.06; }
    else if(ch==='-'){ ang-=ANGLE-wind*(depth+1)*.06; }
    else if(ch==='['){ stack.push([x,y,ang,depth]); depth++; }
    else if(ch===']'){ const s=stack.pop(); x=s[0];y=s[1];ang=s[2];depth=s[3]; }
  }
  return segs;
}

let grown=0,t0=0;
function frame(t){
  if(!t0)t0=t;
  const el=(t-t0)/1000;
  const wind=Math.sin(el*.9)*.6+Math.sin(el*2.3)*.25;
  const segs=build(grown>=1?wind:0);

  if(grown<1) grown=Math.min(1,grown+.006);
  const show=Math.floor(segs.length*grown);

  g.fillStyle='#0a0d14';g.fillRect(0,0,W,H);
  for(let i=0;i<show;i++){
    const s=segs[i],d=s[4];
    g.strokeStyle='hsl('+(95+d*14)+','+(38+d*8)+'%,'+(26+d*11)+'%)';
    g.lineWidth=Math.max(1,4-d*.7);
    g.beginPath();g.moveTo(s[0],s[1]);g.lineTo(s[2],s[3]);g.stroke();
  }

  hud.textContent='depth '+DEPTH+'  ·  branches '+show+'/'+segs.length
    +(grown<1?'  · growing':'  · wind '+wind.toFixed(2));
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
</script></body></html>
GPT-5.5 (Codex)frontier referenceOK
Show code
<!doctype html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Fractal Tree</title><style>html,body{margin:0;height:100%;overflow:hidden;background:#07110d;color:#d7ead5;font:16px system-ui}canvas{display:block;width:100%;height:100%}#i{position:fixed;left:16px;top:14px;background:#0007;padding:8px 11px;border-radius:6px;line-height:1.35;backdrop-filter:blur(4px)}</style></head><body><canvas id=c></canvas><div id=i></div><script>
const c=document.getElementById("c"),x=c.getContext("2d"),i=document.getElementById("i");let W,H,D,S,segs,n,b,done,wait,t0,wind,seed;
function R(a,b){return a+Math.random()*(b-a)}
function fit(){W=c.width=innerWidth*devicePixelRatio;H=c.height=innerHeight*devicePixelRatio;x.setTransform(devicePixelRatio,0,0,devicePixelRatio,0,0)}
onresize=fit;fit();
function make(){
 D=5+(Math.random()*3|0);let s="X",r=["F[+X][-X]FX","F[-X][+X]F[+X]","FF-[-X+X]+[+X-X]"];
 for(let g=0;g<D;g++)s=s.replace(/[FX]/g,m=>m=="X"?r[Math.random()*r.length|0]:"FF");
 S=s;segs=[];b=0;n=0;done=0;wait=0;t0=performance.now();wind=0;seed=R(0,9);
 let st=[],px=innerWidth/2,py=innerHeight*.94,a=-Math.PI/2,L=Math.min(innerWidth,innerHeight)*(.105/(D*.55)),ang=R(.35,.55);
 for(let k=0;k<S.length;k++){let ch=S[k];if(ch=="F"){let qx=px+Math.cos(a)*L,qy=py+Math.sin(a)*L;segs.push([px,py,qx,qy,a,L,b++]);px=qx;py=qy;L*=.992}else if(ch=="+")a+=ang+R(-.08,.08);else if(ch=="-")a-=ang+R(-.08,.08);else if(ch=="[")st.push([px,py,a,L]);else if(ch=="]")[px,py,a,L]=st.pop()}
}
function bg(t){let g=x.createLinearGradient(0,0,0,innerHeight);g.addColorStop(0,"#07110d");g.addColorStop(1,"#132019");x.fillStyle=g;x.fillRect(0,0,innerWidth,innerHeight);x.fillStyle="#ffffff10";for(let k=0;k<45;k++){let y=(k*73+t*.01)%innerHeight;x.fillRect((k*97+seed*31)%innerWidth,y,1,1)}}
function draw(t){
 bg(t);let grow=Math.min(1,(t-t0)/6500);if(done)wind=(Math.sin(t*.0007)+Math.sin(t*.0013+seed))*9;
 n=Math.floor(segs.length*grow);x.lineCap="round";
 for(let k=0;k<segs.length;k++){let e=segs[k],show=k<n?1:k==n?segs.length*grow-n:0;if(show<=0)break;let dep=e[6]/segs.length,sw=done?Math.sin(t*.002+dep*10+seed)*wind*dep:0,dx=(e[2]-e[0])*show,dy=(e[3]-e[1])*show;
 x.strokeStyle=k<segs.length*.45?"#7b5232":"#6fb36c";x.lineWidth=Math.max(.7,(1-dep)*7);x.beginPath();x.moveTo(e[0]+sw*.2,e[1]);x.lineTo(e[0]+dx+sw,e[1]+dy);x.stroke()}
 i.innerHTML="Generation: "+D+"<br>Branches: "+Math.min(n,segs.length)+" / "+segs.length;
 if(grow>=1&&!done){done=1;wait=t}if(done&&t-wait>9000)make();
 requestAnimationFrame(draw)
}
make();requestAnimationFrame(draw);
</script></body></html>
Claude Sonnet 5frontier referenceOK
Show code
<!DOCTYPE html><html><head><meta charset="utf8"><title>L-System Tree</title><style>
body{margin:0;background:#0b1220;overflow:hidden}canvas{display:block}
#i{position:fixed;top:8px;left:8px;color:#dfd;font:14px monospace}
</style></head><body><canvas id="c"></canvas><div id="i"></div><script>
const cv=document.getElementById('c'),ctx=cv.getContext('2d');
function resize(){cv.width=innerWidth;cv.height=innerHeight}
resize();addEventListener('resize',resize);
let str,depth,branchCount,drawIdx,phase,windT,angInc,lenBase,seed;
function lsystem(){
  const rules={};
  rules['F']=Math.random()<0.5?'F[+F]F[-F]F':'F[+F][-F]F[+F]';
  depth=4+Math.floor(Math.random()*3);
  angInc=18+Math.random()*16;
  let s='F';
  for(let i=0;i<depth;i++){
    let ns='';
    for(const ch of s) ns+= (ch==='F'?rules['F']:ch);
    s=ns;
  }
  return s;
}
function build(){
  str=lsystem();
  lenBase=Math.max(6,90/Math.pow(1.55,depth));
  branchCount=(str.match(/F/g)||[]).length;
  drawIdx=0; phase='grow'; windT=0;
  seed=Math.random()*1000;
}
function walk(maxDraw,sway){
  const stack=[];
  let x=cv.width/2,y=cv.height,ang=-90,len=lenBase*7,d=0,drawn=0;
  const out=[];
  for(const ch of str){
    if(ch==='F'){
      if(drawn>=maxDraw) break;
      const s2=sway?Math.sin(windT*1.4+d*0.5+seed)*sway*(d+1)*1.2:0;
      const rad=(ang+s2)*Math.PI/180;
      const nx=x+Math.cos(rad)*len, ny=y+Math.sin(rad)*len;
      out.push({x1:x,y1:y,x2:nx,y2:ny,depth:d});
      x=nx;y=ny;drawn++;
    } else if(ch==='+'){ ang+=angInc; }
    else if(ch==='-'){ ang-=angInc; }
    else if(ch==='['){ stack.push({x,y,ang,len,d}); len*=0.74; d++; }
    else if(ch===']'){ const st=stack.pop(); x=st.x;y=st.y;ang=st.ang;len=st.len;d=st.d; }
  }
  return out;
}
build();
function loop(t){
  ctx.fillStyle='#0b1220';
  ctx.fillRect(0,0,cv.width,cv.height);
  if(phase==='grow'){
    drawIdx += Math.max(1,branchCount/240);
    if(drawIdx>=branchCount){drawIdx=branchCount;phase='sway';}
  }
  windT+=0.016;
  const windStrength=phase==='sway'?((Math.sin(windT*0.15)+1)/2*0.35+0.03):0;
  const list=walk(Math.floor(drawIdx),windStrength);
  for(const b of list){
    const t2=b.depth/8;
    ctx.strokeStyle='rgb('+Math.floor(90+t2*60)+','+Math.floor(150+t2*70)+','+Math.floor(60+ (1-t2)*40)+')';
    ctx.lineWidth=Math.max(1,5-b.depth*0.6);
    ctx.beginPath();ctx.moveTo(b.x1,b.y1);ctx.lineTo(b.x2,b.y2);ctx.stroke();
  }
  ctx.fillStyle='#dfd';ctx.font='14px monospace';
  ctx.fillText('generation depth: '+depth,10,20);
  ctx.fillText('branches: '+branchCount,10,38);
  if(phase==='sway' && windT>28+Math.random()*10) build();
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
</script></body></html>
Claude Haiku 4.5frontier referenceOKMINIFIED
Show code
<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{margin:0;background:#000;overflow:hidden}#c{display:block}#i{position:absolute;top:5px;left:5px;color:#0f0;font-family:monospace;font-size:12px}</style></head><body><canvas id="c"></canvas><div id="i"></div><script>const c=document.getElementById('c'),ctx=c.getContext('2d'),i=document.getElementById('i');c.width=800;c.height=600;let ls='F';for(let j=0;j<4;j++){ls=ls.replace(/F/g,'FF[F]-[F]')}let br=0,mx=400,my=550;function dr(){ctx.fillStyle='#000';ctx.fillRect(0,0,800,600);ctx.strokeStyle='#0f0';ctx.lineWidth=1;let st=[],x=mx,y=my,ang=Math.PI/2;let wnd=(Math.sin(Date.now()/1000)*0.3);for(let ch of ls){if(ch==='F'){let nx=x+Math.cos(ang+wnd)*8,ny=y-Math.sin(ang+wnd)*8;ctx.beginPath();ctx.moveTo(x,y);ctx.lineTo(nx,ny);ctx.stroke();x=nx;y=ny;br++}else if(ch==='['){st.push({x,y,a:ang})}else if(ch===']'){let p=st.pop();x=p.x;y=p.y;ang=p.a}else if(ch==='-'){ang-=Math.PI/8}else if(ch==='+'){ang+=Math.PI/8}}i.textContent=`Gen: 4 Branches: ${br}`}setInterval(()=>{br=0;dr()},50);</script></body></html>
Results at a glance— every model in this round with score, response time and status.

Who wrote what

ModelBlind scoreLatencyStatus
deepseek-r1:14b —15.6 sOK
qwen3:14b —35.0 sOK
qwen3-coder:30b —23.7 sOK
qwen3:8b ——harness
llama3.1:8b —96.2 sOK
mistral-small:24b —96.0 sOK
qwen3.5:9b —68.4 sOK
gemma4:26b ——harness
qwq:32b —273.7 sOK
deepseek-r1:32b —134.2 sOK
command-r:35b —299.2 sOK