Models 44
Train snakeOne-line

Qwen3 Coder Next

by Qwenreasoning default1 console error
Open in new window

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>