Snake · qwen3-coder-flash
Build a playable Snake game on a canvas with arrow-key controls, a growing tail, food, score, and a game-over and restart state.
This one-shot run produced no runnable artifact.
agent produced no index.html
The transcript below shows what the model did — read it to see why the one shot fell short.
transcript · 2 messages
Build a playable Snake game on a canvas with arrow-key controls, a growing tail, food, score, and a game-over and restart state.
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Snake Game</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #f0f0f0; font-family: Arial, sans-serif; } #game-container { text-align: center; } #game-canvas { border: 2px solid #333; background-color: #111; } #score { color: white; font-size: 24px; margin: 10px 0; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); } #game-over { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: rgba(0, 0, 0, 0.8); color: white; padding: 20px; border-radius: 10px; text-align: center; display: none; } #restart-btn { background-color: #4CAF50; border: none; color: white; padding: 10px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; border-radius: 5px; } #restart-btn:hover { background-color: #45a049; } </style> </head> <body> <div id="game-container"> <div id="score">Score: 0</div> <canvas id="game-canvas" width="400" height="400"></canvas> <div id="game-over"> <h2>Game Over!</h2> <p>Your score: <span id="final-score">0</span></p> <button id="restart-btn">Play Again</button> </div> </div> <script> // Game constants const GRID_SIZE = 20; const TILE_COUNT = 20; const INITIAL_SPEED = 150; // Game variables let canvas = document.getElementById('game-canvas'); let ctx = canvas.getContext('2d'); let scoreElement = document.getElementById('score'); let gameOverScreen = document.getElementById('game-over'); let finalScoreElement = document.getElementById('final-score'); let restartBtn = document.getElementById('restart-btn'); let snake = []; let food = {}; let direction = 'right'; let nextDirection = 'right'; let score = 0; let gameSpeed = INITIAL_SPEED; let gameRunning = false; let gameLoop; // Initialize game function initGame() { // Reset game state snake = [ {x: 5, y: 10}, {x: 4, y: 10}, {x: 3, y: 10} ]; generateFood(); direction = 'right'; nextDirection = 'right'; score = 0; gameSpeed = INITIAL_SPEED; scoreElement.textContent = `Score: ${score}`; gameOverScreen.style.display = 'none'; gameRunning = true; // Start game loop if (gameLoop) clearInterval(gameLoop); gameLoop = setInterval(update, gameSpeed); } // Generate food at random position function generateFood() { food = { x: Math.floor(Math.random() * TILE_COUNT), y: Math.floor(Math.random() * TILE_COUNT) }; // Make sure food doesn't appear on snake for (let segment of snake) { if (segment.x === food.x && segment.y === food.y) { return generateFood(); } } } // Update game state function update() { if (!gameRunning) return; // Update direction direction = nextDirection; // Calculate new head position let head = {x: snake[0].x, y: snake[0].y}; switch(direction) { case 'up': head.y--; break; case 'down': head.y++; break; case 'left': head.x--; break; case 'right': head.x++; break; } // Check collision with walls if (head.x < 0 || head.x >= TILE_COUNT || head.y < 0 || head.y >= TILE_COUNT) { gameOver(); return; } // Check collision with self for (let i = 0; i < snake.length; i++) { if (snake[i].x === head.x && snake[i].y === head.y) { gameOver(); return; } } // Add new head snake.unshift(head); // Check if food is eaten if (head.x === food.x && head.y === food.y) { // Increase score score += 10; scoreElement.textContent = `Score: ${score}`; // Increase speed slightly if (gameSpeed > 50) { gameSpeed -= 2; clearInterval(gameLoop); gameLoop = setInterval(update, gameSpeed); } // Generate new food generateFood(); } else { // Remove tail if no food eaten snake.pop(); } // Draw everything draw(); } // Draw game elements function draw() { // Clear canvas ctx.fillStyle = '#111'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw grid ctx.strokeStyle = '#222'; for (let i = 0; i < TILE_COUNT; i++) { for (let j = 0; j < TILE_COUNT; j++) { ctx.strokeRect(i * GRID_SIZE, j * GRID_SIZE, GRID_SIZE, GRID_SIZE); } } // Draw snake snake.forEach((segment, index) => { if (index === 0) { // Draw head differently ctx.fillStyle = '#4CAF50'; } else { // Draw body ctx.fillStyle = '#8BC34A'; } ctx.fillRect(segment.x * GRID_SIZE, segment.y * GRID_SIZE, GRID_SIZE, GRID_SIZE); // Add border to segments ctx.strokeStyle = '#1B5E20'; ctx.strokeRect(segment.x * GRID_SIZE, segment.y * GRID_SIZE, GRID_SIZE, GRID_SIZE); }); // Draw food ctx.fillStyle = '#FF5252'; ctx.beginPath(); ctx.arc( food.x * GRID_SIZE + GRID_SIZE/2, food.y * GRID_SIZE + GRID_SIZE/2, GRID_SIZE/2, 0, Math.PI * 2 ); ctx.fill(); } // Game over function function gameOver() { gameRunning = false; clearInterval(gameLoop); finalScoreElement.textContent = score; gameOverScreen.style.display = 'block'; } // Handle keyboard input document.addEventListener('keydown', (e) => { if (!gameRunning) return; switch(e.key) { case 'ArrowUp': if (direction !== 'down') nextDirection = 'up'; break; case 'ArrowDown': if (direction !== 'up') nextDirection = 'down'; break; case 'ArrowLeft': if (direction !== 'right') nextDirection = 'left'; break; case 'ArrowRight': if (direction !== 'left') nextDirection = 'right'; break; } }); // Restart button event restartBtn.addEventListener('click', initGame); // Start the game initGame(); </script> </body> </html> ```
TAKE IT TO CODE
This run produced no artifact — reuse the prompt with a different model or your own pi-agent run.