Models 44

Mistral Small 4

by MistralReasoningClean
Open in new window

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

How it went

Total time
21.0 s
Cost
$0.0027
Output tokens
4,109
Spent thinking
516 tokens
Speed
201.3 tok/s
Console errors
0
First token after
560 ms
First visible text after
4.1 s
Prompt tokens
379
Code size
11.1 KB
Finish reason
stop
Served by
Mistral
Model id
mistralai/mistral-small-2603
Reasoning sent
{"effort":"high"}
Max output
209,715 tokens
Generated
Nov 12, 2026

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 · 472 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hamburger Breakout</title>
<style>
  body {
    margin: 0;
    padding: 0;
    background: #111;
    color: white;
    font-family: Arial, sans-serif;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    user-select: none;
  }
  #gameCanvas {
    background: #000;
    display: block;
  }
  #overlay {
    position: absolute;
    text-align: center;
    pointer-events: none;
  }
  #startMessage {
    font-size: 24px;
    background: rgba(0,0,0,0.7);
    padding: 20px 30px;
    border-radius: 10px;
    display: none;
  }
  #gameOver {
    font-size: 32px;
    background: rgba(100,0,0,0.8);
    padding: 30px 40px;
    border-radius: 15px;
    display: none;
  }
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<div id="overlay">
  <div id="startMessage">Click or press a key to start</div>
  <div id="gameOver">Game Over! Click to restart</div>
</div>

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

// Set canvas size
function resizeCanvas() {
  canvas.width = Math.min(1280, window.innerWidth);
  canvas.height = Math.min(800, window.innerHeight);
  if (canvas.width > canvas.height * 1.6) {
    canvas.width = canvas.height * 1.6;
  }
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);

// Game state
let gameActive = false;
let demoMode = true;
let gameOver = false;
let score = 0;
let lives = 3;

// Ball properties
const ball = {
  x: 0,
  y: 0,
  radius: 8,
  dx: 0,
  dy: 0,
  speed: 6
};

// Paddle (hamburger) properties
const paddle = {
  width: 120,
  height: 20,
  x: 0,
  y: 0,
  speed: 10,
  isMovingLeft: false,
  isMovingRight: false
};

// Bricks
const brickRowCount = 5;
const brickColumnCount = 12;
const brickWidth = 80;
const brickHeight = 30;
const brickPadding = 10;
const brickOffsetTop = 60;
const brickOffsetLeft = 30;

const bricks = [];
for (let c = 0; c < brickColumnCount; c++) {
  bricks[c] = [];
  for (let r = 0; r < brickRowCount; r++) {
    bricks[c][r] = { x: 0, y: 0, status: 1 };
  }
}

// Hearts particles
const particles = [];

// Initialize game
function initGame() {
  // Reset ball
  ball.x = canvas.width / 2;
  ball.y = canvas.height - 50;
  ball.dx = (Math.random() > 0.5 ? 1 : -1) * ball.speed;
  ball.dy = -ball.speed;

  // Reset paddle
  paddle.x = (canvas.width - paddle.width) / 2;
  paddle.y = canvas.height - 30;

  // Reset bricks
  for (let c = 0; c < brickColumnCount; c++) {
    for (let r = 0; r < brickRowCount; r++) {
      bricks[c][r].status = 1;
    }
  }

  // Reset particles
  particles.length = 0;

  // Reset game state
  score = 0;
  lives = 3;
  gameOver = false;
  gameActive = true;
}

// Draw heart particle
function drawHeart(x, y, size) {
  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.bezierCurveTo(x, y - size * 1.5, x - size, y - size * 2, x, y - size * 2.5);
  ctx.bezierCurveTo(x + size, y - size * 2, x, y - size * 1.5, x, y);
  ctx.closePath();
}

// Draw hamburger paddle
function drawPaddle() {
  // Bottom bun
  ctx.fillStyle = '#D2691E';
  ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);

  // Lettuce
  ctx.fillStyle = '#7CFC00';
  ctx.fillRect(paddle.x + 5, paddle.y - 10, paddle.width - 10, 5);

  // Patty
  ctx.fillStyle = '#8B4513';
  ctx.fillRect(paddle.x + 10, paddle.y - 15, paddle.width - 20, 5);

  // Cheese
  ctx.fillStyle = '#FFD700';
  ctx.fillRect(paddle.x + 15, paddle.y - 20, paddle.width - 30, 5);

  // Top bun
  ctx.fillStyle = '#D2691E';
  ctx.fillRect(paddle.x + 20, paddle.y - 25, paddle.width - 40, 5);

  // Sesame seeds
  ctx.fillStyle = '#F5DEB3';
  for (let i = 0; i < 15; i++) {
    const seedX = paddle.x + 10 + Math.random() * (paddle.width - 20);
    const seedY = paddle.y - 5 - Math.random() * 5;
    ctx.beginPath();
    ctx.arc(seedX, seedY, 1.5, 0, Math.PI * 2);
    ctx.fill();
  }
}

// Draw ball
function drawBall() {
  ctx.beginPath();
  ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
  ctx.fillStyle = '#FF6B6B';
  ctx.fill();
  ctx.closePath();
}

// Draw brick
function drawBrick(c, r) {
  const brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;
  const brickY = r * (brickHeight + brickPadding) + brickOffsetTop;

  // Heart shape for brick
  ctx.beginPath();
  ctx.moveTo(brickX + brickWidth / 2, brickY);
  ctx.bezierCurveTo(brickX + brickWidth, brickY, brickX + brickWidth, brickY + brickHeight / 2, brickX + brickWidth / 2, brickY + brickHeight);
  ctx.bezierCurveTo(brickX, brickY + brickHeight / 2, brickX, brickY, brickX + brickWidth / 2, brickY);
  ctx.closePath();

  // Different colors for different rows
  const hue = (r / brickRowCount) * 120;
  ctx.fillStyle = `hsl(${hue}, 80%, 60%)`;
  ctx.fill();
}

// Draw particles
function drawParticles() {
  particles.forEach(particle => {
    ctx.globalAlpha = particle.alpha;
    drawHeart(particle.x, particle.y, particle.size);
    ctx.fillStyle = `hsl(${particle.hue}, 80%, 60%)`;
    ctx.fill();
  });
  ctx.globalAlpha = 1;
}

// Collision detection
function collisionDetection() {
  for (let c = 0; c < brickColumnCount; c++) {
    for (let r = 0; r < brickRowCount; r++) {
      const brick = bricks[c][r];
      if (brick.status === 1) {
        if (
          ball.x > c * (brickWidth + brickPadding) + brickOffsetLeft &&
          ball.x < c * (brickWidth + brickPadding) + brickOffsetLeft + brickWidth &&
          ball.y > r * (brickHeight + brickPadding) + brickOffsetTop &&
          ball.y < r * (brickHeight + brickPadding) + brickOffsetTop + brickHeight
        ) {
          brick.status = 0;
          score++;

          // Create heart explosion
          for (let i = 0; i < 30; i++) {
            particles.push({
              x: c * (brickWidth + brickPadding) + brickOffsetLeft + brickWidth / 2,
              y: r * (brickHeight + brickPadding) + brickOffsetTop + brickHeight / 2,
              dx: (Math.random() - 0.5) * 8,
              dy: (Math.random() - 0.5) * 8,
              size: 3 + Math.random() * 5,
              hue: (r / brickRowCount) * 120,
              alpha: 1,
              life: 100
            });
          }

          // Bounce
          ball.dy = -ball.dy;
        }
      }
    }
  }
}

// Update particles
function updateParticles() {
  for (let i = particles.length - 1; i >= 0; i--) {
    const p = particles[i];
    p.x += p.dx;
    p.y += p.dy;
    p.alpha -= 0.01;
    p.life--;

    if (p.alpha <= 0 || p.life <= 0) {
      particles.splice(i, 1);
    }
  }
}

// Game loop
function draw() {
  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Draw bricks
  for (let c = 0; c < brickColumnCount; c++) {
    for (let r = 0; r < brickRowCount; r++) {
      if (bricks[c][r].status === 1) {
        drawBrick(c, r);
      }
    }
  }

  // Draw particles
  drawParticles();

  // Draw paddle
  drawPaddle();

  // Draw ball
  drawBall();

  // Draw score
  ctx.fillStyle = '#fff';
  ctx.font = '20px Arial';
  ctx.fillText(`Score: ${score}`, 20, 30);

  // Draw lives
  ctx.fillText(`Lives: ${lives}`, canvas.width - 100, 30);

  // Demo mode indicator
  if (demoMode && !gameActive) {
    ctx.fillStyle = 'rgba(255,255,255,0.3)';
    ctx.font = '24px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('Demo Mode', canvas.width / 2, canvas.height / 2);
    ctx.textAlign = 'left';
  }

  // Game over check
  if (gameOver) {
    gameActive = false;
    gameOverMessage.style.display = 'block';
  }

  // Win check
  if (score >= brickRowCount * brickColumnCount) {
    gameOver = true;
    gameOverMessage.textContent = 'You Win! Click to restart';
    gameOverMessage.style.background = 'rgba(0,100,0,0.8)';
    gameOverMessage.style.display = 'block';
  }

  // Move ball
  if (gameActive) {
    ball.x += ball.dx;
    ball.y += ball.dy;

    // Wall collision (left/right)
    if (ball.x + ball.radius > canvas.width || ball.x - ball.radius < 0) {
      ball.dx = -ball.dx;
    }

    // Wall collision (top)
    if (ball.y - ball.radius < 0) {
      ball.dy = -ball.dy;
    }

    // Paddle collision
    if (
      ball.y + ball.radius > paddle.y &&
      ball.y - ball.radius < paddle.y + paddle.height &&
      ball.x > paddle.x &&
      ball.x < paddle.x + paddle.width
    ) {
      // Add some angle based on where ball hits paddle
      const hitPosition = (ball.x - (paddle.x + paddle.width / 2)) / (paddle.width / 2);
      ball.dx = hitPosition * ball.speed;
      ball.dy = -Math.abs(ball.dy);
      ball.dy = -Math.sqrt(ball.speed * ball.speed - ball.dx * ball.dx);
    }

    // Bottom wall (lose life)
    if (ball.y + ball.radius > canvas.height) {
      lives--;
      if (lives <= 0) {
        gameOver = true;
      } else {
        // Reset ball
        ball.x = canvas.width / 2;
        ball.y = canvas.height - 50;
        ball.dx = (Math.random() > 0.5 ? 1 : -1) * ball.speed;
        ball.dy = -ball.speed;
      }
    }

    collisionDetection();
    updateParticles();
  }

  requestAnimationFrame(draw);
}

// Demo AI for paddle
function demoAIMove() {
  if (!demoMode || gameActive) return;

  // Simple AI: follow the ball
  const targetX = ball.x;
  if (targetX < paddle.x + paddle.width / 2 - 20) {
    paddle.isMovingLeft = true;
    paddle.isMovingRight = false;
  } else if (targetX > paddle.x + paddle.width / 2 + 20) {
    paddle.isMovingRight = true;
    paddle.isMovingLeft = false;
  } else {
    paddle.isMovingLeft = false;
    paddle.isMovingRight = false;
  }
}

// Keyboard controls
document.addEventListener('keydown', (e) => {
  if (!gameActive && !gameOver) {
    initGame();
    gameActive = true;
    demoMode = false;
    startMessage.style.display = 'none';
    gameOverMessage.style.display = 'none';
    gameOverMessage.style.background = 'rgba(100,0,0,0.8)';
  }

  if (gameOver) {
    initGame();
    gameOverMessage.style.display = 'none';
    return;
  }

  if (e.key === 'ArrowLeft') {
    paddle.isMovingLeft = true;
    paddle.isMovingRight = false;
  } else if (e.key === 'ArrowRight') {
    paddle.isMovingRight = true;
    paddle.isMovingLeft = false;
  }
});

document.addEventListener('keyup', (e) => {
  if (e.key === 'ArrowLeft') {
    paddle.isMovingLeft = false;
  } else if (e.key === 'ArrowRight') {
    paddle.isMovingRight = false;
  }
});

// Mouse/touch controls
canvas.addEventListener('mousemove', (e) => {
  if (!gameActive && !gameOver) return;

  const rect = canvas.getBoundingClientRect();
  const mouseX = e.clientX - rect.left;
  paddle.x = mouseX - paddle.width / 2;

  // Keep paddle in bounds
  if (paddle.x < 0) paddle.x = 0;
  if (paddle.x + paddle.width > canvas.width) {
    paddle.x = canvas.width - paddle.width;
  }
});

canvas.addEventListener('click', () => {
  if (!gameActive && !gameOver) {
    initGame();
    gameActive = true;
    demoMode = false;
    startMessage.style.display = 'none';
    gameOverMessage.style.display = 'none';
    gameOverMessage.style.background = 'rgba(100,0,0,0.8)';
  } else if (gameOver) {
    initGame();
    gameOverMessage.style.display = 'none';
  }
});

// Start demo mode
ball.x = canvas.width / 2;
ball.y = canvas.height / 2;
ball.dx = 3;
ball.dy = -3;

draw();
</script>
</body>
</html>
Reasoning trace (516 tokens)
The user wants a Breakout-style game with specific features:
1. Paddle should be a hamburger
2. Bricks should explode into hearts when broken
3. It should be a self-contained web demo with inline CSS and JavaScript
4. Must work in a 1280×800 viewport and adapt to 375px
5. Should start in demo mode with a "Click or press a key to start" message
6. No external resources except CDN URLs explicitly allowed (none needed here)
7. Must be playable in the sandboxed iframe

Let me break this down:
- Game mechanics: Classic Breakout with paddle, ball, bricks
- Visual theme: Hamburger paddle, hearts for bricks
- Features: Bricks explode into hearts when hit, game starts automatically in demo mode
- UI: Clear start message, game over message
- Responsive design: Should work on mobile and desktop

I'll need to:
1. Create a canvas-based game
2. Draw a hamburger as the paddle (can be a simple SVG or drawn with canvas)
3. Draw bricks that look like hearts (or break into hearts)
4. When a brick is hit, make it disappear and spawn heart particles
5. Game loop with physics
6. Start with a demo mode that shows the game playing itself
7. Show "Click or press a key to start" initially
8. Handle clicks/keypresses to start the game
9. Game over detection

For the hamburger paddle, I can draw it with canvas shapes or use a simple representation. Hearts can be drawn as simple shapes too.

Let me structure the code:
- HTML structure with canvas and overlay messages
- CSS for styling and positioning the overlay
- JavaScript for game logic:
  - Game state (demo mode, playing, game over)
  - Ball physics
  - Paddle (hamburger) movement
  - Brick grid with heart sprites
  - Collision detection
  - Particle system for heart explosions
  - Game loop

The hamburger can be represented as:
- Bottom bun: brown rectangle
- Lettuce: green rectangle
- Patty: red rectangle
- Cheese: yellow rectangle
- Top bun: brown rectangle

Hearts can be drawn as simple heart shapes using canvas paths.

For the explosion effect, when a brick is hit, I'll spawn multiple heart particles that fly out in random directions.

Let me write the complete code.