Models 44

GPT-6.1 Terra

by OpenAIReasoningClean
Open in new window

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

How it went

Total time
48.4 s
Cost
$0.022
Output tokens
4,319
Spent thinking
104 tokens
Speed
96 tok/s
Console errors
0
First token after
3.4 s
First visible text after
6.7 s
Prompt tokens
493
Code size
12.9 KB
Finish reason
stop
Served by
OpenAI
Model id
openai/gpt-6.1-terra
Reasoning sent
{"effort":"low"}
Max output
128,000 tokens
Generated
Nov 12, 2026

What it was asked

The prompt
Build a polished Snake game in a single HTML file using vanilla JavaScript and a <canvas>. Requirements: - A grid of at least 20×20 cells, centered on the page. - Arrow keys and WASD control the snake. Quick successive key presses must both be honored, but the snake can never reverse onto itself. - Eating food adds 10 points and grows the snake by one cell; new food never spawns on the snake. - Game over when the snake hits a wall or itself, with an overlay showing the score; Space or Enter restarts, P pauses. - Visual polish: smooth movement, a snake with a distinct head and eyes facing its direction, and a small particle burst when eating. - Display the current score and the best score of the session.
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 · 197 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Snake Garden</title>
<style>
  :root{color-scheme:dark;--bg:#0b1210;--panel:#121d19;--line:#26352d;--muted:#819389;--lime:#c6f36c;--white:#edf5eb}
  *{box-sizing:border-box}
  body{margin:0;min-height:100vh;background:radial-gradient(ellipse at 50% -20%,#263d2d 0,transparent 48%),var(--bg);color:var(--white);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;display:flex;align-items:center;justify-content:center;padding:32px 20px}
  .app{width:min(100%,980px)}
  header{display:flex;justify-content:space-between;align-items:end;margin-bottom:24px;gap:20px}
  .eyebrow{font-size:10px;letter-spacing:.2em;color:var(--lime);font-weight:800;text-transform:uppercase;margin-bottom:8px}
  h1{font-size:clamp(28px,4vw,40px);letter-spacing:-.055em;line-height:1;margin:0;font-weight:750}
  h1 span{color:var(--lime)}
  .header-note{color:#8c9e92;font-size:12px;letter-spacing:.04em;text-align:right}
  .layout{display:grid;grid-template-columns:minmax(0,1fr) 230px;gap:20px;align-items:stretch}
  .board-frame{background:#17251d;border:1px solid #34483a;border-radius:18px;padding:10px;box-shadow:0 20px 60px #0005, inset 0 1px #ffffff0b;position:relative}
  .board{position:relative;width:100%;aspect-ratio:1;overflow:hidden;border-radius:10px;background:#101a14}
  canvas{display:block;width:100%;height:100%}
  .demo-label{position:absolute;top:16px;left:16px;background:#101a14d9;border:1px solid #526b42;border-radius:30px;padding:7px 10px;color:#d7efb5;font-size:10px;font-weight:800;letter-spacing:.12em;pointer-events:none}
  .demo-label:before{content:"";display:inline-block;width:6px;height:6px;background:var(--lime);border-radius:50%;margin-right:7px;vertical-align:1px;box-shadow:0 0 10px var(--lime)}
  .start-hint{position:absolute;bottom:15px;left:50%;transform:translateX(-50%);white-space:nowrap;background:#101a14e8;border:1px solid #42563c;color:#e9f6dc;padding:10px 16px;border-radius:30px;font-size:12px;font-weight:650;box-shadow:0 5px 18px #0004;pointer-events:none}
  .overlay{position:absolute;inset:0;display:none;align-items:center;justify-content:center;background:#08110cbd;backdrop-filter:blur(3px);text-align:center}
  .overlay.show{display:flex}
  .overlay-card{padding:28px}
  .overlay .small{color:var(--lime);font-size:10px;letter-spacing:.2em;font-weight:800;text-transform:uppercase}
  .overlay h2{font-size:38px;letter-spacing:-.05em;margin:10px 0}
  .overlay p{font-size:14px;color:#aebeb1;margin:0 0 20px}
  button{border:0;background:var(--lime);color:#1b2a12;padding:11px 20px;border-radius:8px;font:700 12px inherit;cursor:pointer}
  aside{display:flex;flex-direction:column;gap:12px}
  .card{border:1px solid var(--line);background:#142019;border-radius:14px;padding:19px}
  .card-title{font-size:10px;letter-spacing:.14em;color:#8da092;text-transform:uppercase;font-weight:800}
  .score{font-size:40px;font-weight:750;letter-spacing:-.06em;line-height:1;margin-top:13px}
  .score span{color:var(--lime)}
  .score-sub{font-size:11px;color:#728779;margin-top:8px}
  .best-row{display:flex;justify-content:space-between;align-items:center}
  .best-value{font-size:23px;font-weight:700;color:#dcebd7}
  .controls{flex:1;display:flex;flex-direction:column;justify-content:space-between;gap:18px}
  .control-row{display:flex;justify-content:space-between;align-items:center;color:#aebdb1;font-size:12px;margin-top:15px}
  .keys{display:flex;gap:3px}
  kbd{font:600 10px inherit;color:#dbe8d8;background:#26362b;border:1px solid #3d5041;border-bottom-width:2px;border-radius:4px;min-width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;padding:0 5px}
  .tip{font-size:11px;line-height:1.6;color:#829588;border-top:1px solid #2a3a2e;padding-top:15px}
  .tip strong{color:#c0d3bd}
  footer{display:flex;justify-content:space-between;gap:15px;margin-top:18px;color:#657a6a;font-size:10px;letter-spacing:.06em;text-transform:uppercase}
  @media(max-width:700px){body{align-items:flex-start;padding:24px 14px}.app{max-width:560px}header{margin-bottom:18px}.header-note{font-size:10px}.layout{grid-template-columns:1fr;gap:12px}aside{display:grid;grid-template-columns:1fr 1fr;gap:10px}.card{padding:14px}.score{font-size:30px;margin-top:8px}.controls{grid-column:1/-1;display:block}.controls .rows{display:flex;gap:20px;flex-wrap:wrap}.control-row{gap:12px;margin-top:12px}.tip{margin-top:12px}.board-frame{padding:7px;border-radius:14px}.start-hint{font-size:11px;padding:9px 12px}footer{margin-top:14px}}
</style>
</head>
<body>
<main class="app">
  <header>
    <div><div class="eyebrow">A little game for a little break</div><h1>Snake<span>.</span> Garden</h1></div>
    <div class="header-note">EAT. GROW. REPEAT.<br>MADE FOR THE MOMENT.</div>
  </header>
  <div class="layout">
    <div class="board-frame">
      <div class="board" id="board">
        <canvas id="game" width="720" height="720" aria-label="Snake game board"></canvas>
        <div class="demo-label" id="demoLabel">DEMO MODE</div>
        <div class="start-hint" id="startHint">Click or press a key to start</div>
        <div class="overlay" id="overlay">
          <div class="overlay-card">
            <div class="small" id="overlayLabel">A good run</div>
            <h2 id="overlayTitle">Game over</h2>
            <p id="overlayText">You scored 0 points.</p>
            <button id="restart">PLAY AGAIN &nbsp;↗</button>
          </div>
        </div>
      </div>
    </div>
    <aside>
      <div class="card"><div class="card-title">Current score</div><div class="score"><span id="score">0</span></div><div class="score-sub">10 points per bite</div></div>
      <div class="card best-row"><div><div class="card-title">Personal best</div><div class="score-sub">This session</div></div><div class="best-value" id="best">0</div></div>
      <div class="card controls">
        <div>
          <div class="card-title">How to play</div>
          <div class="rows">
            <div class="control-row"><span>Move</span><div class="keys"><kbd>↑</kbd><kbd>←</kbd><kbd>↓</kbd><kbd>→</kbd></div></div>
            <div class="control-row"><span>Also move</span><div class="keys"><kbd>W</kbd><kbd>A</kbd><kbd>S</kbd><kbd>D</kbd></div></div>
            <div class="control-row"><span>Pause</span><div class="keys"><kbd>P</kbd></div></div>
          </div>
        </div>
        <div class="tip"><strong>Stay in the garden.</strong><br>Collect the fruit, but don't run into the walls or yourself.</div>
      </div>
    </aside>
  </div>
  <footer><span>Snake Garden · No. 01</span><span>A classic, reimagined</span></footer>
</main>
<script>
(() => {
  const canvas=document.getElementById('game'),ctx=canvas.getContext('2d');
  const scoreEl=document.getElementById('score'),bestEl=document.getElementById('best');
  const demoLabel=document.getElementById('demoLabel'),hint=document.getElementById('startHint');
  const overlay=document.getElementById('overlay'),overlayLabel=document.getElementById('overlayLabel'),overlayTitle=document.getElementById('overlayTitle'),overlayText=document.getElementById('overlayText'),restart=document.getElementById('restart');
  const N=24,C=30,stepTime=135;
  const dirs={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0},w:{x:0,y:-1},s:{x:0,y:1},a:{x:-1,y:0},d:{x:1,y:0}};
  let snake,previous,dir,queue,food,score=0,best=0,mode='demo',particles=[],lastStep=performance.now(),lastFrame=lastStep;
  function reset(demo){
    snake=[{x:8,y:12},{x:7,y:12},{x:6,y:12},{x:5,y:12},{x:4,y:12}];
    previous=snake.map(p=>({...p}));dir={x:1,y:0};queue=[];food=demo?{x:13,y:12}:randomFood();
    score=0;particles=[];mode=demo?'demo':'playing';lastStep=performance.now();
    scoreEl.textContent=score;demoLabel.style.display=demo?'block':'none';hint.style.display=demo?'block':'none';overlay.classList.remove('show');
  }
  function randomFood(){
    const free=[];
    for(let y=0;y<N;y++)for(let x=0;x<N;x++)if(!snake.some(p=>p.x===x&&p.y===y))free.push({x,y});
    return free.length?free[Math.floor(Math.random()*free.length)]:null;
  }
  function enqueue(d){
    const reference=queue.length?queue[queue.length-1]:dir;
    if((d.x===-reference.x&&d.y===-reference.y)||(d.x===reference.x&&d.y===reference.y))return;
    if(queue.length<3)queue.push(d);
  }
  function demoDirection(){
    const head=snake[0];
    const options=[{x:1,y:0},{x:0,y:1},{x:-1,y:0},{x:0,y:-1}].filter(d=>{
      const x=head.x+d.x,y=head.y+d.y;
      return !(d.x===-dir.x&&d.y===-dir.y)&&x>=0&&x<N&&y>=0&&y<N&&!snake.slice(0,-1).some(p=>p.x===x&&p.y===y);
    });
    if(!options.length)return dir;
    options.sort((a,b)=>{
      const dist=d=>Math.abs(head.x+d.x-food.x)+Math.abs(head.y+d.y-food.y);
      return dist(a)-dist(b);
    });
    return options[0];
  }
  function burst(x,y){
    for(let i=0;i<18;i++){const a=Math.random()*Math.PI*2,s=35+Math.random()*115;particles.push({x:(x+.5)*C,y:(y+.5)*C,vx:Math.cos(a)*s,vy:Math.sin(a)*s,life:.35+Math.random()*.4,max:.75,size:2+Math.random()*4,color:Math.random()<.5?'#f7a86e':'#d7f68b'});}
  }
  function endGame(){
    if(mode==='demo'){reset(true);return}
    mode='over';overlayLabel.textContent='A good run';overlayTitle.textContent='Game over';overlayText.textContent=`You scored ${score} points. Press Space or Enter to restart.`;restart.textContent='PLAY AGAIN ↗';overlay.classList.add('show');
  }
  function tick(){
    if(mode!=='playing'&&mode!=='demo')return;
    if(mode==='demo')dir=demoDirection();else if(queue.length)dir=queue.shift();
    const head={x:snake[0].x+dir.x,y:snake[0].y+dir.y};
    const eating=food&&head.x===food.x&&head.y===food.y;
    if(head.x<0||head.x>=N||head.y<0||head.y>=N||snake.slice(0,eating?snake.length:-1).some(p=>p.x===head.x&&p.y===head.y)){endGame();return}
    previous=snake.map(p=>({...p}));
    snake.unshift(head);
    if(eating){
      score+=10;scoreEl.textContent=score;
      if(mode!=='demo'&&score>best){best=score;bestEl.textContent=best}
      burst(food.x,food.y);food=randomFood();
      if(!food){endGame();return}
    }else snake.pop();
  }
  function rounded(x,y,w,h,r,color){ctx.fillStyle=color;ctx.beginPath();ctx.roundRect(x,y,w,h,r);ctx.fill()}
  function draw(now){
    const dt=Math.min((now-lastFrame)/1000,.05);lastFrame=now;
    if((mode==='demo'||mode==='playing')&&now-lastStep>=stepTime){tick();lastStep=now}
    const t=(mode==='playing'||mode==='demo')?Math.min((now-lastStep)/stepTime,1):1;
    ctx.fillStyle='#111d15';ctx.fillRect(0,0,720,720);
    for(let y=0;y<N;y++)for(let x=0;x<N;x++){
      ctx.fillStyle=(x+y)%2?'#17251b':'#1a291e';ctx.fillRect(x*C,y*C,C,C);
    }
    if(food){
      const x=(food.x+.5)*C,y=(food.y+.5)*C;
      ctx.save();ctx.shadowColor='#ff9f70';ctx.shadowBlur=18;ctx.fillStyle='#f5a16e';ctx.beginPath();ctx.arc(x,y+2,9,0,Math.PI*2);ctx.fill();ctx.restore();
      ctx.strokeStyle='#d5e894';ctx.lineWidth=2.5;ctx.lineCap='round';ctx.beginPath();ctx.moveTo(x,y-6);ctx.quadraticCurveTo(x+1,y-13,x+6,y-14);ctx.stroke();
      ctx.fillStyle='#e6f3b2';ctx.beginPath();ctx.ellipse(x+5,y-12,4,2,-.5,0,Math.PI*2);ctx.fill();
    }
    for(let i=snake.length-1;i>=0;i--){
      const p=snake[i],old=previous[i]||previous[previous.length-1]||p;
      const x=(old.x+(p.x-old.x)*t)*C,y=(old.y+(p.y-old.y)*t)*C;
      rounded(x+1.5,y+1.5,C-3,C-3,i===0?9:7,i===0?'#d0f77e':i%2?'#91ce68':'#a0dc71');
      if(i===0){
        const cx=x+C/2,cy=y+C/2,fx=dir.x,fy=dir.y,sideX=-fy,sideY=fx;
        ctx.fillStyle='#233a20';
        for(const side of [-1,1]){ctx.beginPath();ctx.arc(cx+fx*5+sideX*6*side,cy+fy*5+sideY*6*side,2.3,0,Math.PI*2);ctx.fill()}
      }
    }
    particles=particles.filter(p=>p.life>0);
    for(const p of particles){p.x+=p.vx*dt;p.y+=p.vy*dt;p.vy+=80*dt;p.life-=dt;ctx.globalAlpha=Math.max(0,p.life/p.max);ctx.fillStyle=p.color;ctx.beginPath();ctx.arc(p.x,p.y,p.size,0,Math.PI*2);ctx.fill()}
    ctx.globalAlpha=1;
    requestAnimationFrame(draw);
  }
  function pause(){
    if(mode==='playing'){mode='paused';overlayLabel.textContent='Take your time';overlayTitle.textContent='Paused';overlayText.textContent='Press P to return to the garden.';restart.textContent='RESUME ↗';overlay.classList.add('show')}
    else if(mode==='paused'){mode='playing';lastStep=performance.now();overlay.classList.remove('show')}
  }
  document.addEventListener('keydown',e=>{
    const key=e.key.length===1?e.key.toLowerCase():e.key;
    if(dirs[key]||[' ','Enter','p'].includes(key))e.preventDefault();
    if(mode==='demo'){reset(false);if(dirs[key])enqueue(dirs[key]);return}
    if(mode==='over'){if(key===' '||key==='Enter')reset(false);return}
    if(key==='p'){pause();return}
    if(mode==='playing'&&dirs[key])enqueue(dirs[key]);
  });
  document.getElementById('board').addEventListener('click',e=>{if(e.target===restart)return;if(mode==='demo')reset(false)});
  restart.addEventListener('click',e=>{e.stopPropagation();if(mode==='paused')pause();else reset(false)});
  reset(true);requestAnimationFrame(draw);
})();
</script>
</body>
</html>
Reasoning trace (104 tokens)
**Designing a demo for AI snake game**

I need to create the code for a 600x600 canvas with a 24-grid layout and a sidebar header. I'm thinking about demonstrating AI's safe use with a serpentine Hamiltonian cycle. The AI should target food using a BFS approach while having a safe fallback option.

For the snake demo, I’ll place it near food and make it greedy with collision detection. I want a non-blocking overlay message at the bottom. The UI will incorporate tick interpolation for snake positions, and I should validate inputs against the last queued actions. The demo will reset on input click, with key start and direction handling, and a paused overlay. The canvas should be responsive too!