Train snakeOne-line
Gemini 3.1 Flash Lite
by GoogleReasoning1 console error
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 6.8 s
- Cost
- $0.0039
- Output tokens
- 2,516
- Spent thinking
- 457 tokens
- Speed
- 447.4 tok/s
- Console errors
- 1
- First token after
- 1.2 s
- First visible text after
- 2.1 s
- Prompt tokens
- 367
- Code size
- 6.3 KB
- Finish reason
- stop
- Served by
- Model id
google/gemini-3.1-flash-lite- Reasoning sent
{"effort":"medium"}- Max output
- 65,536 tokens
- Generated
- Nov 12, 2026
Console errors
Caught in the first 3 seconds after load, in a sandboxed iframe like the one above.
Cannot read properties of undefined (reading 'x')
What it was asked
The prompt
“make me a snake game where the snake is a little train with a locomotive and colorful wagons, picking up passengers waiting on the platform”
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 · 221 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Train Snake</title>
<style>
body {
margin: 0;
background: #2c3e50;
color: white;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
}
#game-container {
position: relative;
box-shadow: 0 0 20px rgba(0,0,0,0.5);
background: #34495e;
border: 4px solid #7f8c8d;
border-radius: 8px;
}
canvas {
display: block;
max-width: 100vw;
max-height: 80vh;
cursor: pointer;
}
#ui {
text-align: center;
padding: 10px;
}
#msg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0,0,0,0.7);
padding: 20px;
border-radius: 10px;
text-align: center;
pointer-events: none;
}
</style>
</head>
<body>
<div id="ui">
<h1>Train Express</h1>
<p>Score: <span id="score">0</span></p>
</div>
<div id="game-container">
<canvas id="gameCanvas" width="600" height="400"></canvas>
<div id="msg">
<h2>Train Express</h2>
<p>Click or press any key to start</p>
</div>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreEl = document.getElementById('score');
const msgEl = document.getElementById('msg');
const gridSize = 20;
const cols = canvas.width / gridSize;
const rows = canvas.height / gridSize;
let snake = [{x: 10, y: 10}];
let direction = {x: 1, y: 0};
let nextDirection = {x: 1, y: 0};
let passengers = [];
let score = 0;
let playing = false;
let attractMode = true;
let speed = 100;
let lastTime = 0;
const wagonColors = ['#e74c3c', '#f1c40f', '#3498db', '#2ecc71', '#9b59b6'];
function initGame() {
snake = [{x: 5, y: 5}];
direction = {x: 1, y: 0};
nextDirection = {x: 1, y: 0};
score = 0;
scoreEl.innerText = score;
spawnPassenger();
playing = true;
attractMode = false;
msgEl.style.display = 'none';
}
function spawnPassenger() {
let pos;
while(true) {
pos = {
x: Math.floor(Math.random() * cols),
y: Math.floor(Math.random() * rows)
};
if (!snake.find(s => s.x === pos.x && s.y === pos.y)) break;
}
passengers = [pos];
}
function update() {
if (!playing && !attractMode) return;
direction = nextDirection;
const head = { x: snake[0].x + direction.x, y: snake[0].y + direction.y };
// Wrap around
if (head.x < 0) head.x = cols - 1;
if (head.x >= cols) head.x = 0;
if (head.y < 0) head.y = rows - 1;
if (head.y >= rows) head.y = 0;
// Collision
if (!attractMode && snake.slice(1).find(s => s.x === head.x && s.y === head.y)) {
gameOver();
return;
}
snake.unshift(head);
if (passengers.some(p => p.x === head.x && p.y === head.y)) {
score += 10;
scoreEl.innerText = score;
spawnPassenger();
} else {
snake.pop();
}
}
function draw() {
ctx.fillStyle = '#34495e';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Grid lines
ctx.strokeStyle = '#2c3e50';
for(let i=0; i<cols; i++) ctx.strokeRect(i*gridSize, 0, gridSize, rows*gridSize);
for(let i=0; i<rows; i++) ctx.strokeRect(0, i*gridSize, cols*gridSize, gridSize);
// Passengers
passengers.forEach(p => {
ctx.fillStyle = '#ecf0f1';
ctx.beginPath();
ctx.arc(p.x * gridSize + gridSize/2, p.y * gridSize + gridSize/2, gridSize/4, 0, Math.PI*2);
ctx.fill();
});
// Snake (Train)
snake.forEach((s, i) => {
ctx.fillStyle = i === 0 ? '#2c3e50' : wagonColors[i % wagonColors.length];
ctx.fillRect(s.x * gridSize + 2, s.y * gridSize + 2, gridSize - 4, gridSize - 4);
// Detail
if(i === 0) {
ctx.fillStyle = 'white';
ctx.fillRect(s.x*gridSize+4, s.y*gridSize+4, 4, 4);
}
});
}
function gameOver() {
playing = false;
attractMode = true;
msgEl.style.display = 'block';
msgEl.querySelector('p').innerText = "Game Over! Click to restart.";
}
function aiMove() {
const head = snake[0];
const target = passengers[0];
const possible = [
{x: 1, y: 0}, {x: -1, y: 0}, {x: 0, y: 1}, {x: 0, y: -1}
];
let bestDir = direction;
let minDist = Infinity;
possible.forEach(d => {
const next = {x: head.x + d.x, y: head.y + d.y};
const dist = Math.abs(next.x - target.x) + Math.abs(next.y - target.y);
if (dist < minDist && (d.x !== -direction.x || d.y !== -direction.y)) {
minDist = dist;
bestDir = d;
}
});
nextDirection = bestDir;
}
function loop(time) {
if (time - lastTime > speed) {
if (attractMode) aiMove();
update();
draw();
lastTime = time;
}
requestAnimationFrame(loop);
}
window.addEventListener('keydown', e => {
if (!playing) initGame();
const dirs = {ArrowUp: {x:0,y:-1}, ArrowDown: {x:0,y:1}, ArrowLeft: {x:-1,y:0}, ArrowRight: {x:1,y:0}};
if (dirs[e.key]) {
const d = dirs[e.key];
if (d.x !== -direction.x || d.y !== -direction.y) nextDirection = d;
}
});
canvas.addEventListener('click', () => { if (!playing) initGame(); });
requestAnimationFrame(loop);
</script>
</body>
</html>Reasoning trace (457 tokens)
**Developing Train Game** I'm focused on implementing the core snake-like mechanics for the train. The plan is to use a locomotive and colorful wagons, picking up passengers instead of traditional food items. I'm also considering how to best represent the train visually and create platforms for passengers to board. **Refining Snake Logic** I'm iterating on the train's movement mechanics, utilizing an array of segments to represent the locomotive and its wagons. Currently exploring the best approach for random passenger placement and prioritizing movement logic, aiming for a simple greedy algorithm to guide the train.