15 Puzzle

ReactTypeScriptuseStateuseEffectuseRef

A sliding tile puzzle where you rearrange 15 numbered tiles into order by clicking adjacent tiles to slide them into the empty space.

What I learned

  • Implementing a solvability check for the 15-puzzle using inversion counting and blank-row parity
  • Using useEffect with setInterval and a useRef for a clean, leak-free timer
  • Applying the "null board on SSR, real board after mount" pattern to prevent hydration mismatches with Math.random()
  • Using <button> elements instead of <div> for accessible, keyboard-friendly tiles

Technical details

The board is a flat array of 16 numbers where 0 marks the empty space. On each click the component checks if the clicked tile is directly adjacent (Manhattan distance = 1) to the blank, then swaps them in a new array copy — keeping state immutable. The shuffle uses Fisher-Yates and includes a solvability check: if the number of inversions and the blank's row parity produce an unsolvable configuration, two non-blank tiles are swapped to flip the parity. The timer starts on the first move and stops when the goal state [1, 2, …, 15, 0] is reached.

Related Journal Entries