Hamburger breakoutOne-line
Ministral 3 14B 2512
by Mistralreasoning default1 console error
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 42.7 s
- Cost
- $0.0012
- Output tokens
- 5,295
- Spent thinking
- 0 tokens
- Speed
- 124.7 tok/s
- Console errors
- 1
- First token after
- 272 ms
- First visible text after
- 272 ms
- Prompt tokens
- 367
- Code size
- 23.8 KB
- Finish reason
- stop
- Served by
- Mistral
- Model id
mistralai/ministral-14b-2512- Reasoning sent
model default- Max output
- 209,715 tokens
- Generated
- Nov 13, 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 · 710 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Breakout: Hamburger Smash</title>
<style>
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #222;
font-family: 'Arial', sans-serif;
overflow: hidden;
user-select: none;
}
#game-container {
position: relative;
width: 100%;
max-width: 800px;
height: 600px;
background-color: #111;
overflow: hidden;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
}
#game-canvas {
display: block;
background-color: #000;
}
#start-message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
text-align: center;
font-size: 24px;
z-index: 10;
pointer-events: none;
background-color: rgba(0, 0, 0, 0.7);
padding: 20px 30px;
border-radius: 10px;
display: none;
}
#score-display {
position: absolute;
top: 10px;
left: 10px;
color: white;
font-size: 20px;
z-index: 10;
text-shadow: 1px 1px 2px black;
}
#lives-display {
position: absolute;
top: 10px;
right: 10px;
color: white;
font-size: 20px;
z-index: 10;
text-shadow: 1px 1px 2px black;
}
.heart {
position: absolute;
width: 12px;
height: 12px;
background-color: #ff4d4d;
border-radius: 50%;
pointer-events: none;
transform: rotate(0deg);
animation: float 3s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0) rotate(0deg); }
50% { transform: translateY(-20px) rotate(180deg); }
}
.paddle {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
width: 80px;
height: 15px;
background-color: #ff6b35;
border-radius: 5px;
}
.paddle-top {
position: absolute;
bottom: 18px;
left: 50%;
transform: translateX(-50%);
width: 60px;
height: 10px;
background-color: #ffd700;
border-radius: 5px;
}
.paddle-bottom {
position: absolute;
bottom: 18px;
left: 50%;
transform: translateX(-50%);
width: 60px;
height: 10px;
background-color: #ffd700;
border-radius: 5px;
}
.paddle-meat {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
width: 40px;
height: 20px;
background-color: #ff6b35;
border-radius: 5px;
}
.brick {
position: absolute;
width: 60px;
height: 20px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
color: white;
border-radius: 5px;
pointer-events: none;
}
.brick-red { background-color: #ff4d4d; }
.brick-orange { background-color: #ff9500; }
.brick-yellow { background-color: #ffd700; }
.brick-green { background-color: #00ff00; }
.brick-blue { background-color: #0066ff; }
.brick-purple { background-color: #9900ff; }
.ball {
position: absolute;
width: 12px;
height: 12px;
background-color: #ffffff;
border-radius: 50%;
pointer-events: none;
}
.explosion {
position: absolute;
width: 40px;
height: 40px;
border-radius: 50%;
pointer-events: none;
display: none;
}
.explosion-circle {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: rgba(255, 77, 77, 0.7);
animation: explode 0.5s ease-out forwards;
}
@keyframes explode {
0% { transform: scale(0); opacity: 1; }
100% { transform: scale(1.5); opacity: 0; }
}
@media (max-width: 400px) {
#game-container {
width: 95%;
height: 500px;
}
.brick {
width: 50px;
height: 18px;
font-size: 10px;
}
.paddle {
width: 60px;
height: 12px;
}
.paddle-top, .paddle-bottom {
width: 40px;
height: 8px;
}
.paddle-meat {
width: 30px;
height: 16px;
}
}
</style>
</head>
<body>
<div id="game-container">
<div id="score-display">Score: 0</div>
<div id="lives-display">Lives: 3</div>
<div id="start-message">Click or press a key to start</div>
<div class="paddle">
<div class="paddle-top"></div>
<div class="paddle-bottom"></div>
<div class="paddle-meat"></div>
</div>
<canvas id="game-canvas"></canvas>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('game-canvas');
const ctx = canvas.getContext('2d');
const startMessage = document.getElementById('start-message');
const scoreDisplay = document.getElementById('score-display');
const livesDisplay = document.getElementById('lives-display');
const gameContainer = document.getElementById('game-container');
// Set canvas size
function resizeCanvas() {
const rect = gameContainer.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// Game state
let gameRunning = false;
let score = 0;
let lives = 3;
let bricks = [];
let balls = [];
let hearts = [];
let explosions = [];
let lastTime = 0;
let animationId = null;
let keys = {};
// Game objects
const paddle = {
x: canvas.width / 2 - 40,
y: canvas.height - 30,
width: 80,
height: 15,
speed: 8,
moveLeft: false,
moveRight: false
};
// Initialize bricks
function initBricks() {
bricks = [];
const brickWidth = 60;
const brickHeight = 20;
const offsetX = 30;
const offsetY = 60;
const rows = 5;
const cols = canvas.width > 600 ? 10 : (canvas.width > 400 ? 7 : 5);
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
const brick = {
x: c * (brickWidth + 10) + offsetX,
y: r * (brickHeight + 10) + offsetY,
width: brickWidth,
height: brickHeight,
color: getBrickColor(r),
visible: true
};
bricks.push(brick);
}
}
}
function getBrickColor(row) {
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
return colors[row % colors.length];
}
// Initialize balls
function initBalls() {
balls = [];
const ballCount = Math.min(3, lives);
for (let i = 0; i < ballCount; i++) {
balls.push({
x: canvas.width / 2 - 6,
y: canvas.height - 50,
radius: 6,
speed: 3 + i * 0.5,
dx: (Math.random() - 0.5) * 3,
dy: -3 - i,
active: false
});
}
}
// Start game
function startGame() {
if (gameRunning) return;
gameRunning = true;
startMessage.style.display = 'none';
score = 0;
lives = 3;
scoreDisplay.textContent = `Score: ${score}`;
livesDisplay.textContent = `Lives: ${lives}`;
initBricks();
initBalls();
hearts = [];
explosions = [];
// Start with all balls active
balls.forEach(ball => {
ball.active = true;
ball.dx = (Math.random() - 0.5) * 3;
ball.dy = -3;
});
lastTime = performance.now();
animationId = requestAnimationFrame(gameLoop);
}
// Game loop
function gameLoop(timestamp) {
if (!gameRunning) return;
const deltaTime = timestamp - lastTime;
lastTime = timestamp;
update(deltaTime);
render();
animationId = requestAnimationFrame(gameLoop);
}
// Update game state
function update(deltaTime) {
// Move paddle
if (paddle.moveLeft && paddle.x > 0) {
paddle.x -= paddle.speed * (deltaTime / 16);
}
if (paddle.moveRight && paddle.x < canvas.width - paddle.width) {
paddle.x += paddle.speed * (deltaTime / 16);
}
// Update balls
for (let i = balls.length - 1; i >= 0; i--) {
const ball = balls[i];
if (!ball.active) continue;
// Move ball
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 + ball.radius > paddle.x &&
ball.x - ball.radius < paddle.x + paddle.width
) {
// Calculate angle based on where ball hits paddle
const relativeIntersectX = (paddle.x + paddle.width / 2) - ball.x;
const normalizedRelativeIntersectionX = relativeIntersectX / (paddle.width / 2);
const bounceAngle = normalizedRelativeIntersectionX * Math.PI / 4;
ball.dx = Math.sin(bounceAngle) * ball.speed;
ball.dy = -Math.abs(Math.cos(bounceAngle)) * ball.speed;
}
// Brick collision
for (let j = bricks.length - 1; j >= 0; j--) {
const brick = bricks[j];
if (!brick.visible) continue;
if (
ball.x + ball.radius > brick.x &&
ball.x - ball.radius < brick.x + brick.width &&
ball.y + ball.radius > brick.y &&
ball.y - ball.radius < brick.y + brick.height
) {
// Determine which side was hit
const topHit = ball.y - ball.radius < brick.y;
const bottomHit = ball.y + ball.radius > brick.y + brick.height;
const leftHit = ball.x - ball.radius < brick.x;
const rightHit = ball.x + ball.radius > brick.x + brick.width;
if (topHit || bottomHit) {
ball.dy = -ball.dy;
} else {
ball.dx = -ball.dx;
}
// Remove brick and create explosion
brick.visible = false;
createExplosion(brick.x + brick.width / 2, brick.y + brick.height / 2);
createHearts(brick.x + brick.width / 2, brick.y + brick.height / 2);
// Add score based on brick color
const colorIndex = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'].indexOf(brick.color);
score += 10 * (colorIndex + 1);
scoreDisplay.textContent = `Score: ${score}`;
// Check if all bricks are gone
if (bricks.every(b => !b.visible)) {
setTimeout(() => {
if (confirm('You Win! Play again?')) {
startGame();
} else {
gameRunning = false;
}
}, 500);
}
bricks.splice(j, 1);
break;
}
}
// Bottom collision (lose life)
if (ball.y + ball.radius > canvas.height) {
ball.active = false;
lives--;
livesDisplay.textContent = `Lives: ${lives}`;
if (lives <= 0) {
gameOver();
}
}
}
// Create new balls when all are inactive and we have lives left
if (balls.every(b => !b.active) && lives > 0) {
setTimeout(() => {
balls.forEach(ball => {
ball.active = true;
ball.x = canvas.width / 2 - 6;
ball.y = canvas.height - 50;
ball.dx = (Math.random() - 0.5) * 3;
ball.dy = -3;
});
}, 1000);
}
// Update hearts (gravity and rotation)
for (let i = hearts.length - 1; i >= 0; i--) {
const heart = hearts[i];
heart.y += 0.5;
heart.rotation += 0.1;
heart.opacity -= 0.01;
if (heart.opacity <= 0) {
hearts.splice(i, 1);
}
}
// Update explosions
for (let i = explosions.length - 1; i >= 0; i--) {
const explosion = explosions[i];
explosion.elapsed += deltaTime / 1000;
if (explosion.elapsed > explosion.duration) {
explosions.splice(i, 1);
}
}
}
// Render game
function render() {
// Clear canvas
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw bricks
bricks.forEach(brick => {
if (brick.visible) {
ctx.fillStyle = getBrickColorFromName(brick.color);
ctx.fillRect(brick.x, brick.y, brick.width, brick.height);
// Add some texture to bricks
ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
for (let i = 0; i < brick.width; i += 10) {
for (let j = 0; j < brick.height; j += 10) {
ctx.fillRect(brick.x + i, brick.y + j, 5, 5);
}
}
}
});
// Draw balls
balls.forEach(ball => {
if (ball.active) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.fillStyle = '#fff';
ctx.fill();
ctx.closePath();
// Add some glow
const gradient = ctx.createRadialGradient(
ball.x, ball.y, ball.radius * 0.5,
ball.x, ball.y, ball.radius
);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.8)');
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
ctx.fill();
}
});
// Draw hearts
hearts.forEach(heart => {
ctx.save();
ctx.translate(heart.x, heart.y);
ctx.rotate(heart.rotation);
ctx.fillStyle = `rgba(255, 77, 77, ${heart.opacity})`;
ctx.beginPath();
ctx.moveTo(0, -6);
ctx.bezierCurveTo(6, -6, 6, 6, 0, 6);
ctx.bezierCurveTo(-6, 6, -6, -6, 0, -6);
ctx.fill();
ctx.restore();
});
// Draw explosions
explosions.forEach(explosion => {
const progress = Math.min(explosion.elapsed / explosion.duration, 1);
const size = explosion.maxSize * progress;
const alpha = (1 - progress) * 0.7;
ctx.fillStyle = `rgba(255, 77, 77, ${alpha})`;
ctx.beginPath();
ctx.arc(explosion.x, explosion.y, size, 0, Math.PI * 2);
ctx.fill();
});
// Draw paddle (as a hamburger)
// Top bun
ctx.fillStyle = '#ffd700';
ctx.fillRect(paddle.x, paddle.y - 5, paddle.width, 5);
// Patty
ctx.fillStyle = '#ff6b35';
ctx.fillRect(paddle.x + 10, paddle.y, paddle.width - 20, 15);
// Bottom bun
ctx.fillStyle = '#ffd700';
ctx.fillRect(paddle.x, paddle.y + 15, paddle.width, 5);
// Sesame seeds
ctx.fillStyle = '#333';
for (let i = 0; i < paddle.width; i += 10) {
ctx.beginPath();
ctx.arc(paddle.x + i + 5, paddle.y - 2, 1, 0, Math.PI * 2);
ctx.fill();
}
for (let i = 0; i < paddle.width; i += 10) {
ctx.beginPath();
ctx.arc(paddle.x + i + 5, paddle.y + 20, 1, 0, Math.PI * 2);
ctx.fill();
}
}
function getBrickColorFromName(name) {
const colors = {
'red': '#ff4d4d',
'orange': '#ff9500',
'yellow': '#ffd700',
'green': '#00ff00',
'blue': '#0066ff',
'purple': '#9900ff'
};
return colors[name] || '#ff4d4d';
}
// Create explosion effect
function createExplosion(x, y) {
explosions.push({
x: x,
y: y,
maxSize: 30,
duration: 0.8,
elapsed: 0
});
}
// Create heart particles
function createHearts(x, y) {
const count = 15 + Math.floor(Math.random() * 10);
for (let i = 0; i < count; i++) {
hearts.push({
x: x,
y: y,
rotation: Math.random() * Math.PI * 2,
opacity: 0.8 + Math.random() * 0.2
});
}
}
// Game over
function gameOver() {
gameRunning = false;
cancelAnimationFrame(animationId);
setTimeout(() => {
if (confirm(`Game Over! Score: ${score}\nPlay again?`)) {
startGame();
}
}, 500);
}
// Event listeners
document.addEventListener('click', startGame);
document.addEventListener('keydown', (e) => {
if (!gameRunning) {
startGame();
return;
}
if (e.key === 'ArrowLeft') {
paddle.moveLeft = true;
} else if (e.key === 'ArrowRight') {
paddle.moveRight = true;
}
});
document.addEventListener('keyup', (e) => {
if (e.key === 'ArrowLeft') {
paddle.moveLeft = false;
} else if (e.key === 'ArrowRight') {
paddle.moveRight = false;
}
});
// Touch controls for mobile
let touchStartX = 0;
gameContainer.addEventListener('touchstart', (e) => {
if (!gameRunning) {
startGame();
return;
}
touchStartX = e.touches[0].clientX;
});
gameContainer.addEventListener('touchmove', (e) => {
if (!gameRunning) return;
const touchX = e.touches[0].clientX;
const rect = gameContainer.getBoundingClientRect();
const containerWidth = rect.width;
// Calculate how much the paddle should move
const touchDelta = (touchX - touchStartX) / containerWidth * 2;
touchStartX = touchX;
// Apply movement (simplified for touch)
if (Math.abs(touchDelta) > 0.1) {
const direction = touchDelta > 0 ? 1 : -1;
paddle.x += direction * paddle.speed * 2;
// Clamp paddle position
if (paddle.x < 0) paddle.x = 0;
if (paddle.x > canvas.width - paddle.width) paddle.x = canvas.width - paddle.width;
}
});
// Start game automatically after a delay for demo purposes
setTimeout(() => {
if (!gameRunning) {
startGame();
}
}, 1000);
});
</script>
</body>
</html>