oneshotlm
Compare all models on this prompt →

Tetris · qwen3.8-2.4t-a95b

Build a playable Tetris on a canvas with all seven tetrominoes, rotation, line clears, increasing speed, a next-piece preview, and score.

⛨ sandboxed Open in new tab ↗
transcript · 10 messages
user

Build a playable Tetris on a canvas with all seven tetrominoes, rotation, line clears, increasing speed, a next-piece preview, and score.

assistant
thinking
Build Tetris in a single index.html. Write a fully playable game with canvas, 7 types of tetrominoes, rotation (with simple wall kicks), line clears, level-based speed-up, next piece preview, and score. Include controls: arrow keys, space for hard drop, P for pause, possibly restart too. Write the file.
write /tmp/ws/index.html (14842 bytes)
toolResult

Successfully wrote 14842 bytes to /tmp/ws/index.html

assistant
thinking
Small cleanup: drawNext has leftover `const fakeCtx = ...` code — it's harmless but sloppy, so I'll remove it. Also, clearLines returns a count, but the row deletion is… wait, that's a bug! In lockPiece, clearLines() records flashRows but doesn't delete the rows. The comment says "rows are deleted immediately for correctness," but they're actually never deleted at all! Let me verify: lockPiece calls clearLines(), adds to the score, then spawns, but the full rows are never removed. This is a bug — rows need to be deleted. Fix: after scoring, call removeRows. Flash is just cosmetic; the easiest approach is to delete the rows immediately and keep the flash overlay effect on top.

Let me fix a bug — cleared rows were never actually removed — and clean up leftover code in the preview drawing:

edit {"path":"/tmp/ws/index.html","edits":[{"oldText":" merge();\n const cleared = clearLines();\n if (!cleared) {\n spawn();\n
toolResult

Successfully replaced 2 block(s) in /tmp/ws/index.html.

assistant
thinking
Note: removeRows shifts the grid, so the flashRows coordinates become stale relative to the visual flash (the flash is drawn at the old y positions, but now those positions display the shifted blocks). That's fine — it's a white flash effect over the area. Acceptable.

Also a quick sanity check: rotateMatrix assumes a square matrix. All the shapes are square matrices (I is 4x4, the others are 3x3, O is 2x2). Good.

Run a syntax check with node.
bash {"command":"cd /tmp/ws && node -e \"\nconst html = require('fs').readFileSync('index.html','utf8');\nconst js = html.match(/<script>([\\s\\S
toolResult

JS syntax OK, file size: 14671

assistant
thinking
Also, I want to quickly verify the core logic (rotation, collision detection, clearing) in node, so I'll extract the pure functions and simulate a few lines of play.
bash {"command":"cd /tmp/ws && node -e \"\n// Simulate core logic extracted from the file\nconst COLS=10, ROWS=20;\nconst PIECES={\n I:{shape:[[0
toolResult

I rotation cycle OK: true O rotation cycle OK: true T rotation cycle OK: true S rotation cycle OK: true Z rotation cycle OK: true J rotation cycle OK: true L rotation cycle OK: true line detect OK: true row remove OK: true all checks passed

assistant
thinking
The score logic inside addScore — addScore is called after removeRows inside lockPiece, no problem. One more check: addScore uses a points array indexed by n (number of cleared lines 1–4), no problem.

Done. Let me summarize.

Done — `index.html` is in place at `/tmp/ws/index.html`, fully self-contained (no external resources), with the JS syntax-checked and the core logic (rotation cycles for all 7 pieces, collision, line detection/removal) verified. **Features:** - **All seven tetrominoes** (I, O, T, S, Z, J, L) with classic colors, using a **7-bag randomizer** for fair distribution - **Rotation** with wall-kick offsets (tries shifts of 0, ±1, ±2 so you can rotate against walls) - **Line clears** with a brief white flash effect and proper row removal - **Increasing speed**: level up every 10 lines, gravity drops from 1000 ms down to 80 ms - **Next-piece preview** panel with centered piece rendering - **Scoring**: 100/300/500/800 × level for 1–4 line clears, +1 per soft-drop cell, +2 per hard-drop cell - Extras: **ghost piece** showing where the piece will land, pause (P), game-over overlay with final score, restart via Enter or button, beveled block rendering and subtle grid lines **Controls:** ← → move, ↑ rotate, ↓ soft drop, Space hard drop, P pause, Enter start/restart.

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

modelqwen3.8-2.4t-a95b
vendorQwen
harnesspi-agent
generated2026-08-13

EVALUATION

3/5 working

Functional Tetris with falling pieces, next preview, score/level; game starts and pieces move with keyboard input.

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.

idle motion0.0%
on click0.0%
on drag0.9%
on wheel0.0%
on enter + space2.5%
on arrow keys1.5%
on w/a/s/d0.8%
frame spread13.9 / 255
console errors0
js errors none

METRICS

runtime117.7s
tokens in32k
tokens out7.0k
cached0
cost / run$0.1060