Build a playable Tetris as a single React component. Tetris is the falling-block puzzle: tetrominoes (four-cell shapes) drop down a grid on a timer, you slide and rotate them as they fall, and completing a horizontal row clears it for points. It's a compact game that leans hard on three things React developers reach for constantly — a timer loop, keyboard input, and derived rendering — and it exposes the classic stale-closure trap when the loop reads state it didn't capture.
The starter App.tsx renders the board in its resting state — an empty 16-row by 10-column grid with the first piece resting at the top, score 0, and a Start button — with no logic. The piece definitions and an empty-board builder are already there. Make it playable:
board (16x10 of 0 or a color index 1..7), the active piece (four cells + a color), plus score, running, and over in useState.setInterval(step, 600). Each step tries to move the piece down one row; if it can't, lock it into the board, clear any full rows, and spawn the next piece.window keydown listener maps ArrowLeft/ArrowRight to a shift, ArrowDown to a soft-drop, and ArrowUp to a 90-degree rotation.ArrowLeft/ArrowRight slide it, ArrowUp rotates it, ArrowDown drops it faster.board only changes when a piece locks; the active piece moves freely above it. Render the piece overlaid on the board.piece/board freezes at its first value — hold them in refs so the interval always sees the current game.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.