Build a Sudoku Game and Learn State Management in React

Sudoku is one of my favorite logic-based number-placement puzzles. Due to the lack of quality Sudoku apps on the web and app stores, I decided to build my own version. It is packed with user-friendly and beginner-friendly features that make the game much more enjoyable. You can play it here. In this post, I will talk about designing, managing and working with the game’s state for the main UIs. You will read about how the right state design helps to keep the code clean and pleasant to work with. I hope it will help you reason, structure and manage an application’s state.

Game Rules

Fill a 9×9 grid with digits so that each column, each row, and each of the nine 3×3 squares that compose the grid contains all of the digits from 1 to 9.

The Game

Game generation

Sudoku is a constraint satisfaction problem. Solving and generating Sudoku puzzles has been an explored topic(see notes). This post focuses on the state management of the game UI, but here is roughly the game generation code if you are interested.

Represent the Puzzle in 2D Array

The puzzle is represented as a 9x9 two-dimensional array. Each element of the array represents a cell’s current value and its notes:

with each cell’s object contains its current value as well as its notes.

The Overall Game State

For the game to work, it needs to be able to:

  • track possible conflicts within each peer group: know the number of times a number is used per peer group(a complete group is one with each number used exactly once)

The Cell Component

Computing the Cell Component’s Inputs

Cell component needs { value, isPeer, isSelected, sameValue, prefilled, notes, conflict } to render its correct presentation to the user. { value, notes, prefilled } are directly accessed from the cell from the puzzle’s 2D array. However, determining the rest of inputs will need inferences from the overall game state particularly in relation to the selected cell. Keeping which cell is selected in the game state is rather straightforward:

component methods for getting selected cell and setting the selected coordinates

The Number Control Component

Each number control component allows a user to assign the corresponding numerical value to the selected cell. The presentation itself also visualizes the assignment progress of the number.

The NumberControl component needs:

  • a callback that would update the selected cell’s value on user clicks
  • a computed value of the number’s progress
  1. Take the minimum of the three values as the progress for the number

The Tool Components

initialize the game state with a history array and historyOffset
For erase and hint, I created erasedSelected and filledSelectedWithSolution respecitively

Wrapping Things Up

This is my thought process of implementing and designing the state for the game’s main components, the parts worth talking about. The Sudoku application benefited tremendously from having a good state design. The toughest thing to get right is state management. Planning the management of the state is crucial to your success in building maintainable applications. Make sure to spend plenty of time designing the application’s state at a high level before diving into the implementation details.

Related Materials

Chasing great designs, delightful user experiences and happy developer experiences. Find me at https://www.sitianliu.com/