A modern, modular implementation of the popular 2048 puzzle game built with React and functional programming principles.
Play the game here ๐ฎ
- Features
- Installation
- Running the Game
- Gameplay Instructions
- Technical Implementation
- Project Structure
- Functional Programming Principles
- Customization
- Contributing
- License
- Modular Architecture: Clean separation of concerns with reusable components
- Functional Programming: Pure functions and immutable data structures
- Configurable Board Size: Play on 3x3, 4x4, 5x5, or 6x6 grids
- Responsive Design: Works on desktop and mobile devices
- Keyboard Controls: Arrow keys or WASD for movement
- Score Tracking: Persistent best score storage
- Smooth Animations: CSS transitions for tile movements
- Game States: Win detection, game over handling, and restart functionality
- Accessibility: Focus indicators and keyboard navigation
- Size Selection: Dropdown menu for easy board size selection
- Attribution: Clean footer with developer contact information
- Node.js (version 14 or higher)
- npm or yarn package manager
-
Clone the repository
git clone https://github.com/yourusername/2048-react-game.git cd 2048-react-game -
Install dependencies
npm install # or yarn install -
Start the development server
npm start # or yarn start -
Open your browser Navigate to
http://localhost:3000to play the game.
npm startRuns the app in development mode with hot reloading.
npm run buildCreates an optimized production build in the build folder.
npm testLaunches the test runner in interactive watch mode.
Combine numbered tiles to reach the 2048 tile!
-
Movement: Use arrow keys or WASD to slide tiles
- โ/W: Move up
- โ/S: Move down
- โ/A: Move left
- โ/D: Move right
-
Merging: Tiles with the same number merge when they collide
- 2 + 2 = 4
- 4 + 4 = 8
- 8 + 8 = 16
- And so on...
-
Scoring: Each merge adds points to your score
- Merging two 4s gives you 8 points
- Merging two 8s gives you 16 points
-
New Tiles: After each move, a new tile (2 or 4) appears randomly
-
Game Over: The game ends when:
- You reach 2048 (You Win!)
- No more moves are possible (Game Over)
- New Game: Start a fresh game
- Size Dropdown: Select board size (3x3 to 6x6)
- Keyboard: Arrow keys or WASD for movement
The game follows a modular, component-based architecture with clear separation of concerns:
src/
โโโ components/ # Reusable UI components
โโโ hooks/ # Custom React hooks
โโโ styles/ # Styled-components
โโโ utils/ # Pure game logic functions
โโโ App.js # Main application component
-
Functional Programming
- Pure functions for game logic
- Immutable data structures
- No side effects in core logic
-
Custom Hooks
useGame: Manages game state and logicuseKeyboard: Handles keyboard input
-
Component Composition
- Small, focused components
- Props-based communication
- Reusable UI elements
User Input โ useKeyboard โ useGame โ Game Logic โ State Update โ UI Re-render
2048-react-game/
โโโ public/
โ โโโ index.html # HTML template
โโโ src/
โ โโโ components/ # React components
โ โ โโโ Controls.js # Game controls (New Game, Size)
โ โ โโโ GameBoard.js # Main game grid
โ โ โโโ GameOverModal.js # Win/Lose modal
โ โ โโโ Instructions.js # Game instructions
โ โ โโโ Score.js # Score display
โ โ โโโ Tile.js # Individual tile component
โ โโโ hooks/ # Custom React hooks
โ โ โโโ useGame.js # Game state management
โ โ โโโ useKeyboard.js # Keyboard event handling
โ โโโ styles/ # Styled-components
โ โ โโโ GlobalStyles.js # All styled components
โ โโโ utils/ # Pure functions
โ โ โโโ gameLogic.js # Core game logic
โ โโโ App.js # Main application
โ โโโ index.js # React entry point
โโโ package.json # Dependencies and scripts
โโโ README.md # This file
All game logic functions are pure - they don't modify external state and always return the same output for the same input:
// Example: Pure function for sliding a row
export const slideRowLeft = (row) => {
// No side effects, returns new data
return { row: newRow, score: gainedScore };
};Game state is never mutated directly. Instead, new state objects are created:
// Example: Creating new board state
const newBoard = board.map(row => [...row]);
newBoard[row][col] = newValue;Complex operations are built by composing simpler functions:
// Example: Slide up = transpose + slide left + transpose
export const slideUp = (board) => {
const transposedBoard = transpose(board);
const { board: slidBoard } = slideLeft(transposedBoard);
return transpose(slidBoard);
};Add new sizes to the availableSizes array in the Controls component:
const availableSizes = [3, 4, 5, 6, 7, 8]; // Add 7x7 and 8x8Update the styled-components in GlobalStyles.js:
${props => props.value === 2048 && `
background: #your-color;
color: #your-text-color;
`}The modular architecture makes it easy to add new features:
- New Components: Add to
src/components/ - New Hooks: Add to
src/hooks/ - New Logic: Add pure functions to
src/utils/
The project is set up with Jest and React Testing Library. Add tests to verify:
- Game logic functions
- Component rendering
- User interactions
- Keyboard controls
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Commit changes:
git commit -am 'Add feature' - Push to branch:
git push origin feature-name - Submit a pull request
- Original 2048 game by Gabriele Cirulli
- React team for the amazing framework
- Styled-components for CSS-in-JS solution
Happy Gaming! ๐ฎ
This is a dummy line for testing purposes.