Models 44
Train snakeOne-line

LFM2.5-2.6B (free)

by LiquidAIreasoning defaultClean
Open in new window

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

How it went

Total time
14.7 s
Cost
$0
Output tokens
3,953
Spent thinking
371 tokens
Speed
273.5 tok/s
Console errors
0
First token after
285 ms
First visible text after
1.5 s
Prompt tokens
378
Code size
12.0 KB
Finish reason
stop
Served by
Liquid
Model id
liquid/lfm-2.5-2.6b:free
Reasoning sent
model default
Max output
8,192 tokens
Generated
Nov 9, 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 · 435 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 {
      background: #1a1a2e;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 800px;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    .game-container {
      width: 1280px;
      max-width: 100vw;
      aspect-ratio: 16/9;
      border: 4px solid #333;
      padding: 20px;
      box-shadow: 0 0 30px rgba(0,0,0,0.5);
    }
    canvas {
      display: block;
      background: #0d1b2a;
    }
    .start-screen {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(10, 15, 30, 0.95);
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      z-index: 10;
      color: #fff;
    }
    .start-screen h1 {
      font-size: 2.5em;
      margin-bottom: 0.5em;
      text-shadow: 0 0 20px rgba(255, 200, 100, 0.5);
    }
    .start-screen p {
      font-size: 1.2em;
      margin-bottom: 2em;
      opacity: 0.9;
    }
    .controls-hint {
      margin-top: 1em;
      font-size: 0.9em;
      opacity: 0.7;
    }
    .game-over-screen {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(10, 15, 30, 0.95);
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      z-index: 10;
      color: #fff;
    }
    .game-over-screen h2 {
      font-size: 2em;
      margin-bottom: 0.5em;
      text-shadow: 0 0 20px rgba(255, 200, 100, 0.5);
    }
    .game-over-screen .final-score {
      font-size: 1.5em;
      margin-bottom: 2em;
    }
    .btn-start {
      padding: 12px 40px;
      font-size: 1.1em;
      background: #e94560;
      color: #fff;
      border: none;
      border-radius: 8px;
      cursor: pointer;
      transition: background 0.3s, transform 0.2s;
    }
    .btn-start:hover {
      background: #ff6b81;
    }
    .btn-start:active {
      transform: scale(0.98);
    }
  </style>
</head>
<body>
  <div class="game-container">
    <canvas id="gameCanvas" width="1280" height="800"></canvas>
    
    <!-- Start Screen -->
    <div class="start-screen" id="startScreen">
      <h1>🚂 Train Snake</h1>
      <p>Collect passengers at the platform to grow your train!</p>
      <p class="controls-hint">Click or press any key to start</p>
    </div>
    
    <!-- Game Over Screen -->
    <div class="game-over-screen" id="gameOverScreen">
      <h2>Game Over!</h2>
      <div class="final-score" id="finalScore">0 Passengers</div>
      <button class="btn-start" id="restartBtn">Play Again</button>
    </div>
  </div>

  <script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    
    // Game state
    let gameState = 'start'; // start, playing, gameover
    let score = 0;
    let passengers = [];
    let train = [];
    let direction = { x: 1, y: 0 }; // locomotive direction
    let wagonCount = 3;
    let wagonColors = ['#ff6b35', '#ffd93d', '#6bcb77', '#a29bfe'];
    let trainLength = 3;
    
    // Platform and track boundaries
    const TRACK_WIDTH = 120;
    const PLATFORM_HEIGHT = 80;
    const PLATFORM_Y = 650;
    const PLATFORM_X = 50;
    const TRACK_LEFT = 50;
    const TRACK_RIGHT = 950;
    
    // AI parameters
    const AI_SPEED = 0.15;
    const AI_RETRY_LIMIT = 30;
    
    // Initialize game
    function initGame() {
      gameState = 'playing';
      score = 0;
      trainLength = 3;
      wagonCount = 3;
      train = [
        { x: TRACK_LEFT + 10, y: PLATFORM_Y - 10, type: 'locomotive' },
        { x: TRACK_LEFT + 40, y: PLATFORM_Y - 10, type: 'wagon' },
        { x: TRACK_LEFT + 80, y: PLATFORM_Y - 10, type: 'wagon' }
      ];
      direction = { x: 1, y: 0 };
      passengers = [];
      spawnPassengers();
      updateUI();
    }
    
    function spawnPassengers() {
      // Spawn passengers on the platform
      for (let i = 0; i < 5; i++) {
        const angle = (i / 5) * Math.PI * 2 + Math.random() * 0.5;
        const dist = 60 + Math.random() * 40;
        passengers.push({
          x: PLATFORM_X + 20 + Math.cos(angle) * dist,
          y: PLATFORM_Y - 10,
          id: i,
          size: 20
        });
      }
    }
    
    // AI movement - simple pathfinding to avoid walls and self
    function aiMove() {
      if (gameState !== 'playing') return;
      
      // Try to move forward
      let newDir = { ...direction };
      
      // Check if moving forward would cause collision
      const nextX = direction.x * TRACK_WIDTH;
      const nextY = direction.y * TRACK_WIDTH;
      
      // Check walls
      if (nextX < TRACK_LEFT || nextX > TRACK_RIGHT) {
        // Turn around
        newDir = { x: -direction.x, y: direction.y };
      } else if (nextY < 0 || nextY > PLATFORM_Y + 20) {
        // Turn around
        newDir = { x: -direction.x, y: -direction.y };
      } else if (isSelfCollision(newDir)) {
        // Turn to avoid self
        newDir = { x: -direction.x, y: direction.y };
      } else {
        // Safe to move forward
        newDir = direction;
      }
      
      // If still can't move forward, try other directions
      if (isSelfCollision(newDir)) {
        // Try turning left or right
        if (Math.abs(direction.x) < 1) {
          newDir = { x: -direction.x, y: direction.y };
        } else {
          newDir = { x: direction.x, y: -direction.y };
        }
      }
      
      // Execute the new direction
      direction = newDir;
      
      // Move the train
      moveTrain();
    }
    
    function isSelfCollision(newDir) {
      for (let i = 0; i < train.length; i++) {
        const t = train[i];
        if (t.type === 'wagon' && t.x >= newDir.x * TRACK_WIDTH && t.x <= newDir.x * TRACK_WIDTH + TRACK_WIDTH &&
            t.y >= newDir.y * TRACK_WIDTH && t.y <= newDir.y * TRACK_WIDTH + TRACK_WIDTH) {
          return true;
        }
      }
      return false;
    }
    
    function moveTrain() {
      // Move each wagon in the train
      for (let i = train.length - 1; i >= 0; i--) {
        const t = train[i];
        if (t.type === 'wagon') {
          t.x += direction.x * TRACK_WIDTH;
        }
      }
      
      // Add new wagon at the front if we haven't reached max length
      if (train.length < wagonCount) {
        train.push({
          x: TRACK_LEFT + 10 + direction.x * TRACK_WIDTH,
          y: PLATFORM_Y - 10,
          type: 'wagon'
        });
      }
    }
    
    // Update UI
    function updateUI() {
      const scoreEl = document.getElementById('finalScore');
      if (gameState === 'gameover') {
        scoreEl.textContent = `${score} Passengers`;
      } else {
        scoreEl.textContent = `Score: ${score}`;
      }
    }
    
    // Main game loop
    function gameLoop() {
      if (gameState === 'start') {
        // Show start screen
        return;
      }
      
      if (gameState === 'playing') {
        // AI controls movement
        aiMove();
        
        // Check for collisions
        if (checkCollision()) {
          gameOver();
          return;
        }
        
        // Check for passenger collection
        collectPassengers();
        
        // Move train
        moveTrain();
        
        // Update drawing
        draw();
        
        // Cap frame rate
        requestAnimationFrame(gameLoop);
      }
    }
    
    function checkCollision() {
      // Wall collision
      if (train[0].x < TRACK_LEFT || train[0].x > TRACK_RIGHT) return true;
      if (train[0].y < 0 || train[0].y > PLATFORM_Y + 20) return true;
      
      // Self collision (except front wagon)
      for (let i = 0; i < train.length; i++) {
        if (i === 0) continue; // Skip locomotive
        const t = train[i];
        if (t.x >= train[0].x && t.x <= train[0].x + TRACK_WIDTH &&
            t.y >= train[0].y && t.y <= train[0].y + TRACK_WIDTH) {
          return true;
        }
      }
      return false;
    }
    
    function collectPassengers() {
      for (let i = passengers.length - 1; i >= 0; i--) {
        const p = passengers[i];
        // Check if passenger is on the platform
        if (p.y >= PLATFORM_Y - 10 && p.y <= PLATFORM_Y + 10) {
          // Eat the passenger
          score += 10;
          passengers.splice(i, 1);
          updateUI();
          spawnPassengers();
          return;
        }
      }
    }
    
    function gameOver() {
      gameState = 'gameover';
      document.getElementById('gameOverScreen').style.display = 'flex';
      document.getElementById('finalScore').textContent = `${score} Passengers`;
    }
    
    // Draw everything
    function draw() {
      // Clear canvas
      ctx.fillStyle = '#0d1b2a';
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      
      // Draw track
      ctx.fillStyle = '#1a3a2a';
      ctx.fillRect(TRACK_LEFT, 0, TRACK_RIGHT - TRACK_LEFT, canvas.height);
      
      // Draw platform
      ctx.fillStyle = '#2d5a3d';
      ctx.fillRect(PLATFORM_X, PLATFORM_Y, TRACK_RIGHT - PLATFORM_X, PLATFORM_HEIGHT);
      
      // Draw passengers
      for (const p of passengers) {
        ctx.fillStyle = '#ff6b35';
        ctx.beginPath();
        ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
        ctx.fill();
      }
      
      // Draw train wagons
      for (let i = 0; i < train.length; i++) {
        const t = train[i];
        if (t.type === 'locomotive') {
          // Locomotive - larger and more detailed
          ctx.fillStyle = '#c0392b';
          ctx.fillRect(t.x, t.y, TRACK_WIDTH + 40, 40);
          // Engine details
          ctx.fillStyle = '#e74c3c';
          ctx.fillRect(t.x + 10, t.y + 5, 30, 15);
          ctx.fillStyle = '#f39c12';
          ctx.beginPath();
          ctx.arc(t.x + 20, t.y + 20, 8, 0, Math.PI * 2);
          ctx.fill();
        } else {
          // Wagon - colorful
          ctx.fillStyle = wagonColors[i % wagonColors.length];
          ctx.fillRect(t.x, t.y, TRACK_WIDTH + 40, 30);
          // Wagon details
          ctx.fillStyle = '#fff';
          ctx.fillRect(t.x + 5, t.y + 5, TRACK_WIDTH + 30, 5);
          ctx.fillRect(t.x + 5, t.y + 25, TRACK_WIDTH + 30, 5);
          // Top line
          ctx.fillStyle = '#fff';
          ctx.fillRect(t.x, t.y, TRACK_WIDTH + 40, 2);
        }
      }
      
      // Draw direction indicator
      if (gameState === 'playing') {
        ctx.fillStyle = '#fff';
        ctx.beginPath();
        ctx.arc(TRACK_LEFT + 30, PLATFORM_Y - 30, 15, 0, Math.PI * 2);
        ctx.fill();
        ctx.fillStyle = '#e94560';
        ctx.beginPath();
        ctx.arc(TRACK_LEFT + 30, PLATFORM_Y - 30, 10, 0, Math.PI * 2);
        ctx.fill();
      }
    }
    
    // Start the game loop
    function startGame() {
      initGame();
      gameState = 'playing';
      requestAnimationFrame(gameLoop);
    }
    
    // Restart game
    function restartGame() {
      initGame();
      gameState = 'playing';
      requestAnimationFrame(gameLoop);
    }
    
    // Event listeners
    document.getElementById('startScreen').addEventListener('click', startGame);
    document.getElementById('restartBtn').addEventListener('click', restartGame);
    
    // Keyboard controls
    document.addEventListener('keydown', (e) => {
      if (gameState === 'start') {
        startGame();
        return;
      }
      
      // Only allow direction changes if not moving too fast
      if (e.key === 'ArrowUp' || e.key === 'w' || e.key === 'W') {
        if (direction.y === 0) direction = { x: 0, y: -1 };
      } else if (e.key === 'ArrowDown' || e.key === 's' || e.key === 'S') {
        if (direction.y === 0) direction = { x: 0, y: 1 };
      } else if (e.key === 'ArrowLeft' || e.key === 'a' || e.key === 'A') {
        if (direction.x === 0) direction = { x: -1, y: 0 };
      } else if (e.key === 'ArrowRight' || e.key === 'd' || e.key === 'D') {
        if (direction.x === 0) direction = { x: 1, y: 0 };
      }
    });
    
    // Initialize
    initGame();
  </script>
</body>
</html>
Reasoning trace (371 tokens)
The user wants a Snake game where the snake is a little train with a locomotive and colorful wagons, picking up passengers waiting on the platform. The game should have:
1. A train-shaped snake (locomotive + colorful wagons)
2. Passengers waiting on the platform
3. Self-playing demo mode (AI plays)
4. "Click or press a key to start" message initially
5. Visible immediately on first paint
6. Works in 1280×800 viewport, adapts to smaller screens
7. No external files, images, fonts, or network requests (except allowed CDN)
8. No alert(), confirm(), prompt(), or window.open()

Let me create a complete HTML file with all the necessary code. I'll use:
- Canvas for the game rendering
- CSS for styling
- JavaScript for game logic
- A simple AI for self-play

The train should have:
- A locomotive (front)
- Colorful wagons (body)
- Passengers that can be picked up
- A platform where passengers wait

Let me design this carefully:

1. Canvas setup (1280x800)
2. Train components:
   - Locomotive (red/blue)
   - Wagons (different colors: yellow, green, purple, etc.)
3. Platform at the bottom
4. Passengers that spawn on the platform
5. Game logic: movement, eating passengers, growing, collision detection
6. AI: simple pathfinding or random movement that avoids walls and itself
7. Start screen with "Click or press a key to start"

I'll make sure everything is self-contained in one HTML file with inline CSS and JS.

Let me write the code: