#44Tetris II
Overview
This is the second part of the Tetris challenge series. In this version, the user interface, game loop, and React components are already implemented for you. Your goal is to focus purely on the game logic by completing the utility functions in src/utils.ts. You will implement piece generation, movement, collision detection, and row clearing to make the game functional.
Requirements
Application Logic (Provided in App.tsx)
The main application component is already implemented and handles:
- Game state management (board, piece, score, game over).
- The game loop.
- Canvas rendering (calling
drawBoardanddrawPiece). - Keyboard event listeners.
Utilities (src/utils.ts)
You must implement the following functions marked with // complete function (and checkCollision which is required by them):
-
randomPiece():- Select a random piece shape and color from the
PIECESarray. - Set its initial position to the horizontal center of the board and the top row (
y=0).
- Select a random piece shape and color from the
-
checkCollision(board, piece):- Return
trueif any part of thepieceoverlaps with:- The board boundaries (left, right, bottom).
- Existing solidified blocks on the board.
- Return
falseotherwise.
- Return
-
solidifyPiece(board, piece):- Merge the
pieceinto theboard. - Return a new board grid with the piece's shape permanently added (using non-zero values).
- Merge the
-
removeCompletedRows(board):- Identify rows that are completely filled (no zeros).
- Remove those rows.
- Add an equivalent number of new empty rows to the top of the board.
- Return an object:
{ board: number[][], removed: number }(whereremovedis the count of cleared rows).
-
movePiece(board, piece, direction):- Handle directions:
"left","right","down","rotate". - Calculate the new candidate position/shape.
- Use
checkCollisionto verify if the move is valid. - Return the new piece state if valid, or the original piece if invalid.
- Handle directions:
-
rotatePiece(shape):- Rotate the 2D array
shape90 degrees clockwise. - Return the new rotated shape.
- Rotate the 2D array
Notes
- Focus on
src/utils.ts: TheApp.tsxfile is already complete. It handles the React state, game loop (requestAnimationFrame), and canvas rendering. Your task is to implement the logic functions it calls. - Board Dimensions: The board size is defined by
ROWandCOLconstants derived fromWIDTH,HEIGHT, andCELL_SIZE. - Coordinate System:
xcorresponds to columns (horizontal).ycorresponds to rows (vertical).- The top-left corner is
(0, 0).
- Immutability: Functions like
solidifyPieceandremoveCompletedRowsshould return new copies of the board/state, avoiding direct mutation of the arguments. - Collision Detection:
- Check boundaries:
xmust be within[0, COL-1]andywithin[0, ROW-1]. - Check existing blocks: The board cell at
(y, x)must be0(empty).
- Check boundaries:
- Rotation: Standard Tetris rotation is 90 degrees clockwise.
- Row Clearing: When a row is full (all cells are non-zero), it is removed, and all rows above it shift down. New empty rows are added at the top.
Tests
- renders the app title
- drawBoard draws filled cells
- drawPiece draws piece at correct position
- drawPiece does not draw zero cells
- drawPiece sets the correct fillStyle for piece color
- drawBoard sets fillStyle to black for filled cells
- drawBoard and drawPiece do not draw zeros
- creates an empty board
- detects collision with board boundaries
- solidifies piece on board correctly
- removes completed rows
- rotates piece correctly
- randomPiece returns a valid piece
- solidify + removeCompletedRows integration
- detects collision after rotation
- detects lateral collisions
- detects collision with existing blocks on board
- does not detect collision when piece is adjacent to blocks
- solidifyPiece does not mutate original board
- does not remove rows that are not fully completed
- moves piece left
- moves piece right with ArrowRight
- moves piece down with ArrowDown
- does not move piece left if collision
- does not move piece right if collision
- increments points when rows are completed
- sets game over when a new piece collides immediately
- startGame initializes board, piece, points, and isGameStarted
- resetGame clears board, points, and game state
- shows Game Over when board is already full