Hamburger breakoutOne-line
DeepSeek V4.1 Flash 1017
by DeepSeekReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 18.9 s
- Cost
- $0.0035
- Output tokens
- 6,977
- Spent thinking
- 0 tokens
- Speed
- 376.2 tok/s
- Console errors
- 0
- First token after
- 330 ms
- First visible text after
- 330 ms
- Prompt tokens
- 360
- Code size
- 22.3 KB
- Finish reason
- stop
- Served by
- Ionstream
- Model id
deepseek/deepseek-v4.1-flash-1017- Reasoning sent
{"effort":"none"}- Max output
- 64,000 tokens
- Generated
- Nov 10, 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 · 729 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 · Heart Explosion</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
user-select: none;
}
body {
background: #1a0e0b;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
font-family: system-ui, 'Segoe UI', Roboto, sans-serif;
padding: 16px;
}
.game-container {
position: relative;
max-width: 1000px;
width: 100%;
border-radius: 28px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.7), 0 0 0 4px #f5e7d9, 0 0 0 8px #b45f3b;
background: #2b1a12;
aspect-ratio: 4 / 3;
overflow: hidden;
}
canvas {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
cursor: none;
background: #2d1b12;
}
.overlay {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(25, 8, 4, 0.82);
backdrop-filter: blur(4px);
color: #ffefdd;
text-align: center;
padding: 24px;
transition: opacity 0.3s ease;
pointer-events: none;
z-index: 10;
font-weight: 600;
letter-spacing: 1px;
}
.overlay.hidden {
opacity: 0;
pointer-events: none;
}
.overlay .big {
font-size: clamp(1.8rem, 8vw, 3.5rem);
text-shadow: 0 6px 0 #8b3f1f, 0 10px 20px black;
margin-bottom: 12px;
background: linear-gradient(135deg, #ffe6b0, #ffb07c);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.overlay .sub {
font-size: clamp(1rem, 4vw, 1.5rem);
background: #3f2a1e;
padding: 12px 26px;
border-radius: 100px;
box-shadow: inset 0 -4px 0 #1f110b, 0 6px 0 #1f110b;
color: #ffe0b9;
font-weight: 500;
display: inline-flex;
align-items: center;
gap: 10px;
}
.overlay .sub span {
font-size: 1.6rem;
line-height: 1;
}
.hint {
margin-top: 28px;
font-size: 0.9rem;
opacity: 0.8;
font-weight: 400;
letter-spacing: 0.5px;
}
@media (max-width: 500px) {
.game-container {
border-radius: 18px;
}
}
</style>
</head>
<body>
<div class="game-container">
<canvas id="gameCanvas" width="800" height="600"></canvas>
<div class="overlay" id="overlay">
<div class="big">🍔 HAMBURGER BREAKOUT 🍔</div>
<div class="sub"><span>❤️</span> Click or press a key to start <span>❤️</span></div>
<div class="hint">Move mouse / arrow keys · Every brick explodes into hearts</div>
</div>
</div>
<script>
(function() {
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const overlay = document.getElementById('overlay');
// ---------- FIXED DIMENSIONS ----------
const W = 800, H = 600;
canvas.width = W;
canvas.height = H;
// ---------- GAME STATE ----------
let gameActive = false;
let demoMode = true; // self-playing AI
let gameStarted = false; // user already started
let gameOver = false;
let gameWin = false;
// ---------- PADDLE (hamburger) ----------
const paddle = {
x: W / 2 - 60,
y: H - 40,
w: 120,
h: 30,
speed: 9,
targetX: W / 2 - 60,
};
// ---------- BALL ----------
const ball = {
x: W / 2,
y: H - 80,
vx: 0,
vy: 0,
r: 8,
speed: 6.8,
active: true,
};
// ---------- BRICKS ----------
const BRICK_ROWS = 5;
const BRICK_COLS = 9;
const BRICK_W = 72;
const BRICK_H = 24;
const BRICK_GAP = 10;
const BRICK_OFFSET_X = (W - (BRICK_COLS * (BRICK_W + BRICK_GAP) - BRICK_GAP)) / 2;
const BRICK_OFFSET_Y = 60;
let bricks = [];
let hearts = []; // particle hearts
let score = 0;
let totalBricks = 0;
// ---------- COLORS ----------
const brickColors = [
'#f9c74f', // yellow
'#f9844a', // orange
'#f25c5c', // red
'#e56b6f', // pink
'#b5838d', // mauve
];
// ---------- INIT BRICKS ----------
function initBricks() {
bricks = [];
totalBricks = 0;
for (let row = 0; row < BRICK_ROWS; row++) {
for (let col = 0; col < BRICK_COLS; col++) {
const bx = BRICK_OFFSET_X + col * (BRICK_W + BRICK_GAP);
const by = BRICK_OFFSET_Y + row * (BRICK_H + BRICK_GAP);
// maybe skip some for pattern? keep all for more hearts
bricks.push({
x: bx, y: by, w: BRICK_W, h: BRICK_H,
color: brickColors[row % brickColors.length],
alive: true,
});
totalBricks++;
}
}
}
initBricks();
// ---------- HEART PARTICLES ----------
function spawnHearts(x, y, count = 12) {
for (let i = 0; i < count; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = 1.5 + Math.random() * 5.5;
const vx = Math.cos(angle) * speed;
const vy = Math.sin(angle) * speed - 1.5; // slight upward bias
const size = 6 + Math.random() * 10;
const life = 0.8 + Math.random() * 0.9;
const rot = Math.random() * Math.PI * 2;
const rotSpeed = (Math.random() - 0.5) * 0.2;
hearts.push({
x, y,
vx, vy,
size,
life,
maxLife: life,
rot,
rotSpeed,
alpha: 1,
color: Math.random() > 0.3 ? '#ff4d6d' : '#ff8fa3',
});
}
}
// ---------- RESET BALL ----------
function resetBall() {
ball.x = paddle.x + paddle.w / 2;
ball.y = paddle.y - 20;
const angle = (Math.random() * 0.8 - 0.4) + Math.PI / 2; // mostly upwards
ball.vx = Math.cos(angle) * ball.speed * 0.7;
ball.vy = -Math.sin(angle) * ball.speed * 0.7;
ball.active = true;
}
// ---------- RESET GAME ----------
function resetGame() {
initBricks();
score = 0;
hearts = [];
paddle.x = W / 2 - paddle.w / 2;
paddle.targetX = paddle.x;
ball.speed = 6.8;
ball.x = W / 2;
ball.y = H - 80;
ball.vx = (Math.random() > 0.5 ? 1 : -1) * 4.5;
ball.vy = -5.5;
ball.active = true;
gameOver = false;
gameWin = false;
demoMode = true;
gameStarted = false;
gameActive = false;
overlay.classList.remove('hidden');
}
// ---------- START ----------
function startGame() {
if (gameStarted) return;
overlay.classList.add('hidden');
gameStarted = true;
gameActive = true;
demoMode = false; // disable AI
// reset ball/ paddle for a clean start
resetGame();
// small delay for ball movement? no, start immediately
gameActive = true;
demoMode = false;
ball.x = W / 2;
ball.y = H - 100;
ball.vx = (Math.random() > 0.5 ? 1 : -1) * 4.8;
ball.vy = -6.2;
ball.active = true;
}
// ---------- TRIGGER START ----------
function handleStart() {
if (!gameStarted && (gameOver || gameWin || demoMode || !gameActive)) {
// If game over, reset and then start
if (gameOver || gameWin) {
resetGame();
gameStarted = false;
demoMode = true;
gameActive = false;
gameOver = false;
gameWin = false;
// immediately start after short delay
setTimeout(() => {
if (!gameStarted) startGame();
}, 100);
} else {
startGame();
}
} else if (!gameActive && !gameOver && !gameWin) {
startGame();
} else if (gameOver || gameWin) {
resetGame();
gameStarted = false;
demoMode = true;
gameActive = false;
gameOver = false;
gameWin = false;
overlay.classList.remove('hidden');
}
}
// ---------- INPUT ----------
canvas.addEventListener('mousemove', (e) => {
if (!gameActive) return;
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
let mouseX = (e.clientX - rect.left) * scaleX;
paddle.targetX = Math.min(Math.max(mouseX - paddle.w / 2, 0), W - paddle.w);
});
window.addEventListener('keydown', (e) => {
if (!gameStarted) {
// start on any key
e.preventDefault();
handleStart();
return;
}
if (!gameActive) return;
if (e.key === 'ArrowLeft' || e.key === 'a' || e.key === 'A') {
e.preventDefault();
paddle.targetX = Math.max(0, paddle.targetX - 35);
} else if (e.key === 'ArrowRight' || e.key === 'd' || e.key === 'D') {
e.preventDefault();
paddle.targetX = Math.min(W - paddle.w, paddle.targetX + 35);
}
});
canvas.addEventListener('mousedown', (e) => {
e.preventDefault();
if (!gameStarted) {
handleStart();
} else if (gameOver || gameWin) {
handleStart();
}
});
overlay.addEventListener('mousedown', (e) => {
e.preventDefault();
if (!gameStarted) {
handleStart();
}
});
// also click on canvas if game over
canvas.addEventListener('click', (e) => {
if (gameOver || gameWin) handleStart();
});
// ---------- UPDATE ----------
function update() {
// demo AI: move paddle toward ball
if (demoMode) {
// simple AI: follow the ball x position, but with some error
const target = ball.x - paddle.w / 2;
paddle.targetX = Math.min(Math.max(target, 0), W - paddle.w);
// shift ball a bit for fun
}
// smooth paddle movement
const dx = paddle.targetX - paddle.x;
paddle.x += dx * 0.25;
paddle.x = Math.max(0, Math.min(W - paddle.w, paddle.x));
if (!gameActive) return;
// ball movement
if (!ball.active) return;
ball.x += ball.vx;
ball.y += ball.vy;
// walls
if (ball.x - ball.r < 0) {
ball.x = ball.r;
ball.vx = -ball.vx;
}
if (ball.x + ball.r > W) {
ball.x = W - ball.r;
ball.vx = -ball.vx;
}
if (ball.y - ball.r < 0) {
ball.y = ball.r;
ball.vy = -ball.vy;
}
// paddle collision
if (ball.y + ball.r > paddle.y && ball.y - ball.r < paddle.y + paddle.h &&
ball.x + ball.r > paddle.x && ball.x - ball.r < paddle.x + paddle.w) {
// only bounce if moving down
if (ball.vy > 0) {
ball.y = paddle.y - ball.r;
// reflect based on hit position
const hit = (ball.x - (paddle.x + paddle.w / 2)) / (paddle.w / 2);
const maxAngle = 1.2;
const angle = hit * maxAngle;
const spd = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy);
ball.vx = Math.sin(angle) * spd;
ball.vy = -Math.cos(angle) * spd;
// slightly increase speed
if (spd < 12) {
ball.vx *= 1.02;
ball.vy *= 1.02;
}
}
}
// bottom - lose
if (ball.y - ball.r > H) {
ball.active = false;
gameActive = false;
gameOver = true;
overlay.classList.remove('hidden');
overlay.innerHTML = `<div class="big">💔 GAME OVER 💔</div>
<div class="sub" style="cursor:pointer">Click or press a key to restart</div>
<div class="hint">Score: ${score} hearts</div>`;
overlay.style.pointerEvents = 'auto';
return;
}
// brick collision
for (let brick of bricks) {
if (!brick.alive) continue;
if (ball.x + ball.r > brick.x && ball.x - ball.r < brick.x + brick.w &&
ball.y + ball.r > brick.y && ball.y - ball.r < brick.y + brick.h) {
// destroy brick
brick.alive = false;
score++;
// spawn hearts
spawnHearts(brick.x + brick.w / 2, brick.y + brick.h / 2, 18);
// bounce ball
// determine direction
const overlapLeft = (ball.x + ball.r) - brick.x;
const overlapRight = (brick.x + brick.w) - (ball.x - ball.r);
const overlapTop = (ball.y + ball.r) - brick.y;
const overlapBottom = (brick.y + brick.h) - (ball.y - ball.r);
const minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);
if (minOverlap === overlapLeft) {
ball.vx = -Math.abs(ball.vx);
ball.x = brick.x - ball.r;
} else if (minOverlap === overlapRight) {
ball.vx = Math.abs(ball.vx);
ball.x = brick.x + brick.w + ball.r;
} else if (minOverlap === overlapTop) {
ball.vy = -Math.abs(ball.vy);
ball.y = brick.y - ball.r;
} else if (minOverlap === overlapBottom) {
ball.vy = Math.abs(ball.vy);
ball.y = brick.y + brick.h + ball.r;
}
break; // only one brick per frame
}
}
// check win
const aliveBricks = bricks.filter(b => b.alive).length;
if (aliveBricks === 0) {
gameActive = false;
gameWin = true;
overlay.classList.remove('hidden');
overlay.innerHTML = `<div class="big">🍔 YOU WIN! 🍔</div>
<div class="sub" style="cursor:pointer">Click or press a key to play again</div>
<div class="hint">Hearts scattered: ${score * 18}</div>`;
overlay.style.pointerEvents = 'auto';
}
// update hearts
for (let i = hearts.length - 1; i >= 0; i--) {
const h = hearts[i];
h.x += h.vx;
h.y += h.vy;
h.vy += 0.12; // gravity
h.vx *= 0.99;
h.rot += h.rotSpeed;
h.life -= 0.012;
if (h.life <= 0) {
hearts.splice(i, 1);
}
}
}
// ---------- DRAW ----------
function draw() {
ctx.clearRect(0, 0, W, H);
// background gradient
const bgGrad = ctx.createLinearGradient(0, 0, 0, H);
bgGrad.addColorStop(0, '#2d1b12');
bgGrad.addColorStop(1, '#1f0f08');
ctx.fillStyle = bgGrad;
ctx.fillRect(0, 0, W, H);
// subtle tiles
ctx.fillStyle = '#3e241b';
for (let i = 0; i < W; i += 40) {
for (let j = 0; j < H; j += 40) {
if ((i / 40 + j / 40) % 2 === 0) {
ctx.fillRect(i, j, 40, 40);
}
}
}
// bricks
for (let brick of bricks) {
if (!brick.alive) continue;
// rounded rect with shine
ctx.shadowColor = 'rgba(0,0,0,0.5)';
ctx.shadowBlur = 8;
ctx.shadowOffsetY = 4;
ctx.fillStyle = brick.color;
ctx.beginPath();
ctx.roundRect(brick.x, brick.y, brick.w, brick.h, 8);
ctx.fill();
// highlight
ctx.shadowBlur = 0;
ctx.shadowOffsetY = 0;
ctx.fillStyle = 'rgba(255,255,255,0.25)';
ctx.beginPath();
ctx.roundRect(brick.x + 4, brick.y + 4, brick.w - 8, 6, 4);
ctx.fill();
}
ctx.shadowBlur = 0;
ctx.shadowOffsetY = 0;
// draw hearts
for (let h of hearts) {
const alpha = Math.min(1, h.life / 0.6);
ctx.save();
ctx.translate(h.x, h.y);
ctx.rotate(h.rot);
ctx.globalAlpha = alpha;
ctx.fillStyle = h.color;
ctx.shadowColor = '#ff4d6d';
ctx.shadowBlur = 18;
// heart shape
const s = h.size;
ctx.beginPath();
ctx.moveTo(0, s * 0.3);
ctx.bezierCurveTo(-s * 0.5, -s * 0.3, -s * 0.2, -s * 0.8, 0, -s * 0.4);
ctx.bezierCurveTo(s * 0.2, -s * 0.8, s * 0.5, -s * 0.3, 0, s * 0.3);
ctx.closePath();
ctx.fill();
ctx.restore();
}
ctx.globalAlpha = 1;
ctx.shadowBlur = 0;
// draw paddle (hamburger)
drawHamburger(paddle.x, paddle.y, paddle.w, paddle.h);
// draw ball
if (ball.active) {
ctx.shadowColor = '#ffdd44';
ctx.shadowBlur = 24;
ctx.fillStyle = '#ffe066';
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2);
ctx.fill();
// inner shine
ctx.shadowBlur = 0;
ctx.fillStyle = '#fff9c4';
ctx.beginPath();
ctx.arc(ball.x - 2, ball.y - 2, ball.r * 0.4, 0, Math.PI * 2);
ctx.fill();
}
// score
ctx.font = 'bold 22px "Segoe UI", system-ui, sans-serif';
ctx.fillStyle = '#ffe0b9';
ctx.shadowColor = '#3a1e0e';
ctx.shadowBlur = 8;
ctx.shadowOffsetY = 3;
ctx.fillText(`❤️ ${score}`, 24, 44);
ctx.shadowBlur = 0;
ctx.shadowOffsetY = 0;
// demo hint
if (demoMode && !gameStarted && gameActive) {
ctx.font = 'bold 18px system-ui, sans-serif';
ctx.fillStyle = '#d9b38c';
ctx.shadowBlur = 10;
ctx.fillText('🍔 DEMO MODE 🍔', W - 230, 44);
}
}
function drawHamburger(x, y, w, h) {
const bunTop = y + 2;
const bunBottom = y + h - 4;
const midY = y + h * 0.45;
const pattyY = y + h * 0.62;
// bottom bun
ctx.fillStyle = '#c97b3d';
ctx.shadowColor = '#4a2a10';
ctx.shadowBlur = 12;
ctx.shadowOffsetY = 5;
ctx.beginPath();
ctx.roundRect(x, y + h * 0.55, w, h * 0.45, [12, 12, 24, 24]);
ctx.fill();
// patty
ctx.fillStyle = '#5a2e16';
ctx.shadowBlur = 10;
ctx.beginPath();
ctx.roundRect(x + 4, y + h * 0.45, w - 8, h * 0.25, 8);
ctx.fill();
// cheese
ctx.fillStyle = '#ffb703';
ctx.shadowBlur = 8;
ctx.beginPath();
ctx.ellipse(x + w * 0.28, y + h * 0.42, w * 0.18, h * 0.08, 0.2, 0, 2 * Math.PI);
ctx.ellipse(x + w * 0.72, y + h * 0.42, w * 0.18, h * 0.08, -0.2, 0, 2 * Math.PI);
ctx.fill();
// lettuce
ctx.fillStyle = '#6a994e';
ctx.shadowBlur = 8;
ctx.beginPath();
ctx.ellipse(x + w * 0.2, y + h * 0.35, w * 0.14, h * 0.06, 0.4, 0, 2 * Math.PI);
ctx.ellipse(x + w * 0.5, y + h * 0.3, w * 0.16, h * 0.07, 0.2, 0, 2 * Math.PI);
ctx.ellipse(x + w * 0.8, y + h * 0.35, w * 0.14, h * 0.06, -0.3, 0, 2 * Math.PI);
ctx.fill();
// top bun
ctx.fillStyle = '#d68c4e';
ctx.shadowBlur = 14;
ctx.shadowOffsetY = 6;
ctx.beginPath();
ctx.roundRect(x, y, w, h * 0.55, [16, 16, 8, 8]);
ctx.fill();
// sesame seeds
ctx.fillStyle = '#fff6e0';
ctx.shadowBlur = 4;
ctx.shadowOffsetY = 2;
const seedPositions = [
[0.3, 0.22], [0.5, 0.1], [0.7, 0.18], [0.4, 0.35], [0.6, 0.32], [0.2, 0.4], [0.8, 0.38]
];
for (let [sx, sy] of seedPositions) {
ctx.beginPath();
ctx.ellipse(x + w * sx, y + h * sy, 4, 2.5, 0.4, 0, 2 * Math.PI);
ctx.fill();
}
ctx.shadowBlur = 0;
ctx.shadowOffsetY = 0;
}
// helper for roundRect
CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) {
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
if (typeof r === 'number') {
this.moveTo(x + r, y);
this.lineTo(x + w - r, y);
this.quadraticCurveTo(x + w, y, x + w, y + r);
this.lineTo(x + w, y + h - r);
this.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
this.lineTo(x + r, y + h);
this.quadraticCurveTo(x, y + h, x, y + h - r);
this.lineTo(x, y + r);
this.quadraticCurveTo(x, y, x + r, y);
} else {
// array of radii
const [tl, tr, br, bl] = r;
this.moveTo(x + tl, y);
this.lineTo(x + w - tr, y);
this.quadraticCurveTo(x + w, y, x + w, y + tr);
this.lineTo(x + w, y + h - br);
this.quadraticCurveTo(x + w, y + h, x + w - br, y + h);
this.lineTo(x + bl, y + h);
this.quadraticCurveTo(x, y + h, x, y + h - bl);
this.lineTo(x, y + tl);
this.quadraticCurveTo(x, y, x + tl, y);
}
return this;
};
// ---------- GAME LOOP ----------
let lastTime = 0;
function gameLoop(now) {
// fixed update rate ~60fps
update();
draw();
requestAnimationFrame(gameLoop);
}
// ---------- INITIAL STATE FOR DEMO ----------
function initDemo() {
resetGame();
// demo mode: ball active & AI plays
gameActive = true;
demoMode = true;
gameStarted = false;
gameOver = false;
gameWin = false;
overlay.classList.remove('hidden');
// overlay content back to default
overlay.innerHTML = `<div class="big">🍔 HAMBURGER BREAKOUT 🍔</div>
<div class="sub"><span>❤️</span> Click or press a key to start <span>❤️</span></div>
<div class="hint">Move mouse / arrow keys · Every brick explodes into hearts</div>`;
overlay.style.pointerEvents = 'none';
// reset ball
ball.x = W / 2;
ball.y = H - 100;
ball.vx = 4.5;
ball.vy = -5.5;
ball.active = true;
paddle.x = W / 2 - paddle.w / 2;
paddle.targetX = paddle.x;
}
initDemo();
// start loop
requestAnimationFrame(gameLoop);
// handle click on overlay to start
overlay.addEventListener('click', (e) => {
e.stopPropagation();
if (!gameStarted) {
handleStart();
}
});
// ensure pointer events
window.addEventListener('load', () => {
overlay.style.pointerEvents = 'none';
});
})();
</script>
</body>
</html>