Train snakeOne-line
Qwen3 Coder Next
by Qwenreasoning default1 console error
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 46.3 s
- Cost
- $0.0037
- Output tokens
- 4,570
- Spent thinking
- 0 tokens
- Speed
- 99.8 tok/s
- Console errors
- 1
- First token after
- 517 ms
- First visible text after
- 517 ms
- Prompt tokens
- 368
- Code size
- 19.6 KB
- Finish reason
- stop
- Served by
- Parasail
- Model id
qwen/qwen3-coder-next- Reasoning sent
model default- Max output
- 235,929 tokens
- Generated
- Nov 13, 2026
Console errors
Caught in the first 3 seconds after load, in a sandboxed iframe like the one above.
Identifier 'game' has already been declared
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 · 559 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 Adventure</title>
<style>
:root {
--bg-color: #2c3e50;
--game-bg: #a3d9a5;
--text-color: #ecf0f1;
--accent-color: #e74c3c;
}
body {
margin: 0;
padding: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
overflow: hidden;
}
h1 {
margin: 10px 0;
font-size: 2.5rem;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
#game-container {
position: relative;
box-shadow: 0 10px 20px rgba(0,0,0,0.5);
border: 4px solid #555;
border-radius: 8px;
background-color: var(--game-bg);
}
canvas {
display: block;
background-color: var(--game-bg);
}
#ui-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.7);
z-index: 10;
transition: opacity 0.3s;
}
.hidden {
opacity: 0;
pointer-events: none;
}
#stats {
display: flex;
gap: 20px;
margin-bottom: 10px;
font-size: 1.2rem;
font-weight: bold;
}
.stat-box {
background: rgba(0,0,0,0.3);
padding: 8px 16px;
border-radius: 20px;
}
#start-btn, #restart-btn {
background-color: #f1c40f;
color: #2c3e50;
border: none;
padding: 15px 40px;
font-size: 1.5rem;
font-weight: bold;
border-radius: 50px;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
box-shadow: 0 4px 0 #c0392b;
}
#start-btn:hover, #restart-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 0 #c0392b;
}
#start-btn:active, #restart-btn:active {
transform: translateY(2px);
box-shadow: 0 0 0 #c0392b;
}
#instructions {
margin-top: 20px;
font-size: 1rem;
color: #bdc3c7;
text-align: center;
line-height: 1.5;
}
.key {
display: inline-block;
background: #ecf0f1;
color: #2c3e50;
padding: 2px 6px;
border-radius: 4px;
font-family: monospace;
font-weight: bold;
margin: 0 2px;
}
#passenger-info {
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
background: rgba(0,0,0,0.5);
padding: 5px 15px;
border-radius: 15px;
font-size: 0.9rem;
pointer-events: none;
}
</style>
</head>
<body>
<h1>🚂 Train Snake Adventure</h1>
<div id="stats">
<div class="stat-box">Score: <span id="score">0</span></div>
<div class="stat-box">Passengers Picked Up: <span id="passengers">0</span></div>
</div>
<div id="game-container">
<canvas id="gameCanvas" width="600" height="600"></canvas>
<div id="ui-layer">
<h2 id="game-title" style="color: #f1c40f; font-size: 3rem; margin-bottom: 20px;">Train Snake</h2>
<p id="game-message" style="margin-bottom: 30px; font-size: 1.2rem;">Collect all passengers to reach the next station!</p>
<button id="start-btn">Start Engine</button>
<div id="instructions">
<p>Use <span class="key">↑</span> <span class="key">↓</span> <span class="key">←</span> <span class="key">→</span> to steer the train.</p>
<p>Eat the red passengers to grow your train!</p>
</div>
</div>
<div id="passenger-info">Next Station: <span id="station-dist">?</span> passengers away</div>
</div>
<script>
/**
* Game Constants & Setup
*/
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const uiLayer = document.getElementById('ui-layer');
const startBtn = document.getElementById('start-btn');
const scoreEl = document.getElementById('score');
const passengersEl = document.getElementById('passengers');
const stationDistEl = document.getElementById('station-dist');
const gameMessage = document.getElementById('game-message');
const GRID_SIZE = 20;
const TILE_COUNT = canvas.width / GRID_SIZE;
// Colors for wagons
const WAGON_COLORS = ['#e74c3c', '#3498db', '#9b59b6', '#f1c40f', '#e67e22', '#1abc9c'];
let game;
let animationId;
let isGameRunning = false;
/**
* Game Logic Class
*/
class TrainGame {
constructor() {
this.reset();
this.speed = 100; // ms per frame
this.lastTime = 0;
this.score = 0;
this.passengersCollected = 0;
this.passengersNeeded = 5; // Starts small
this.distanceToNextStation = this.passengersNeeded;
}
reset() {
// Snake (Train) starts in the middle
this.snake = [
{ x: 10, y: 10 }, // Head (Locomotive)
{ x: 10, y: 11 }, // Wagons
{ x: 10, y: 12 },
{ x: 10, y: 13 }
];
this.velocity = { x: 0, y: -1 }; // Moving Up initially
this.nextVelocity = { x: 0, y: -1 };
// Generate first passenger
this.spawnPassenger();
this.growing = false;
this.gameOver = false;
this.passengersCollected = 0;
this.score = 0;
this.passengersNeeded = 5;
this.distanceToNextStation = this.passengersNeeded;
this.updateUI();
}
spawnPassenger() {
let validPosition = false;
while (!validPosition) {
this.passenger = {
x: Math.floor(Math.random() * TILE_COUNT),
y: Math.floor(Math.random() * TILE_COUNT),
color: `hsl(${Math.random() * 360}, 80%, 60%)`
};
// Make sure passenger doesn't spawn on snake
validPosition = true;
for (let segment of this.snake) {
if (segment.x === this.passenger.x && segment.y === this.passenger.y) {
validPosition = false;
break;
}
}
}
}
update() {
if (this.gameOver) return;
// Update velocity
this.velocity = { ...this.nextVelocity };
// Calculate new head position
const head = {
x: this.snake[0].x + this.velocity.x,
y: this.snake[0].y + this.velocity.y
};
// Wall Collision
if (head.x < 0 || head.x >= TILE_COUNT || head.y < 0 || head.y >= TILE_COUNT) {
this.handleGameOver();
return;
}
// Self Collision
for (let segment of this.snake) {
if (head.x === segment.x && head.y === segment.y) {
this.handleGameOver();
return;
}
}
this.snake.unshift(head);
// Check for Passenger (Food)
if (head.x === this.passenger.x && head.y === this.passenger.y) {
this.collectPassenger();
} else {
this.snake.pop();
}
}
collectPassenger() {
this.score += 10;
this.passengersCollected++;
this.passengersNeeded--;
this.distanceToNextStation = this.passengersNeeded;
// Visual flair: passenger is "eaten"
this.growing = true;
if (this.passengersNeeded <= 0) {
this.handleStationArrival();
} else {
this.spawnPassenger();
}
this.updateUI();
}
handleStationArrival() {
this.gameOver = true;
this.speed = Math.max(50, this.speed - 5); // Game gets faster each station
gameMessage.innerHTML = `Station Arrived!<br>You collected ${this.passengersCollected} passengers.<br>Current Score: ${this.score}`;
startBtn.textContent = "Continue to Next Station";
uiLayer.classList.remove('hidden');
}
handleGameOver() {
this.gameOver = true;
gameMessage.innerHTML = `Train Derailment!<br>Final Score: ${this.score}<br>Passengers Collected: ${this.passengersCollected}`;
startBtn.textContent = "Try Again";
uiLayer.classList.remove('hidden');
}
updateUI() {
scoreEl.textContent = this.score;
passengersEl.textContent = this.passengersCollected;
stationDistEl.textContent = this.passengersNeeded;
}
draw() {
// Clear Screen
ctx.fillStyle = '#a3d9a5'; // Grass color
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw Grid (Subtle)
ctx.strokeStyle = 'rgba(0,0,0,0.05)';
ctx.lineWidth = 1;
for (let i = 0; i <= TILE_COUNT; i++) {
ctx.beginPath();
ctx.moveTo(i * GRID_SIZE, 0);
ctx.lineTo(i * GRID_SIZE, canvas.height);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0, i * GRID_SIZE);
ctx.lineTo(canvas.width, i * GRID_SIZE);
ctx.stroke();
}
// Draw Passenger (Platform / Item)
this.drawPassenger(this.passenger.x, this.passenger.y, this.passenger.color);
// Draw Snake (Train)
this.snake.forEach((segment, index) => {
this.drawTrainSegment(segment, index);
});
}
drawPassenger(x, y, color) {
const pixelX = x * GRID_SIZE;
const pixelY = y * GRID_SIZE;
const center = GRID_SIZE / 2;
// Platform base
ctx.fillStyle = '#7f8c8d';
ctx.fillRect(pixelX + 4, pixelY + 4, GRID_SIZE - 8, GRID_SIZE - 8);
// Passenger figure (Simple Circle/Person)
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(pixelX + center, pixelY + center, 6, 0, Math.PI * 2);
ctx.fill();
// Passenger head (darker)
ctx.fillStyle = 'rgba(0,0,0,0.2)';
ctx.beginPath();
ctx.arc(pixelX + center, pixelY + center - 2, 3, 0, Math.PI * 2);
ctx.fill();
// "Wait" text if close (optional visual flair)
if (this.passengersNeeded === 1) {
ctx.fillStyle = '#c0392b';
ctx.font = '10px Arial';
ctx.textAlign = 'center';
ctx.fillText("Hurry!", pixelX + center, pixelY - 2);
}
}
drawTrainSegment(segment, index) {
const pixelX = segment.x * GRID_SIZE;
const pixelY = segment.y * GRID_SIZE;
const center = GRID_SIZE / 2;
if (index === 0) {
// --- LOCOMOTIVE (HEAD) ---
// Main Body
ctx.fillStyle = '#e74c3c'; // Red locomotive
ctx.fillRect(pixelX + 2, pixelY + 2, GRID_SIZE - 4, GRID_SIZE - 4);
// Windows
ctx.fillStyle = '#3498db'; // Blue windows
if (this.velocity.y === -1) { // Up
ctx.fillRect(pixelX + 4, pixelY + 6, 6, 6);
ctx.fillRect(pixelX + 10, pixelY + 6, 6, 6);
} else if (this.velocity.y === 1) { // Down
ctx.fillRect(pixelX + 4, pixelY + 10, 6, 6);
ctx.fillRect(pixelX + 10, pixelY + 10, 6, 6);
} else if (this.velocity.x === -1) { // Left
ctx.fillRect(pixelX + 6, pixelY + 4, 6, 6);
ctx.fillRect(pixelX + 6, pixelY + 10, 6, 6);
} else { // Right
ctx.fillRect(pixelX + 10, pixelY + 4, 6, 6);
ctx.fillRect(pixelX + 10, pixelY + 10, 6, 6);
}
// Chimney/Top detail
ctx.fillStyle = '#2c3e50';
if (this.velocity.y === -1) {
ctx.fillRect(pixelX + 6, pixelY + 2, 8, 4);
} else if (this.velocity.y === 1) {
ctx.fillRect(pixelX + 6, pixelY + 14, 8, 4);
} else if (this.velocity.x === -1) {
ctx.fillRect(pixelX + 2, pixelY + 6, 4, 8);
} else {
ctx.fillRect(pixelX + 14, pixelY + 6, 4, 8);
}
} else {
// --- WAGONS ---
// Alternate colors for variety
const color = WAGON_COLORS[(index - 1) % WAGON_COLORS.length];
ctx.fillStyle = color;
// Draw rounded rectangle for wagon
ctx.beginPath();
ctx.roundRect(pixelX + 2, pixelY + 2, GRID_SIZE - 4, GRID_SIZE - 4, 4);
ctx.fill();
// Detail: Bolt or connection
ctx.fillStyle = 'rgba(0,0,0,0.3)';
ctx.beginPath();
ctx.arc(pixelX + center, pixelY + center, 3, 0, Math.PI * 2);
ctx.fill();
// Connection to previous car (visual line)
const prev = this.snake[index - 1];
if (prev.x !== segment.x || prev.y !== segment.y) {
ctx.strokeStyle = 'rgba(0,0,0,0.2)';
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(pixelX + center, pixelY + center);
ctx.lineTo(prev.x * GRID_SIZE + center, prev.y * GRID_SIZE + center);
ctx.stroke();
}
}
}
}
/**
* Game Loop & Controls
*/
function gameLoop(timestamp) {
if (!isGameRunning) return;
if (timestamp - game.lastTime > game.speed) {
game.update();
game.draw();
game.lastTime = timestamp;
}
if (!game.gameOver) {
animationId = requestAnimationFrame(gameLoop);
}
}
function startGame() {
if (game.gameOver && game.passengersNeeded <= 0) {
// Resuming station logic (simulated for this demo by just resetting speed slightly)
game.gameOver = false;
game.speed = 100;
// Continue with current score/passengers but spawn new food
game.spawnPassenger();
game.passengersNeeded = 5 + Math.floor(game.passengersCollected / 10); // Increase difficulty
game.distanceToNextStation = game.passengersNeeded;
game.updateUI();
} else if (game.gameOver) {
game.reset();
} else {
game.reset();
}
game.lastTime = 0;
isGameRunning = true;
uiLayer.classList.add('hidden');
requestAnimationFrame(gameLoop);
}
// Keyboard Controls
window.addEventListener('keydown', (e) => {
// Prevent default scrolling for arrow keys
if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
e.preventDefault();
}
// Only allow controls if game is running
if (!isGameRunning && !game.gameOver) return;
if (game.gameOver) return;
switch (e.key) {
case 'ArrowUp':
if (game.velocity.y === 0) game.nextVelocity = { x: 0, y: -1 };
break;
case 'ArrowDown':
if (game.velocity.y === 0) game.nextVelocity = { x: 0, y: 1 };
break;
case 'ArrowLeft':
if (game.velocity.x === 0) game.nextVelocity = { x: -1, y: 0 };
break;
case 'ArrowRight':
if (game.velocity.x === 0) game.nextVelocity = { x: 1, y: 0 };
break;
}
});
// Mouse/Touch Controls (Swipe)
let touchStartX = 0;
let touchStartY = 0;
canvas.addEventListener('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
touchStartY = e.changedTouches[0].screenY;
}, {passive: false});
canvas.addEventListener('touchend', (e) => {
if (!isGameRunning || game.gameOver) return;
const touchEndX = e.changedTouches[0].screenX;
const touchEndY = e.changedTouches[0].screenY;
const dx = touchEndX - touchStartX;
const dy = touchEndY - touchStartY;
if (Math.abs(dx) > Math.abs(dy)) {
// Horizontal
if (dx > 0 && game.velocity.x === 0) game.nextVelocity = { x: 1, y: 0 };
else if (dx < 0 && game.velocity.x === 0) game.nextVelocity = { x: -1, y: 0 };
} else {
// Vertical
if (dy > 0 && game.velocity.y === 0) game.nextVelocity = { x: 0, y: 1 };
else if (dy < 0 && game.velocity.y === 0) game.nextVelocity = { x: 0, y: -1 };
}
}, {passive: false});
// Initial Setup
const game = new TrainGame();
game.draw(); // Draw initial state
startBtn.addEventListener('click', startGame);
// Click anywhere to start if button not clicked (fallback)
uiLayer.addEventListener('click', (e) => {
if (e.target === uiLayer || e.target.id === 'game-title') {
startGame();
}
});
</script>
</body>
</html>