GPT-6 Luna
by OpenAIReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 40.6 s
- Cost
- $0.0021
- Output tokens
- 4,174
- Spent thinking
- 211 tokens
- Speed
- 138.9 tok/s
- Console errors
- 0
- First token after
- 10.5 s
- First visible text after
- 11.9 s
- Prompt tokens
- 493
- Code size
- 11.5 KB
- Finish reason
- stop
- Served by
- OpenAI
- Model id
openai/gpt-6-luna- Reasoning sent
{"effort":"low"}- Max output
- 64,000 tokens
- Generated
- Nov 10, 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 · 166 lines
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Snake — Arcade</title>
<style>
:root{color-scheme:dark;--bg:#0a0e14;--panel:#111821;--line:#202b37;--muted:#8593a5;--green:#9df36b;--text:#eef4f8}
*{box-sizing:border-box}
body{margin:0;min-height:100vh;background:radial-gradient(ellipse at 50% 5%,#17231e 0%,#0b1116 39%,var(--bg) 76%);color:var(--text);font-family:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;display:grid;place-items:center;padding:28px}
.app{width:min(100%,1050px)}
header{display:flex;align-items:center;justify-content:space-between;margin:0 0 22px;padding:0 4px}
.brand{display:flex;gap:13px;align-items:center}
.brand-icon{width:42px;height:42px;border:1px solid #34453b;background:#17231d;border-radius:13px;display:grid;place-items:center;color:var(--green);font-size:23px;box-shadow:inset 0 0 18px #9df36b0c}
h1{font-size:20px;letter-spacing:-.5px;margin:0;font-weight:750}
.subtitle{font-size:11px;color:var(--muted);margin-top:3px;letter-spacing:1.5px;text-transform:uppercase}
.status{display:flex;align-items:center;gap:8px;color:#aeb9c3;font-size:12px}
.dot{width:7px;height:7px;border-radius:50%;background:var(--green);box-shadow:0 0 10px #9df36b}
.layout{display:grid;grid-template-columns:minmax(0,700px) 230px;gap:22px;align-items:stretch;justify-content:center}
.board-wrap{position:relative;border:1px solid #26333b;border-radius:17px;padding:10px;background:linear-gradient(145deg,#141c22,#0d1318);box-shadow:0 25px 80px #0008,0 0 50px #8ce45b08}
canvas{display:block;width:100%;aspect-ratio:1;border-radius:10px}
.side{display:flex;flex-direction:column;gap:13px}
.card{background:linear-gradient(145deg,#141d25,#10171e);border:1px solid var(--line);border-radius:14px;padding:18px}
.label{color:var(--muted);font-size:10px;font-weight:700;letter-spacing:1.5px;text-transform:uppercase}
.score{font-size:38px;line-height:1.1;letter-spacing:-1.5px;font-weight:750;margin-top:10px;font-variant-numeric:tabular-nums}
.score small{font-size:14px;color:var(--muted);font-weight:500;letter-spacing:0}
.best{font-size:24px}
.food-key{display:flex;align-items:center;gap:10px;margin-top:13px;color:#b6c1cb;font-size:12px}
.food-icon{width:11px;height:11px;border-radius:50%;background:#ff7871;box-shadow:0 0 12px #ff787180}
.controls{padding:16px 18px}
.key-row{display:flex;gap:5px;margin-top:11px;align-items:center}
kbd{min-width:27px;height:26px;padding:0 7px;display:grid;place-items:center;border-radius:6px;border:1px solid #35414c;background:#1a242d;color:#d8e0e6;font:600 11px ui-monospace,monospace;box-shadow:0 2px 0 #080c10}
.control-note{font-size:11px;color:#95a2ae;line-height:1.6;margin-top:13px}
.help{margin-top:auto;padding:4px 6px;color:#758291;font-size:11px;line-height:1.9}
.help strong{color:#aeb9c3;font-weight:600}
.banner{position:absolute;bottom:21px;left:50%;transform:translateX(-50%);width:max-content;max-width:calc(100% - 35px);padding:10px 15px;border-radius:9px;background:#0b1112dc;border:1px solid #405143;backdrop-filter:blur(8px);color:#dbe8d8;font-size:12px;text-align:center;box-shadow:0 5px 20px #0005}
.banner b{color:var(--green);font-weight:700}
.banner.over{border-color:#5a383a;color:#f0d6d4}
.banner.over b{color:#ff938b}
@media(max-width:760px){body{padding:15px}.layout{grid-template-columns:minmax(0,1fr);gap:12px}.side{display:grid;grid-template-columns:1fr 1fr;gap:10px}.card{padding:14px}.score{font-size:30px}.controls{grid-column:1/-1}.help{grid-column:1/-1;margin:0;display:flex;justify-content:center;gap:18px}.board-wrap{padding:7px}header{margin-bottom:13px}}
@media(max-width:420px){body{padding:11px}.side{gap:8px}.card{padding:12px}.banner{font-size:10px;padding:9px 11px}.help{gap:10px;font-size:10px}}
</style>
</head>
<body>
<main class="app">
<header>
<div class="brand">
<div class="brand-icon">蛇</div>
<div><h1>Snake</h1><div class="subtitle">The classic, reimagined</div></div>
</div>
<div class="status"><span class="dot"></span><span id="mode">Demo running</span></div>
</header>
<div class="layout">
<section class="board-wrap" aria-label="Snake game board">
<canvas id="game" aria-label="Snake game canvas"></canvas>
<div class="banner" id="banner"><b>DEMO MODE</b> · Click or press a key to start</div>
</section>
<aside class="side">
<div class="card">
<div class="label">Current score</div>
<div class="score"><span id="score">0</span> <small>pts</small></div>
<div class="food-key"><span class="food-icon"></span>Every apple is worth 10</div>
</div>
<div class="card">
<div class="label">Best this session</div>
<div class="score best" id="best">0</div>
<div class="label" style="margin-top:7px">points</div>
</div>
<div class="card controls">
<div class="label">How to play</div>
<div class="key-row"><kbd>W</kbd><kbd>A</kbd><kbd>S</kbd><kbd>D</kbd><span style="color:#71808d;font-size:11px;margin:0 3px">or</span><kbd>↑</kbd><kbd>←</kbd><kbd>↓</kbd><kbd>→</kbd></div>
<div class="control-note">Eat apples, grow longer, and don't hit the walls or yourself.</div>
</div>
<div class="help"><span><strong>P</strong> Pause</span><span><strong>Space / Enter</strong> Restart</span></div>
</aside>
</div>
</main>
<script>
(() => {
const canvas=document.getElementById('game'), ctx=canvas.getContext('2d');
const N=26, dirs={ArrowUp:[0,-1],w:[0,-1],ArrowDown:[0,1],s:[0,1],ArrowLeft:[-1,0],a:[-1,0],ArrowRight:[1,0],d:[1,0]};
let snake,dir,food,score=0,best=0,mode='demo',paused=false,dead=false,queue=[],last=0,acc=0,stepMs=115,particles=[];
const banner=document.getElementById('banner'), scoreEl=document.getElementById('score'), bestEl=document.getElementById('best'), modeEl=document.getElementById('mode');
function resize(){const r=canvas.getBoundingClientRect(),dpr=Math.min(devicePixelRatio||1,2);canvas.width=Math.round(r.width*dpr);canvas.height=Math.round(r.height*dpr);ctx.setTransform(dpr,0,0,dpr,0,0)}
new ResizeObserver(resize).observe(canvas); resize();
function reset(demo=false){
score=0;scoreEl.textContent='0';snake=[{x:7,y:13},{x:6,y:13},{x:5,y:13},{x:4,y:13}];dir={x:1,y:0};queue=[];dead=false;paused=false;mode=demo?'demo':'playing';stepMs=demo?105:115;particles=[];spawnFood();
modeEl.textContent=demo?'Demo running':'Playing';setBanner(demo?'<b>DEMO MODE</b> · Click or press a key to start':'<b>GOOD LUCK</b> · P to pause');
}
function setBanner(html,cls=''){banner.innerHTML=html;banner.className='banner '+cls;banner.style.display='block'}
function spawnFood(){
let p; do{p={x:Math.floor(Math.random()*N),y:Math.floor(Math.random()*N)}}while(snake.some(s=>s.x===p.x&&s.y===p.y)); food=p;
}
function begin(){reset(false)}
function key(e){
const k=e.key, lower=k.toLowerCase();
if([...Object.keys(dirs),' ','Enter','p'].includes(k)||lower==='p')e.preventDefault();
if(mode==='demo'){begin();if(dirs[k]||dirs[lower])enqueue(dirs[k]||dirs[lower]);return}
if(k===' '||k==='Enter'){if(dead){begin();return}if(paused){paused=false;modeEl.textContent='Playing';setBanner('<b>GOOD LUCK</b> · P to pause');return}}
if(lower==='p'&&!dead){paused=!paused;modeEl.textContent=paused?'Paused':'Playing';setBanner(paused?'<b>PAUSED</b> · Press P to resume':'<b>GOOD LUCK</b> · P to pause');return}
const d=dirs[k]||dirs[lower];if(d&&!dead&&!paused)enqueue(d);
}
function enqueue(d){
const from=queue.length?queue[queue.length-1]:dir;
if(d.x!==-from.x||d.y!==-from.y){if(queue.length<2)queue.push(d)}
}
document.addEventListener('keydown',key);canvas.addEventListener('pointerdown',()=>{if(mode==='demo')begin()});
function ai(){
// Find a short safe route to the apple, treating the body as obstacles.
const start=snake[0], blocked=new Set(snake.slice(0,-1).map(p=>p.x+','+p.y)), q=[[start.x,start.y,[]]], seen=new Set([start.x+','+start.y]);
while(q.length){
const [x,y,path]=q.shift();
if(x===food.x&&y===food.y&&path.length)return path[0];
for(const [dx,dy] of [[1,0],[0,1],[-1,0],[0,-1]]){
const nx=x+dx,ny=y+dy,key=nx+','+ny;
if(nx<0||ny<0||nx>=N||ny>=N||blocked.has(key)||seen.has(key))continue;
seen.add(key);q.push([nx,ny,path.concat([{x:dx,y:dy}])]);
}
}
for(const d of [{x:dir.y,y:-dir.x},{x:-dir.y,y:dir.x},dir]){
const x=start.x+d.x,y=start.y+d.y;
if(x>=0&&y>=0&&x<N&&y<N&&!snake.slice(0,-1).some(p=>p.x===x&&p.y===y))return d;
}
return dir;
}
function burst(x,y){for(let i=0;i<14;i++){const a=Math.random()*Math.PI*2,s=1+Math.random()*2.6;particles.push({x:x+.5,y:y+.5,vx:Math.cos(a)*s,vy:Math.sin(a)*s,life:1})}}
function tick(){
if(dead||paused)return;
if(mode==='demo'){queue=[];dir=ai()}else if(queue.length)dir=queue.shift();
const h={x:snake[0].x+dir.x,y:snake[0].y+dir.y},eating=h.x===food.x&&h.y===food.y;
if(h.x<0||h.y<0||h.x>=N||h.y>=N||snake.slice(0,eating?snake.length:snake.length-1).some(p=>p.x===h.x&&p.y===h.y)){
dead=true;modeEl.textContent='Game over';setBanner('<b>GAME OVER</b> · Score '+score+' · Press Space or Enter to restart','over');return;
}
snake.unshift(h);if(eating){score+=10;scoreEl.textContent=score;if(score>best){best=score;bestEl.textContent=best}burst(food.x,food.y);spawnFood();if(mode==='playing')stepMs=Math.max(72,stepMs-1)}else snake.pop();
}
function draw(){
const w=canvas.clientWidth,cell=w/N;ctx.clearRect(0,0,w,w);
ctx.fillStyle='#0b1216';ctx.fillRect(0,0,w,w);
ctx.strokeStyle='rgba(167,205,169,.055)';ctx.lineWidth=1;
for(let i=0;i<=N;i++){const p=i*cell;ctx.beginPath();ctx.moveTo(p,0);ctx.lineTo(p,w);ctx.stroke();ctx.beginPath();ctx.moveTo(0,p);ctx.lineTo(w,p);ctx.stroke()}
const t=performance.now()/1000;
const fx=(food.x+.5)*cell,fy=(food.y+.5)*cell,glow=cell*(.29+.035*Math.sin(t*5));
const grd=ctx.createRadialGradient(fx,fy,1,fx,fy,cell*.75);grd.addColorStop(0,'#ff857b65');grd.addColorStop(1,'#ff635000');ctx.fillStyle=grd;ctx.beginPath();ctx.arc(fx,fy,cell*.75,0,7);ctx.fill();
ctx.fillStyle='#ff716c';ctx.beginPath();ctx.arc(fx,fy,glow,0,7);ctx.fill();ctx.fillStyle='#ffc0a4';ctx.beginPath();ctx.arc(fx-cell*.08,fy-cell*.09,cell*.085,0,7);ctx.fill();
particles=particles.filter(p=>p.life>0);for(const p of particles){p.x+=p.vx*.015;p.y+=p.vy*.015;p.life-=.035;ctx.globalAlpha=p.life;ctx.fillStyle='#c2ff91';ctx.beginPath();ctx.arc(p.x*cell,p.y*cell,cell*.07,0,7);ctx.fill()}ctx.globalAlpha=1;
snake.forEach((s,i)=>{
const pad=cell*.09,x=s.x*cell+pad,y=s.y*cell+pad,size=cell-pad*2;
ctx.fillStyle=i===0?'#b5ff82':`hsl(${103-i*1.35} 68% ${59-i*.27}%)`;
ctx.beginPath();ctx.roundRect(x,y,size,size,cell*.28);ctx.fill();
if(i===0){
const forward=dir,side={x:-dir.y,y:dir.x};
for(const sign of [-1,1]){
const ex=(s.x+.5+forward.x*.21+side.x*.19*sign)*cell,ey=(s.y+.5+forward.y*.21+side.y*.19*sign)*cell;
ctx.fillStyle='#17221a';ctx.beginPath();ctx.arc(ex,ey,cell*.075,0,7);ctx.fill();
ctx.fillStyle='#f4ffe9';ctx.beginPath();ctx.arc(ex-forward.x*cell*.02,ey-forward.y*cell*.02,cell*.025,0,7);ctx.fill();
}
}
});
}
function frame(now){const dt=Math.min(now-last,60);last=now;if(!paused&&!dead){acc+=dt;if(acc>=stepMs){tick();acc%=stepMs}}draw();requestAnimationFrame(frame)}
reset(true);requestAnimationFrame(frame);
})();
</script>
</body>
</html>Reasoning trace (211 tokens)
**Designing game demo features** I need to create a game demo that autoplays behind a message. The canvas will be centered with a 26x26 grid, and attractive controls should maintain fast legal presses. The AI demo will start autoplaying when a call-to-action is clicked, and on the first click, it may reset the game. I want the demo overlay message visible for at least three seconds. There are various considerations, like responsive design and ensuring smooth gameplay, with clear instructions for users.