Real-time
Multiplayer
Game
Sudoku
Web App
Featured Project
Real-time
Multiplayer
PWA

Sudoku with Friends

A multiplayer Sudoku game where you and your friends can solve puzzles together in real-time. No sign-up required, just create a room and share the link. Built with a custom Sudoku engine from scratch.

Maruf Hossainco-authored withGPT-5.2 (OpenAI)
ThinkFast Sudoku gameplay screenshot
ThinkFast Sudoku room creation screenshot

Key Features

Real-time Multiplayer

Live synchronization

No Registration

Instant play

PWA

Mobile-first design

Multiple Levels

From easy to Inhuman

Tech Stack

Frontend

Next.js 14
React 18
TypeScript
Tailwind CSS
Radix UI
Framer-Motion

Backend & Database

Firebase Realtime DB
Firebase Auth
Next.js API Routes

How It Works

Real-time Multiplayer

Firebase Realtime Database keeps everyone's moves synced instantly. When someone fills in a number, everyone else sees it within milliseconds. The trickiest part was handling conflicts, what happens when two people try to fill the same cell at the same time? I added validation and conflict resolution so it always stays consistent.

Custom Sudoku Engine

The most interesting part of this project was building the Sudoku engine from scratch: 820 lines of puzzle generation and solving logic. It uses a backtracking algorithm to generate valid puzzles and can create six difficulty levels by removing different amounts of numbers.

The difficulty ranges from Easy (62 starting numbers) down to Inhuman (only 17 numbers—the theoretical minimum for a valid Sudoku). Each puzzle is guaranteed to have exactly one solution.

State Management

React Context handles the game state, with undo/redo support and a notes mode for pencil marks. The validation runs in real-time, so you immediately see when there's a conflict.

Technical Highlights

Sudoku Generation

The puzzle generator uses backtracking to create valid grids:

// Recursive backtracking to fill the grid
function solveGrid(grid: number[][]): boolean {
  for (let row = 0; row < 9; row++) {
    for (let col = 0; col < 9; col++) {
      if (grid[row][col] === 0) {
        // Try numbers 1-9 in random order
        const numbers = shuffleArray([1, 2, 3, 4, 5, 6, 7, 8, 9]);

        for (const num of numbers) {
          if (isValid(grid, row, col, num)) {
            grid[row][col] = num;
            if (solveGrid(grid)) return true;
            grid[row][col] = 0; // Backtrack
          }
        }
        return false;
      }
    }
  }
  return true;
}

Real-time Sync

Firebase hooks keep the game state in sync:

// Listen to game state changes
useEffect(() => {
  const gameRef = ref(database, `games/${roomId}`);

  onValue(gameRef, (snapshot) => {
    setGameState(snapshot.val());
  });

  return () => off(gameRef);
}, [roomId]);

// Update a cell and sync to all players
const updateCell = async (row: number, col: number, value: number) => {
  await update(ref(database), {
    [`games/${roomId}/grid/${row}/${col}`]: value,
    [`games/${roomId}/lastMove`]: { row, col, value, timestamp: serverTimestamp() }
  });
};

Challenges

The hardest part was keeping the game state consistent when multiple people are editing at once. Firebase helps with atomic updates, but I still needed validation to handle edge cases. I ended up using optimistic updates with rollback, it feels instant but corrects itself if there's a conflict.

Making it work well on mobile took some iteration. The 9×9 grid needs to be big enough for fat fingers but still fit on small screens. I added a custom numpad and made sure all the touch targets were at least 44px.

Stats

2,500+
Lines of Code
820
Custom Engine Lines
25+
React Components

Performance & Analytics

Performance Metrics

Initial Load Time1.2s
Real-time Latency<100ms
Bundle Size45KB
Lighthouse Score98/100

User Engagement

Average Session12 minutes
Puzzles Completed500+
Multiplayer Games200+
Mobile Usage65%

What I Learned

Building the Sudoku engine from scratch was a great exercise in algorithm design. Backtracking algorithms are elegant but can be tricky to debug, unit tests saved me hours of headache.

Firebase is great for getting real-time features up quickly, but you need to think carefully about data structure and security rules. I learned to use optimistic updates to make it feel instant while still validating on the backend.

Starting with single-player mode first was the right call. Getting the core game logic solid before adding multiplayer complexity made debugging much easier.