Snake · qwen3.8-27b
Build a playable Snake game on a canvas with arrow-key controls, a growing tail, food, score, and a game-over and restart state.
transcript · 6 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.
thinking
Create a single index.html that includes a snake game.
/tmp/ws/index.html (7744 bytes)Successfully wrote 7744 bytes to /tmp/ws/index.html
thinking
Wait — in the startIfNeeded using { once: false }, it'll keep listening forever, but that's not a problem. Actually, if state is "over" then reset() gets executed first, so... keydown handler: if state === "over" then reset sets state to "playing", but the rAF loop doesn't get started — the startIfNeeded handler fires too (added after reset? Handler order: reset's handler is added first, and it does the reset. Next, startIfNeeded sees state as "playing" and starts the loop). OK, this works.
But there's a bug: in the keydown handler, the check `e.key.toLowerCase()` for space — space's toLowerCase is " ", no problem.
Also, "ready" state: the initial paint is done, and on the first keypress it starts. But the food's pulse animation doesn't animate in the ready state (no rAF). No problem.
Let me check whether the file exists.
{"command":"ls -la /tmp/ws/index.html && node -e \"\nconst html = require('fs').readFileSync('/tmp/ws/index.html','utf8');\n// sanity: extra-rw-r--r--. 1 node node 7744 Aug 15 13:51 /tmp/ws/index.html JS syntax OK, length 5506
thinking
One issue: when restarting from game over via Enter, state becomes "playing", and then startIfNeeded starts the loop. But the keydown handler order — the reset handler is registered before startIfNeeded. Both fire on the same event, and the earlier one runs first. Good. But wait: in the case of state "over" with an arrow key, reset does not occur (only enter/space) — correct. Also, the "startIfNeeded" handler: after the game ends and restarts, state becomes "playing", and the loop resumes. Good. Done.
Done. `index.html` is written to `/tmp/ws/index.html` — fully self-contained (inline CSS + JS, zero network requests), and the embedded script passes a syntax check. Features: - **Canvas rendering** (480×480, 24×24 grid) with a subtle grid, pulsing food, and a gradient-shaded snake with eyes on the head - **Controls**: arrow keys or WASD, with reverse-direction prevention; game starts on first keypress - **Growing tail**: the snake grows by one segment per food eaten (tail not popped on that tick) - **Score & best score** in the HUD; speed ramps up as you eat - **Collision**: walls and self → **game-over overlay** showing final score - **Restart**: Enter/Space, or the "Play Again" button
TAKE IT TO CODE
A single self-contained HTML file — copy it and open in any browser, or reuse the prompt with your own pi-agent run.
RUN
EVALUATION
Snake renders with score/food but Enter/Space instantly triggers Game Over, and arrows/WASD don't restart or move the snake.
Vision grade · anthropic/claude-sonnet-5
MEASUREMENTS
Raw readings from the capture, not a verdict — the grade above is the only judgement. Percentages are how much of the screen changed; the measure under-reports sparse motion on a dark background.