Models 44

Claude Haiku 5.5

by AnthropicReasoning1 console error
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
22.7 s
Cost
$0.0034
Output tokens
6,642
Spent thinking
0 tokens
Speed
305.9 tok/s
Console errors
1
First token after
1.0 s
First visible text after
1.0 s
Prompt tokens
541
Code size
13.2 KB
Finish reason
stop
Served by
Claude Platform on AWS
Model id
anthropic/claude-haiku-5.5
Reasoning sent
{"effort":"none"}
Max output
32,000 tokens
Generated
Nov 10, 2026

Console errors

Caught in the first 3 seconds after load, in a sandboxed iframe like the one above.

Failed to load resource: the server responded with a status of 404 (Not Found)

What it was asked

The prompt
“i want a breakout game where the paddle is a hamburger and every brick you break explodes into tons of little hearts”
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task.

Output rules:
- Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block.
- Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task.
- Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw.
- The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar.
- Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction.
- Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session.
- Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing.
- The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message.
- The code must run with zero errors in the console of the latest Chrome.

Code run-1.html · 449 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hamburger Breakout</title>
<style>
  * { box-sizing: border-box; margin: 0; padding: 0; }
  html, body {
    width: 100%; height: 100%;
    background: radial-gradient(circle at 50% 30%, #2a1040 0%, #0d0716 70%);
    overflow: hidden;
    font-family: "Trebuchet MS", "Segoe UI", Arial, sans-serif;
    color: #fff;
  }
  #wrap {
    position: relative;
    width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
  }
  #game {
    position: relative;
    width: min(96vw, 1000px);
    height: min(calc(100vh - 20px), 700px);
    max-width: 100%;
    border: 3px solid #ff5fa2;
    border-radius: 14px;
    background: linear-gradient(#150a24, #0b0614);
    box-shadow: 0 0 30px rgba(255, 95, 162, 0.35), inset 0 0 40px rgba(255, 95, 162, 0.08);
    overflow: hidden;
  }
  canvas { width: 100%; height: 100%; display: block; }
  #hud {
    position: absolute; top: 10px; left: 0; right: 0;
    display: flex; justify-content: space-between; padding: 0 18px;
    font-weight: bold; font-size: clamp(14px, 2.2vw, 20px);
    pointer-events: none; text-shadow: 0 0 6px #000;
  }
  #hud .score { color: #ffd1e6; }
  #hud .lives { color: #ff5fa2; }
  #overlay {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    background: rgba(10, 4, 18, 0.55);
    text-align: center; padding: 20px;
    cursor: pointer;
    transition: opacity .3s;
  }
  #overlay.hidden { opacity: 0; pointer-events: none; }
  #overlay h1 {
    font-size: clamp(28px, 6vw, 56px);
    color: #ff8fc1;
    text-shadow: 0 0 14px #ff3d8b;
    margin-bottom: 14px;
  }
  #overlay p {
    font-size: clamp(14px, 2.5vw, 20px);
    color: #ffe6f2;
    animation: pulse 1.4s ease-in-out infinite;
  }
  @keyframes pulse { 50% { opacity: .45; } }
  @media (max-width: 480px) {
    #game { border-width: 2px; border-radius: 8px; }
  }
</style>
</head>
<body>
<div id="wrap">
  <div id="game">
    <canvas id="c"></canvas>
    <div id="hud"><span class="score">Score: 0</span><span class="lives">Lives: 3</span></div>
    <div id="overlay">
      <h1>Hamburger Breakout</h1>
      <p>Click or press a key to start</p>
    </div>
  </div>
</div>

<script>
(function () {
  const canvas = document.getElementById('c');
  const ctx = canvas.getContext('2d');
  const overlay = document.getElementById('overlay');
  const scoreEl = document.querySelector('#hud .score');
  const livesEl = document.querySelector('#hud .lives');

  let W = 800, H = 600, dpr = 1;
  let state = 'demo'; // demo | playing | over
  let started = false;
  let score = 0, lives = 3;
  let mouseX = null;

  const brickColors = ['#ff6b9d', '#ff9f43', '#feca57', '#55efc4', '#74b9ff', '#a29bfe'];
  let paddle, ball, bricks, particles, hearts, flash;

  function resize() {
    const r = canvas.getBoundingClientRect();
    dpr = window.devicePixelRatio || 1;
    canvas.width = Math.max(1, Math.floor(r.width * dpr));
    canvas.height = Math.max(1, Math.floor(r.height * dpr));
    W = r.width; H = r.height;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    if (paddle) {
      paddle.w = Math.max(90, W * 0.16);
      paddle.y = H - 40;
    }
    if (bricks) layoutBricks();
  }

  function layoutBricks() {
    bricks = [];
    const cols = Math.max(5, Math.min(10, Math.floor(W / 80)));
    const rows = 5;
    const gap = 6;
    const bw = (W - 40 - gap * (cols - 1)) / cols;
    const bh = Math.max(16, Math.min(28, H * 0.045));
    const top = 70;
    for (let r = 0; r < rows; r++) {
      for (let c = 0; c < cols; c++) {
        bricks.push({
          x: 20 + c * (bw + gap),
          y: top + r * (bh + gap),
          w: bw, h: bh,
          color: brickColors[r % brickColors.length],
          alive: true
        });
      }
    }
  }

  function resetBall(serveUp) {
    ball = {
      x: paddle.x + paddle.w / 2,
      y: paddle.y - 14,
      r: 9,
      vx: (Math.random() < 0.5 ? -1 : 1) * 260,
      vy: -340,
      stuck: !serveUp
    };
  }

  function init() {
    paddle = { x: 0, w: 120, h: 26, y: 0 };
    paddle.x = W / 2 - paddle.w / 2;
    paddle.y = H - 40;
    score = 0; lives = 3;
    particles = []; hearts = []; flash = 0;
    layoutBricks();
    resetBall(false);
    updateHud();
  }

  function updateHud() {
    scoreEl.textContent = 'Score: ' + score;
    livesEl.textContent = 'Lives: ' + lives;
  }

  // ---------- Hamburger paddle ----------
  function drawHamburger(x, y, w, h) {
    const cx = x + w / 2;
    // bun top
    ctx.fillStyle = '#e8a04a';
    roundRect(x + 4, y - 4, w - 8, h * 0.62, 12, true);
    // sesame seeds
    ctx.fillStyle = '#fff3d6';
    for (let i = 0; i < 6; i++) {
      const sx = x + 14 + i * ((w - 28) / 5);
      ctx.beginPath();
      ctx.ellipse(sx, y + 2 + (i % 2) * 3, 2.2, 1.3, 0.4, 0, Math.PI * 2);
      ctx.fill();
    }
    // lettuce
    ctx.fillStyle = '#5cd65c';
    roundRect(x, y + h * 0.5, w, h * 0.22, 5, true);
    // patty
    ctx.fillStyle = '#6b3a1e';
    roundRect(x + 2, y + h * 0.66, w - 4, h * 0.26, 5, true);
    // cheese
    ctx.fillStyle = '#ffd23f';
    roundRect(x, y + h * 0.9, w, h * 0.14, 3, true);
    // bottom bun
    ctx.fillStyle = '#d98b36';
    roundRect(x + 4, y + h * 1.02, w - 8, h * 0.42, 8, true);
  }

  function roundRect(x, y, w, h, r, fill) {
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.arcTo(x + w, y, x + w, y + h, r);
    ctx.arcTo(x + w, y + h, x, y + h, r);
    ctx.arcTo(x, y + h, x, y, r);
    ctx.arcTo(x, y, x + w, y, r);
    ctx.closePath();
    if (fill) ctx.fill();
  }

  // ---------- Hearts ----------
  function drawHeart(x, y, s, color, alpha) {
    ctx.save();
    ctx.globalAlpha = alpha;
    ctx.fillStyle = color;
    ctx.beginPath();
    ctx.moveTo(x, y + s * 0.3);
    ctx.bezierCurveTo(x, y, x - s * 0.5, y - s * 0.1, x - s * 0.5, y + s * 0.2);
    ctx.bezierCurveTo(x - s * 0.5, y + s * 0.5, x, y + s * 0.7, x, y + s);
    ctx.bezierCurveTo(x, y + s * 0.7, x + s * 0.5, y + s * 0.5, x + s * 0.5, y + s * 0.2);
    ctx.bezierCurveTo(x + s * 0.5, y - s * 0.1, x, y, x, y + s * 0.3);
    ctx.fill();
    ctx.restore();
  }

  function burstBrick(b) {
    const cx = b.x + b.w / 2, cy = b.y + b.h / 2;
    const count = 28 + Math.floor(Math.random() * 12);
    for (let i = 0; i < count; i++) {
      const a = Math.random() * Math.PI * 2;
      const sp = 60 + Math.random() * 260;
      hearts.push({
        x: cx + (Math.random() - 0.5) * b.w * 0.8,
        y: cy + (Math.random() - 0.5) * b.h,
        vx: Math.cos(a) * sp,
        vy: Math.sin(a) * sp - 120,
        s: 5 + Math.random() * 9,
        rot: Math.random() * 0.6 - 0.3,
        life: 1,
        color: Math.random() < 0.5 ? b.color : (Math.random() < 0.5 ? '#ff4d8d' : '#ffb3d1')
      });
    }
    for (let i = 0; i < 10; i++) {
      particles.push({
        x: cx, y: cy,
        vx: (Math.random() - 0.5) * 300,
        vy: (Math.random() - 0.5) * 300,
        life: 1, color: '#fff'
      });
    }
    flash = 0.15;
  }

  // ---------- Update ----------
  let lastT = performance.now();
  function step(dt) {
    // paddle control
    if (state === 'demo') {
      // AI follows ball
      const target = ball.x - paddle.w / 2 + (Math.sin(performance.now() / 400) * 10);
      paddle.x += (target - paddle.x) * Math.min(1, dt * 6);
    } else if (mouseX !== null) {
      paddle.x += (mouseX - paddle.w / 2 - paddle.x) * Math.min(1, dt * 18);
    }
    paddle.x = Math.max(0, Math.min(W - paddle.w, paddle.x));

    if (ball.stuck) {
      ball.x = paddle.x + paddle.w / 2;
      ball.y = paddle.y - 14;
      if (state === 'demo' && Math.random() < dt * 1.5) ball.stuck = false;
    } else {
      ball.x += ball.vx * dt;
      ball.y += ball.vy * dt;

      if (ball.x < ball.r) { ball.x = ball.r; ball.vx = Math.abs(ball.vx); }
      if (ball.x > W - ball.r) { ball.x = W - ball.r; ball.vx = -Math.abs(ball.vx); }
      if (ball.y < ball.r) { ball.y = ball.r; ball.vy = Math.abs(ball.vy); }

      // paddle collision
      if (ball.vy > 0 &&
          ball.y + ball.r >= paddle.y && ball.y + ball.r <= paddle.y + paddle.h + 8 &&
          ball.x >= paddle.x - ball.r && ball.x <= paddle.x + paddle.w + ball.r) {
        const rel = (ball.x - (paddle.x + paddle.w / 2)) / (paddle.w / 2);
        const speed = Math.hypot(ball.vx, ball.vy) * 1.02;
        const ang = rel * 1.0;
        ball.vx = Math.sin(ang) * speed;
        ball.vy = -Math.cos(ang) * speed;
        ball.y = paddle.y - ball.r;
      }

      // brick collision
      for (const b of bricks) {
        if (!b.alive) continue;
        if (ball.x + ball.r > b.x && ball.x - ball.r < b.x + b.w &&
            ball.y + ball.r > b.y && ball.y - ball.r < b.y + b.h) {
          b.alive = false;
          burstBrick(b);
          score += 10;
          const overlapX = Math.min(ball.x + ball.r - b.x, b.x + b.w - (ball.x - ball.r));
          const overlapY = Math.min(ball.y + ball.r - b.y, b.y + b.h - (ball.y - ball.r));
          if (overlapX < overlapY) ball.vx = -ball.vx; else ball.vy = -ball.vy;
          break;
        }
      }

      // lost ball
      if (ball.y > H + 20) {
        if (state === 'demo') {
          resetBall(false);
        } else {
          lives--;
          updateHud();
          if (lives <= 0) {
            gameOver();
          } else {
            resetBall(false);
          }
        }
      }
    }

    // particles and hearts
    for (const p of particles) {
      p.x += p.vx * dt; p.y += p.vy * dt;
      p.life -= dt * 2.5;
    }
    particles = particles.filter(p => p.life > 0);

    for (const h of hearts) {
      h.vy += 420 * dt;
      h.vx *= 0.99;
      h.x += h.vx * dt;
      h.y += h.vy * dt;
      h.life -= dt * 0.35;
      if (h.y > H + 20) h.life = 0;
    }
    hearts = hearts.filter(h => h.life > 0);
    if (flash > 0) flash -= dt;

    // level cleared -> rebuild
    if (bricks.every(b => !b.alive)) {
      layoutBricks();
      resetBall(state === 'demo');
      if (state === 'playing') score += 100;
      updateHud();
    }
    if (state === 'playing') updateHud();
  }

  function gameOver() {
    state = 'over';
    overlay.querySelector('h1').textContent = 'Out of Buns!';
    overlay.querySelector('p').textContent = 'Click or press a key to play again';
    overlay.classList.remove('hidden');
    setTimeout(() => {
      if (state === 'over') {
        state = 'demo';
        init();
        overlay.querySelector('h1').textContent = 'Hamburger Breakout';
        overlay.querySelector('p').textContent = 'Click or press a key to start';
        overlay.classList.remove('hidden');
      }
    }, 2500);
  }

  function startGame() {
    if (state === 'playing') return;
    state = 'playing';
    init();
    resetBall(true);
    overlay.classList.add('hidden');
  }

  // ---------- Draw ----------
  function draw() {
    ctx.clearRect(0, 0, W, H);

    if (flash > 0) {
      ctx.fillStyle = 'rgba(255, 110, 170, ' + (flash * 0.5) + ')';
      ctx.fillRect(0, 0, W, H);
    }

    // bricks
    for (const b of bricks) {
      if (!b.alive) continue;
      ctx.fillStyle = b.color;
      roundRect(b.x, b.y, b.w, b.h, 6, true);
      ctx.fillStyle = 'rgba(255,255,255,0.35)';
      roundRect(b.x + 3, b.y + 3, b.w - 6, b.h * 0.3, 4, true);
    }

    // hearts
    for (const h of hearts) {
      ctx.save();
      ctx.translate(h.x, h.y);
      ctx.rotate(h.rot + h.life);
      drawHeart(0, 0, h.s, h.color, Math.min(1, h.life * 1.6));
      ctx.restore();
    }

    // sparkles
    ctx.fillStyle = '#fff';
    for (const p of particles) {
      ctx.globalAlpha = p.life;
      ctx.beginPath();
      ctx.arc(p.x, p.y, 2, 0, Math.PI * 2);
      ctx.fill();
    }
    ctx.globalAlpha = 1;

    // ball (a small pickle-colored orb)
    const grd = ctx.createRadialGradient(ball.x - 3, ball.y - 3, 1, ball.x, ball.y, ball.r);
    grd.addColorStop(0, '#fff');
    grd.addColorStop(1, '#ff4d8d');
    ctx.fillStyle = grd;
    ctx.beginPath();
    ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2);
    ctx.fill();

    drawHamburger(paddle.x, paddle.y, paddle.w, paddle.h);
  }

  // ---------- Input ----------
  function pointerMove(clientX) {
    const r = canvas.getBoundingClientRect();
    mouseX = clientX - r.left;
  }
  canvas.addEventListener('mousemove', e => pointerMove(e.clientX));
  canvas.addEventListener('touchmove', e => {
    e.preventDefault();
    pointerMove(e.touches[0].clientX);
  }, { passive: false });
  canvas.addEventListener('mouseleave', () => { mouseX = null; });

  overlay.addEventListener('click', startGame);
  document.addEventListener('keydown', e => {
    if (state !== 'playing') { startGame(); return; }
    if (e.key === 'ArrowLeft') mouseX = Math.max(0, paddle.x + paddle.w / 2 - 40);
    if (e.key === 'ArrowRight') mouseX = Math.min(W, paddle.x + paddle.w / 2 + 40);
    if (e.key === ' ' && ball.stuck) ball.stuck = false;
  });
  canvas.addEventListener('click', () => {
    if (state === 'playing' && ball.stuck) ball.stuck = false;
  });

  window.addEventListener('resize', resize);

  // ---------- Loop ----------
  function loop(now) {
    const dt = Math.min(0.033, (now - lastT) / 1000);
    lastT = now;
    step(dt);
    draw();
    requestAnimationFrame(loop);
  }

  resize();
  init();
  requestAnimationFrame(loop);
})();
</script>
</body>
</html>