ReactCHALLENGES
💻 Challenges🎁 Referral Program🐞 Report a Bug

© 2025 reactchallenges.com

Terms of ServicePrivacy PolicyContact

#43Tetris
120min

Overview

This is a classic Tetris game implemented in React using a canvas for rendering. The game allows players to move, rotate, and drop pieces, complete rows to earn points, and ends when new pieces cannot be placed on the board.

Requirements

Application logic (App.tsx)

  • Manage game state:

    • Board
    • Current piece
    • Game running state
    • Game over state
    • Points
  • Implement a game loop (using requestAnimationFrame) to move the piece down automatically.

  • Handle user interactions:

    • Start: initialize board, piece, points, and start the game loop.
    • Reset: reset the game to its initial state.
  • When a piece can no longer move down:

    • Solidify it into the board
    • Remove completed rows
    • Update points (e.g. 100 points per row)
    • Spawn a new piece
  • Detect Game Over when a new piece collides immediately on spawn.

  • When the game is over:

    • Stop the game loop
    • Show the Game Over! overlay (data-testid="game-over")

Utilities (utils.ts)

  • Implement createEmptyBoard() to return a ROW x COL grid filled with zeros.
  • Implement randomPiece() to return a random piece with an initial position at the top of the board.
  • Implement checkCollision() to detect collisions with:
    • Board boundaries
    • Existing solidified blocks
  • Implement solidifyPiece() to merge the current piece into the board.
  • Implement removeCompletedRows() to:
    • Remove full rows
    • Shift remaining rows down
    • Return how many rows were removed
  • Implement rotatePiece() to rotate a piece clockwise.
  • Implement movePiece() to move or rotate a piece while preventing invalid moves.
  • Implement drawBoard() to render the board on the canvas.
  • Implement drawPiece() to render the active piece on the canvas.

Notes

  • The starting point is a simple App.tsx with a canvas, Start and Reset buttons, and a points counter. Core game logic such as piece generation, board updates, collision detection, row removal, and scoring should be complete in utils.ts.
  • The board size is calculated from WIDTH / CELL_SIZE (columns) and HEIGHT / CELL_SIZE (rows). Avoid off-by-one errors.
  • Pieces should start at the horizontal middle (Math.floor(COL / 2)) and top (y = 0) when spawned.
  • Collision checks must consider both the board edges and solidified blocks.
  • Solidifying a piece should not mutate the original board (always return a new board).
  • Removing completed rows should maintain the total number of rows (ROW) by adding empty rows at the top.
  • Rotations may cause collisions; ensure movePiece() prevents invalid rotations.
  • Rendering on the canvas must respect CELL_SIZE for correct scaling.
  • Game over is triggered when a new piece collides immediately on spawn.
  • Points are calculated based on rows removed and updated after each piece is solidified.

Tests

  1. renders the app title
  2. drawBoard draws filled cells
  3. drawPiece draws piece at correct position
  4. drawPiece does not draw zero cells
  5. drawPiece sets the correct fillStyle for piece color
  6. drawBoard sets fillStyle to black for filled cells
  7. drawBoard and drawPiece do not draw zeros
  8. creates an empty board
  9. detects collision with board boundaries
  10. solidifies piece on board correctly
  11. removes completed rows
  12. rotates piece correctly
  13. randomPiece returns a valid piece
  14. solidify + removeCompletedRows integration
  15. detects collision after rotation
  16. detects lateral collisions
  17. detects collision with existing blocks on board
  18. does not detect collision when piece is adjacent to blocks
  19. solidifyPiece does not mutate original board
  20. does not remove rows that are not fully completed
  21. moves piece left
  22. moves piece right with ArrowRight
  23. moves piece down with ArrowDown
  24. does not move piece left if collision
  25. does not move piece right if collision
  26. increments points when rows are completed
  27. sets game over when a new piece collides immediately
  28. startGame initializes board, piece, points, and isGameStarted
  29. resetGame clears board, points, and game state
  30. shows Game Over when board is already full
Subscribe to StartBack