Models 44

GLM 5.3

by Z.aiReasoningClean
Open in new window

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

How it went

Total time
19.9 s
Cost
$0.011
Output tokens
3,568
Spent thinking
34 tokens
Speed
184.5 tok/s
Console errors
0
First token after
546 ms
First visible text after
2.1 s
Prompt tokens
357
Code size
9.9 KB
Finish reason
stop
Served by
CoreWeave
Model id
z-ai/glm-5.3
Reasoning sent
{"effort":"low"}
Max output
943,718 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 · 282 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HeartBreaker — Burger Breakout</title>
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  html, body { height: 100%; overflow: hidden; }
  body {
    background: radial-gradient(ellipse at 50% 0%, #2b1a3d 0%, #14092b 60%, #0a0518 100%);
    font-family: Georgia, 'Times New Roman', serif;
    display: flex; align-items: center; justify-content: center;
    color: #ffd9ec;
  }
  #wrap { position: relative; width: 100%; max-width: 900px; }
  canvas { display: block; width: 100%; height: auto; border-radius: 12px; }
  #overlay {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 14px;
    background: rgba(10,5,24,.55); backdrop-filter: blur(2px);
    border-radius: 12px; text-align: center; padding: 20px;
    transition: opacity .4s; cursor: pointer;
  }
  #overlay.hidden { opacity: 0; pointer-events: none; }
  #overlay h1 { font-size: clamp(28px, 6vw, 54px); letter-spacing: 2px;
    text-shadow: 0 0 18px #ff5fa8, 0 2px 0 #7a1f4d; color: #fff; font-style: italic; }
  #overlay p { font-size: clamp(15px, 2.5vw, 20px); color: #ffd9ec; }
  #hud { position: absolute; top: 10px; left: 14px; right: 14px;
    display: flex; justify-content: space-between; font-size: 17px;
    pointer-events: none; text-shadow: 0 1px 3px #000; letter-spacing: 1px; }
  .blink { animation: bl 1.2s infinite; }
  @keyframes bl { 50% { opacity: .35; } }
</style>
</head>
<body>
<div id="wrap">
  <canvas id="cv" width="900" height="620"></canvas>
  <div id="hud"><span>SCORE <b id="score">0</b></span><span>HEARTS 💗 <b id="lives">3</b></span></div>
  <div id="overlay">
    <h1>💗 HeartBreaker 🍔</h1>
    <p>Break bricks with your burger paddle —<br>every brick bursts into little hearts!</p>
    <p class="blink" id="cta">Click or press a key to start</p>
    <p style="font-size:14px;opacity:.7">← → or mouse to move the burger</p>
  </div>
</div>
<script>
const cv = document.getElementById('cv'), ctx = cv.getContext('2d');
const W = cv.width, H = cv.height;
const overlay = document.getElementById('overlay');
const scoreEl = document.getElementById('score'), livesEl = document.getElementById('lives');

let score = 0, lives = 3, playing = false, demo = true;
let paddleX = W/2, paddleW = 130, paddleH = 42, paddleY = H - 60;
let targetX = W/2;
let ball = { x: W/2, y: H-120, r: 9, vx: 3.2, vy: -4.4, stuck: false };
let bricks = [], hearts = [], floats = [];

const COLS = 10, ROWS = 5, BW = 74, BH = 26, GAP = 8, TOP = 70;
const COLORS = ['#ff5c8a','#ff8f5c','#ffd15c','#7ee08a','#6cc5ff'];

function buildBricks(){
  bricks = [];
  const totalW = COLS*BW + (COLS-1)*GAP;
  const ox = (W - totalW)/2;
  for (let r=0;r<ROWS;r++) for (let c=0;c<COLS;c++)
    bricks.push({x: ox + c*(BW+GAP), y: TOP + r*(BH+GAP), w: BW, h: BH, col: COLORS[r], alive: true});
}
buildBricks();

function burst(x, y, col){
  for (let i=0;i<26;i++){
    const a = Math.random()*Math.PI*2, s = 1+Math.random()*4.5;
    hearts.push({x, y, vx: Math.cos(a)*s, vy: Math.sin(a)*s - 1.5,
      size: 4+Math.random()*8, rot: Math.random()*6.28, vr:(Math.random()-.5)*.3,
      life: 1, hue: Math.random()<.5 ? col : '#ff5c9e'});
  }
  floats.push({x, y, txt: '+10', life: 1});
}

function drawHeart(x, y, s, rot, col, alpha){
  ctx.save(); ctx.translate(x,y); ctx.rotate(rot); ctx.scale(s/10, s/10);
  ctx.globalAlpha = alpha;
  ctx.fillStyle = col;
  ctx.beginPath();
  ctx.moveTo(0, 4);
  ctx.bezierCurveTo(-10, -6, -5, -14, 0, -8);
  ctx.bezierCurveTo(5, -14, 10, -6, 0, 4);
  ctx.fill(); ctx.restore();
}

function drawBurger(cx){
  const x = cx - paddleW/2, y = paddleY;
  ctx.save();
  // bun top
  ctx.fillStyle = '#e8a34e';
  ctx.beginPath();
  ctx.moveTo(x, y+16);
  ctx.quadraticCurveTo(x+paddleW/2, y-22, x+paddleW, y+16);
  ctx.closePath(); ctx.fill();
  ctx.fillStyle = 'rgba(255,255,255,.25)';
  for (let i=0;i<6;i++){
    ctx.beginPath();
    ctx.arc(x+18+i*(paddleW-36)/5, y+4+ (i%2)*3, 2.4, 0, 7); ctx.fill();
  }
  // lettuce
  ctx.fillStyle = '#6fbf4a';
  ctx.beginPath();
  ctx.moveTo(x, y+18);
  for (let i=0;i<9;i++) ctx.quadraticCurveTo(x+ (i+.5)*paddleW/9, y+ (i%2? 26:14), x+(i+1)*paddleW/9, y+18);
  ctx.lineTo(x+paddleW, y+22); ctx.lineTo(x, y+22); ctx.fill();
  // tomato
  ctx.fillStyle = '#d8433f';
  ctx.fillRect(x+4, y+24, paddleW-8, 5);
  // patty
  ctx.fillStyle = '#6b3d1f';
  ctx.beginPath();
  ctx.roundRect(x-3, y+29, paddleW+6, 10, 5); ctx.fill();
  // bun bottom
  ctx.fillStyle = '#e8a34e';
  ctx.beginPath();
  ctx.roundRect(x, y+38, paddleW, 12, 6); ctx.fill();
  ctx.restore();
}

function resetBall(dir){
  ball.x = paddleX; ball.y = paddleY - 24;
  const ang = (-Math.PI/2) + (Math.random()-.5)*.7;
  const sp = 6;
  ball.vx = Math.cos(ang)*sp*(dir||1); ball.vy = Math.sin(ang)*sp;
}

function reflectOffPaddle(){
  const hit = (ball.x - paddleX) / (paddleW/2);
  const sp = Math.min(9, Math.hypot(ball.vx, ball.vy)*1.03);
  const ang = -Math.PI/2 + hit*1.0;
  ball.vx = Math.cos(ang)*sp; ball.vy = Math.sin(ang)*sp;
}

function aiMove(){
  // simple demo AI
  const px = ball.vx > 0 && ball.y < H*0.6 ? ball.x + 60 : ball.x;
  targetX = Math.max(paddleW/2, Math.min(W-paddleW/2, px + Math.sin(t*2)*10));
}

let t = 0;
function update(){
  t += 0.016;
  if (demo) aiMove();
  paddleX += (targetX - paddleX) * 0.25;
  paddleX = Math.max(paddleW/2, Math.min(W-paddleW/2, paddleX));

  if (!ball.stuck){
    ball.x += ball.vx; ball.y += ball.vy;
    if (ball.x < ball.r){ ball.x = ball.r; ball.vx *= -1; }
    if (ball.x > W-ball.r){ ball.x = W-ball.r; ball.vx *= -1; }
    if (ball.y < ball.r){ ball.y = ball.r; ball.vy *= -1; }

    // paddle collision — ball vs burger
    if (ball.vy > 0 && ball.y + ball.r > paddleY && ball.y - ball.r < paddleY + paddleH &&
        ball.x > paddleX - paddleW/2 - ball.r && ball.x < paddleX + paddleW/2 + ball.r){
      ball.y = paddleY - ball.r;
      reflectOffPaddle();
      for (let i=0;i<5;i++) hearts.push({x: ball.x, y: paddleY, vx:(Math.random()-.5)*3, vy: -Math.random()*3,
        size: 5+Math.random()*5, rot: Math.random()*6, vr: .1, life: 1, hue: '#ffd15c'});
    }

    // bricks
    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;
        score += 10; scoreEl.textContent = score;
        burst(b.x + b.w/2, b.y + b.h/2, b.col);
        // bounce: pick axis by penetration
        const oxl = ball.x + ball.r - b.x, oxr = b.x + b.w - (ball.x - ball.r);
        const oyt = ball.y + ball.r - b.y, oyb = b.y + b.h - (ball.y - ball.r);
        const m = Math.min(oxl, oxr, oyt, oyb);
        if (m === oxl || m === oxr) ball.vx *= -1; else ball.vy *= -1;
        break;
      }
    }

    if (bricks.every(b=>!b.alive)){
      buildBricks(); score += 100; scoreEl.textContent = score;
      for (let i=0;i<60;i++) burst(Math.random()*W, TOP+Math.random()*200, '#fff');
      resetBall(1);
    }

    if (ball.y > H + 30){
      lives--; livesEl.textContent = Math.max(0,lives);
      if (lives <= 0){ lives = 3; score = 0; scoreEl.textContent = 0; livesEl.textContent = 3; }
      if (!demo){ ball.stuck = true; }
      resetBall(Math.random()<.5?1:-1);
    }
  } else {
    ball.x = paddleX; ball.y = paddleY - 24;
  }

  // hearts
  for (const h of hearts){
    h.x += h.vx; h.y += h.vy; h.vy += .12; h.rot += h.vr; h.life -= .012;
  }
  hearts = hearts.filter(h => h.life > 0 && h.y < H + 40);
  for (const f of floats){ f.y -= 1; f.life -= .02; }
  floats = floats.filter(f => f.life > 0);
}

function render(){
  // background
  const g = ctx.createLinearGradient(0,0,0,H);
  g.addColorStop(0,'#241238'); g.addColorStop(1,'#120825');
  ctx.fillStyle = g; ctx.fillRect(0,0,W,H);
  // faint hearts bg
  ctx.globalAlpha = .06;
  for (let i=0;i<8;i++) drawHeart(100+i*100, 150 + Math.sin(i*2)*60, 40, .3, '#ff5c9e', 1);
  ctx.globalAlpha = 1;

  for (const b of bricks){
    if (!b.alive) continue;
    ctx.fillStyle = b.col;
    ctx.beginPath(); ctx.roundRect(b.x, b.y, b.w, b.h, 6); ctx.fill();
    ctx.fillStyle = 'rgba(255,255,255,.3)';
    ctx.beginPath(); ctx.roundRect(b.x+4, b.y+4, b.w-8, 6, 3); ctx.fill();
    ctx.strokeStyle = 'rgba(0,0,0,.3)'; ctx.strokeRect(b.x+.5, b.y+.5, b.w-1, b.h-1);
  }

  for (const h of hearts) drawHeart(h.x, h.y, h.size, h.rot, h.hue, Math.max(0,h.life));

  ctx.font = 'bold 20px Georgia'; ctx.textAlign = 'center';
  for (const f of floats){
    ctx.globalAlpha = f.life; ctx.fillStyle = '#fff';
    ctx.fillText(f.txt, f.x, f.y); ctx.globalAlpha = 1;
  }

  drawBurger(paddleX);

  // ball — a little heart!
  drawHeart(ball.x, ball.y + 6, 18, 0, '#ff3d7f', 1);
  drawHeart(ball.x, ball.y + 5, 11, 0, '#ff8fb8', 1);

  if (ball.stuck){
    ctx.fillStyle = '#ffd9ec'; ctx.font = '16px Georgia';
    ctx.fillText('Click to launch the heart!', W/2, H-110);
  }
}

function loop(){ update(); render(); requestAnimationFrame(loop); }
loop();

function start(){
  if (playing) return;
  playing = true; demo = false;
  overlay.classList.add('hidden');
  lives = 3; score = 0;
  scoreEl.textContent = 0; livesEl.textContent = 3;
  buildBricks(); resetBall(1);
}
overlay.addEventListener('click', start);
window.addEventListener('keydown', e => {
  if (!playing){ start(); return; }
  if (e.key === 'ArrowLeft')  targetX = paddleX - 90;
  if (e.key === 'ArrowRight') targetX = paddleX + 90;
  if (e.key === ' ' && ball.stuck){ ball.stuck = false; resetBall(1); }
});
cv.addEventListener('mousemove', e => {
  const r = cv.getBoundingClientRect();
  targetX = (e.clientX - r.left) * (W / r.width);
});
overlay.addEventListener('mousemove', e => {
  if (demo){
    const r = cv.getBoundingClientRect();
    // keep AI in demo
  }
});
cv.addEventListener('click', () => { if (playing && ball.stuck) ball.stuck = false; });
// gentle idle drift so demo looks alive
setInterval(()=>{ if (demo && !ball.stuck) {} }, 1000);
</script>
</body>
</html>
Reasoning trace (34 tokens)
Make a canvas breakout game: paddle = hamburger (drawn with arcs), bricks explode into heart particles. Self-playing demo mode, click/key to start.