Models 44
Train snakeOne-line

Claude Haiku 4.5

by AnthropicReasoningClean
Open in new window

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

How it went

Total time
14.1 s
Cost
$0.022
Output tokens
4,357
Spent thinking
0 tokens
Speed
325.5 tok/s
Console errors
0
First token after
685 ms
First visible text after
685 ms
Prompt tokens
381
Code size
14.9 KB
Finish reason
stop
Served by
Amazon Bedrock
Model id
anthropic/claude-haiku-4.5
Reasoning sent
{"effort":"none"}
Max output
32,000 tokens
Generated
Nov 10, 2026

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 · 464 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 Game</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            font-family: 'Arial', sans-serif;
        }

        .container {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 20px;
        }

        h1 {
            color: white;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
            font-size: 28px;
        }

        .game-board {
            background: linear-gradient(to bottom, #87CEEB 0%, #E0F6FF 100%);
            border: 4px solid #333;
            border-radius: 8px;
            width: 800px;
            height: 600px;
            position: relative;
            overflow: hidden;
            box-shadow: 0 8px 16px rgba(0,0,0,0.3);
        }

        .platform {
            position: absolute;
            background: linear-gradient(to right, #8B4513, #A0522D);
            border: 2px solid #654321;
            border-radius: 4px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 20px;
        }

        .passenger {
            position: absolute;
            font-size: 24px;
            animation: bounce 1s infinite;
        }

        @keyframes bounce {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-8px); }
        }

        .locomotive {
            position: absolute;
            width: 40px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 32px;
        }

        .wagon {
            position: absolute;
            width: 32px;
            height: 32px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 28px;
            border-radius: 4px;
        }

        .stats {
            color: white;
            font-size: 18px;
            display: flex;
            gap: 30px;
            background: rgba(0,0,0,0.3);
            padding: 15px 30px;
            border-radius: 8px;
            min-width: 300px;
            justify-content: center;
        }

        .stat-item {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .start-message {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0,0,0,0.9);
            color: white;
            padding: 30px 50px;
            border-radius: 8px;
            text-align: center;
            font-size: 20px;
            z-index: 100;
            display: none;
            white-space: nowrap;
        }

        .start-message.show {
            display: block;
            animation: pulse 1s infinite;
        }

        @keyframes pulse {
            0%, 100% { transform: translate(-50%, -50%) scale(1); }
            50% { transform: translate(-50%, -50%) scale(1.05); }
        }

        .game-over {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0,0,0,0.95);
            color: white;
            padding: 30px 50px;
            border-radius: 8px;
            text-align: center;
            z-index: 101;
            display: none;
            min-width: 300px;
        }

        .game-over h2 {
            font-size: 32px;
            margin-bottom: 15px;
            color: #ff6b6b;
        }

        .game-over p {
            font-size: 18px;
            margin-bottom: 10px;
        }

        @media (max-width: 820px) {
            .game-board {
                width: 90vw;
                max-width: 800px;
                height: 60vh;
                max-height: 600px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🚂 Train Passengers 🚂</h1>
        <div class="game-board" id="gameBoard">
            <div class="start-message show" id="startMessage">Click or press a key to start</div>
            <div class="game-over" id="gameOverScreen"></div>
        </div>
        <div class="stats">
            <div class="stat-item">
                <span>🚃 Wagons:</span>
                <span id="wagonCount">0</span>
            </div>
            <div class="stat-item">
                <span>👥 Passengers:</span>
                <span id="passengerCount">0</span>
            </div>
            <div class="stat-item">
                <span>⏱️ Time:</span>
                <span id="timeCount">0s</span>
            </div>
        </div>
    </div>

    <script>
        const GRID_SIZE = 20;
        const BOARD_WIDTH = 800;
        const BOARD_HEIGHT = 600;
        const COLS = Math.floor(BOARD_WIDTH / GRID_SIZE);
        const ROWS = Math.floor(BOARD_HEIGHT / GRID_SIZE);

        let gameState = {
            running: false,
            demo: true,
            direction: { x: 1, y: 0 },
            nextDirection: { x: 1, y: 0 },
            gameOver: false,
            passengers: 0,
            startTime: 0,
            elapsedTime: 0
        };

        let train = [
            { x: 10, y: 10, type: 'locomotive' },
            { x: 9, y: 10, type: 'wagon', color: '#FF6B6B' },
            { x: 8, y: 10, type: 'wagon', color: '#4ECDC4' }
        ];

        let passengers = [];
        let platforms = [];

        const gameBoard = document.getElementById('gameBoard');
        const startMessage = document.getElementById('startMessage');
        const gameOverScreen = document.getElementById('gameOverScreen');

        function initGame() {
            train = [
                { x: 10, y: 10, type: 'locomotive' },
                { x: 9, y: 10, type: 'wagon', color: '#FF6B6B' },
                { x: 8, y: 10, type: 'wagon', color: '#4ECDC4' }
            ];
            gameState.direction = { x: 1, y: 0 };
            gameState.nextDirection = { x: 1, y: 0 };
            gameState.gameOver = false;
            gameState.passengers = 0;
            gameState.startTime = Date.now();
            gameState.elapsedTime = 0;
            passengers = [];
            platforms = [];

            generatePlatforms(8);
            generatePassengers();
        }

        function generatePlatforms(count) {
            platforms = [];
            for (let i = 0; i < count; i++) {
                let x, y;
                let valid = true;
                do {
                    x = Math.floor(Math.random() * (COLS - 4)) + 1;
                    y = Math.floor(Math.random() * (ROWS - 2)) + 1;
                    valid = !platforms.some(p => Math.hypot(p.x - x, p.y - y) < 4);
                } while (!valid);
                platforms.push({ x: x * GRID_SIZE, y: y * GRID_SIZE });
            }
        }

        function generatePassengers() {
            passengers = [];
            for (let platform of platforms) {
                const passengerEmojis = ['👨', '👩', '👦', '👧', '👨‍🦰', '👩‍🦱'];
                const count = Math.floor(Math.random() * 3) + 1;
                for (let i = 0; i < count; i++) {
                    passengers.push({
                        x: platform.x + Math.random() * 40 - 20,
                        y: platform.y - 30,
                        emoji: passengerEmojis[Math.floor(Math.random() * passengerEmojis.length)],
                        picked: false
                    });
                }
            }
        }

        function drawGame() {
            gameBoard.querySelectorAll('.platform, .passenger, .locomotive, .wagon').forEach(el => el.remove());

            // Draw platforms
            for (let platform of platforms) {
                const platformEl = document.createElement('div');
                platformEl.className = 'platform';
                platformEl.style.left = platform.x + 'px';
                platformEl.style.top = platform.y + 'px';
                platformEl.style.width = '50px';
                platformEl.style.height = '20px';
                platformEl.innerHTML = '🚏';
                gameBoard.appendChild(platformEl);
            }

            // Draw passengers
            for (let passenger of passengers) {
                if (!passenger.picked) {
                    const passengerEl = document.createElement('div');
                    passengerEl.className = 'passenger';
                    passengerEl.style.left = passenger.x + 'px';
                    passengerEl.style.top = passenger.y + 'px';
                    passengerEl.innerHTML = passenger.emoji;
                    gameBoard.appendChild(passengerEl);
                }
            }

            // Draw train
            for (let i = 0; i < train.length; i++) {
                const segment = train[i];
                const x = segment.x * GRID_SIZE;
                const y = segment.y * GRID_SIZE;

                if (segment.type === 'locomotive') {
                    const locEl = document.createElement('div');
                    locEl.className = 'locomotive';
                    locEl.style.left = x + 'px';
                    locEl.style.top = y + 'px';
                    locEl.innerHTML = '🚂';
                    gameBoard.appendChild(locEl);
                } else {
                    const wagonEl = document.createElement('div');
                    wagonEl.className = 'wagon';
                    wagonEl.style.left = x + 'px';
                    wagonEl.style.top = y + 'px';
                    wagonEl.style.backgroundColor = segment.color;
                    wagonEl.innerHTML = segment.emoji || '🚃';
                    gameBoard.appendChild(wagonEl);
                }
            }
        }

        function updateStats() {
            document.getElementById('wagonCount').textContent = train.length - 1;
            document.getElementById('passengerCount').textContent = gameState.passengers;
            gameState.elapsedTime = Math.floor((Date.now() - gameState.startTime) / 1000);
            document.getElementById('timeCount').textContent = gameState.elapsedTime + 's';
        }

        function update() {
            if (!gameState.running && gameState.demo) {
                // Demo AI
                const head = train[0];
                const dx = Math.random();
                if (dx < 0.3 && gameState.direction.y === 0) {
                    gameState.nextDirection = { x: 0, y: -1 };
                } else if (dx < 0.6 && gameState.direction.y === 0) {
                    gameState.nextDirection = { x: 0, y: 1 };
                } else if (dx < 0.8 && gameState.direction.x === 0) {
                    gameState.nextDirection = { x: 1, y: 0 };
                } else if (gameState.direction.x === 0) {
                    gameState.nextDirection = { x: -1, y: 0 };
                }
            }

            if (!gameState.running) return;

            gameState.direction = gameState.nextDirection;
            const head = train[0];
            const newHead = {
                x: (head.x + gameState.direction.x + COLS) % COLS,
                y: (head.y + gameState.direction.y + ROWS) % ROWS,
                type: 'locomotive'
            };

            // Check self collision
            if (train.some((segment, i) => i > 0 && segment.x === newHead.x && segment.y === newHead.y)) {
                endGame();
                return;
            }

            train.unshift(newHead);

            // Check passenger pickup
            let pickUp = false;
            for (let passenger of passengers) {
                if (!passenger.picked) {
                    const px = Math.floor(passenger.x / GRID_SIZE);
                    const py = Math.floor(passenger.y / GRID_SIZE);
                    if (px === newHead.x && py === newHead.y) {
                        passenger.picked = true;
                        pickUp = true;
                        gameState.passengers++;
                    }
                }
            }

            if (!pickUp && train.length > 3) {
                train.pop();
            }

            if (passengers.every(p => p.picked) && passengers.length > 0) {
                generatePassengers();
            }

            drawGame();
            updateStats();
        }

        function endGame() {
            gameState.running = false;
            gameState.demo = false;
            gameOverScreen.style.display = 'block';
            gameOverScreen.innerHTML = `
                <h2>GAME OVER!</h2>
                <p>🚃 Wagons: ${train.length - 1}</p>
                <p>👥 Passengers: ${gameState.passengers}</p>
                <p>⏱️ Time: ${gameState.elapsedTime}s</p>
                <p style="margin-top: 20px; font-size: 16px;">Click or press a key to try again</p>
            `;
        }

        function startGame() {
            if (!gameState.gameOver && gameState.running) return;
            
            gameState.demo = false;
            gameState.running = true;
            gameOverScreen.style.display = 'none';
            startMessage.classList.remove('show');
            initGame();
            drawGame();
            updateStats();
        }

        function handleKeyDown(e) {
            if (!gameState.running && !gameState.demo) {
                startGame();
                return;
            }

            if (!gameState.running) return;

            const key = e.key.toLowerCase();
            if (key === 'arrowup' || key === 'w') {
                if (gameState.direction.y === 0) gameState.nextDirection = { x: 0, y: -1 };
                e.preventDefault();
            } else if (key === 'arrowdown' || key === 's') {
                if (gameState.direction.y === 0) gameState.nextDirection = { x: 0, y: 1 };
                e.preventDefault();
            } else if (key === 'arrowleft' || key === 'a') {
                if (gameState.direction.x === 0) gameState.nextDirection = { x: -1, y: 0 };
                e.preventDefault();
            } else if (key === 'arrowright' || key === 'd') {
                if (gameState.direction.x === 0) gameState.nextDirection = { x: 1, y: 0 };
                e.preventDefault();
            }
        }

        gameBoard.addEventListener('click', () => {
            if (!gameState.running) {
                startGame();
            }
        });

        document.addEventListener('keydown', (e) => {
            if (!gameState.running && (gameState.demo || gameOverScreen.style.display === 'block')) {
                startGame();
            } else {
                handleKeyDown(e);
            }
        });

        // Initialize and start demo
        initGame();
        drawGame();
        updateStats();

        // Game loop
        setInterval(update, 150);
    </script>
</body>
</html>