Simply Sudoku
A familiar puzzle. Built from the rules up.
A native Android learning project exploring puzzle generation, game state, and responsive interaction in Kotlin.
- Platform
- Mobile App
- Scope
- Full-stack
- Team
- Solo
- Status
- Complete
- Started
- Jun 15, 2024
Project context
Sudoku has been one of my favorite puzzle games since middle school, so when I began learning Kotlin and Android development, it felt like a natural project to build from scratch.
The goal was not to reinvent the game or turn it into something overly complex. I wanted to create a clean, familiar Sudoku experience while using the project to practice algorithm design, state management, and native mobile development.
The challenge
- Generate valid puzzles from scratch
- Keep the board synchronized with game rules
The approach
- One game model owns state and moves
- Native views render the current board
From intent to interaction
Generate a puzzle
Build a solved grid and remove clues while checking for multiple solutions.
Work through the board
Select cells, enter values, and use hints or undo when needed.
Save and return
Resume a locally saved game for the selected difficulty.
What it makes possible
Play a generated puzzle
Start a locally generated puzzle with a checked solution.
Work through mistakes
Use hints, undo, redo, and reset while solving the board.
Resume a saved game
Resume saved board state and elapsed time by difficulty.
How the pieces fit
Android screens
Render the board and respond to player input.
Fragments and XML viewsShared game state
Manage puzzles, move history, and validation.
MainViewModel and GameLogicLocal save slots
Save board state and elapsed time by difficulty.
SharedPreferencesOne owner for game logic
Keep board updates and gameplay tools connected to one game model.
Keep computation off the interaction path
Run heavier puzzle operations without blocking player interaction.
Engineering notebook
Explore the design, data flow, and implementation in more detail.
Android screens
Render the board and respond to player input.
Fragments and XML viewsShared game state
Manage puzzles, move history, and validation.
MainViewModel and GameLogicLocal save slots
Save board state and elapsed time by difficulty.
SharedPreferencesSimply Sudoku was built as a personal learning project around a game I already enjoyed playing.
The project gave me a focused way to practice Kotlin, Android development, recursive problem solving, and gameplay state management without hiding behind a prebuilt game engine. Because Sudoku is deterministic and rule-driven, it provided a clear environment for learning how to represent a board, validate moves, manage player interaction, and keep the interface synchronized with the underlying game state.
Implementation
Simply Sudoku is built as a native Android application in Kotlin using AppCompat fragments, XML layouts, traditional Views, and an activity-scoped MainViewModel.
The app centers around a single GameLogic instance owned by the ViewModel. GameLogic handles puzzle generation, board mutation, validation against the solved grid, hints, undo/redo, reset, completion checks, and save-state serialization, while fragments observe LiveData and refresh the board UI.
Generate a puzzle
Generate a board with a checked unique solution.
Work through the board
Enter values and use hints or undo when needed.
Save and return
Resume the saved game for the chosen difficulty.
Users open the app, start a Sudoku puzzle, select cells, enter values, and work through the board using a familiar mobile puzzle interface.
The experience is intentionally simple. The app is meant to feel like Sudoku: clear, focused, and consistent, without unnecessary layers getting in the way of solving the puzzle.
Implementation
A puzzle begins inside GameLogic, which creates a solved 9x9 grid by randomizing diagonal boxes and completing the board with recursive backtracking. It then removes clues while rejecting removals that would produce multiple solutions.
The board is represented through parallel grids for the solved puzzle, initial givens, current player-visible state, and cell color classification. When a user enters a value, the ViewModel routes the update into GameLogic, records the move in undo history, recalculates correctness against the solved grid, and republishes board state through LiveData for the fragment to render.
Generate a unique puzzle
Reject clue removals that allow multiple solutions.
Keep separate board grids
Track solved, initial, current, and color grids.
Save one game per difficulty
Save board state and elapsed time by difficulty.
Simply Sudoku is built around the gameplay loop that makes Sudoku work: board state, valid moves, puzzle solving, and responsive interaction.
The most interesting part of the project was not adding extra features, but coordinating the backtracking logic, game state, and Android UI so the app remained responsive while puzzle operations were processed. Working through that helped me better understand how coroutines can keep computation-heavy logic from blocking the user experience.
Implementation
Navigation is handled through fragment replacement inside a single FragmentContainerView, with LandingFragment, GameFragment, and ThemeFragment forming the main screens. The game board is rendered as 81 TextView cells inside a ConstraintLayout, with larger margins marking 3x3 box boundaries.
Persistence uses SharedPreferences save slots for Easy, Medium, and Hard games. Each slot stores the initial board, solved board, current user board, color grid, and elapsed time. The implementation favors a simple local architecture over accounts, remote sync, databases, or a game engine.
Generated puzzles
Generate a solved board, then remove clues while checking for multiple solutions.
Board state model
Keep solution, givens, player entries, and cell colors together inside GameLogic.
Move validation
Compare player input with the solution and reveal mistakes through Show mode.
Hints and correction tools
Support solved-cell hints, reset, clear mistakes, and in-memory undo and redo.
Local save slots
Store one game per difficulty in SharedPreferences, including grids and elapsed time.
Classic Sudoku gameplay
Provides a familiar Sudoku experience centered on solving a clean, rule-driven puzzle board.
Board interaction
Allows users to select cells, enter values, and progress through the puzzle using a simple mobile interface.
Puzzle validation
Uses Sudoku rules to keep gameplay grounded in row, column, and box constraints.
Solver-backed logic
Uses backtracking logic to support the puzzle system and reinforce the deterministic rules behind the game.
Responsive gameplay
Uses asynchronous processing patterns so puzzle logic can run without making the interface feel blocked or sluggish.
Implementation
Generated puzzles
Creates puzzles locally by seeding randomized diagonal 3x3 boxes, completing the board with recursive backtracking, and removing clues while checking for multiple solutions.
Board state model
Tracks the solved board, original givens, current user entries, and cell color state through parallel 9x9 grids managed by GameLogic.
Move validation
Compares user-entered values directly against the generated solution and uses Show mode to reveal correct, incorrect, and hinted cells.
Hints and correction tools
Supports random solved-cell hints, clear-mistakes behavior, reset, and in-memory undo/redo stacks for player actions.
Local save slots
Stores one resumable game per difficulty in SharedPreferences, including board grids and elapsed time.
Have a related challenge?
Let’s talk about it.
Bring an idea, a workflow to improve, or a technical question. We can work through what comes next.