Lightweight, deterministic and Unity-independent Sudoku generation, solving and validation library for .NET and Unity.
OpenSudokuEngine provides a compact 9×9 Sudoku domain model and reusable puzzle generation, solving, validation and candidate-number APIs. It is extracted from real-world Sudoku game development experience and has no runtime package dependencies.
- Immutable board and cell values with defensive array conversion
- Seeded puzzle generation with a unique-solution guarantee
- Solver distinguishes solved, unsolvable and invalid boards
- Bounded solution counting distinguishes 0, 1 and 2+ solutions
- Partial/completed board validation, solution checks and candidates
- Easy, Medium, Hard and Expert generation profiles
- Library: .NET Standard 2.1 (suitable for Unity 2022+)
- Tests: .NET 10
Build src/OpenSudokuEngine/OpenSudokuEngine.csproj and reference the resulting assembly in your .NET or Unity project. Restore and build the solution with the .NET SDK.
using OpenSudokuEngine;
var generator = new SudokuGenerator();
SudokuPuzzle puzzle = generator.Generate(new SudokuGenerationOptions
{
Difficulty = SudokuDifficulty.Medium,
Seed = 12345
});var result = new SudokuSolver().Solve(puzzle.Board);
if (result.Status == SudokuSolveStatus.Solved)
{
SudokuBoard solvedBoard = result.Solution!;
}Solve returns InvalidBoard for duplicate/out-of-range givens and Unsolvable when a structurally valid partial board has no completion. The input board is never mutated.
SudokuValidationResult partial = SudokuValidator.Validate(puzzle.Board);
SudokuValidationResult complete = SudokuValidator.Validate(puzzle.Solution, requireComplete: true);
bool matches = SudokuValidator.IsSolution(puzzle.Board, puzzle.Solution);var candidates = SudokuValidator.GetCandidates(puzzle.Board, row: 0, column: 0);An occupied cell returns an empty candidate list. Candidate results are read-only and do not expose board storage.
The built-in SystemRandomSource makes generation repeatable for the same seed and library/runtime version. A caller may provide another IRandomSource; it must return values in [0, exclusiveUpperBound). Custom random sources are not assumed thread-safe. Each generation call owns its working state. The generator supports date-derived seeds for deterministic daily puzzles, but does not implement date selection or a daily service.
Default empty-cell targets are Easy 32, Medium 38, Hard 45 and Expert 51. They are generation presets, not a human solving-technique rating. Callers can set EmptyCellTarget from 0 through 64. The generator tries shuffled clue removals and keeps each removal only when exactly one solution remains; if the requested count cannot be reached, it returns the best unique puzzle found after considering each cell at most once.
Every generated puzzle has exactly one solution. CountSolutions(board, limit) returns a count capped at the positive limit; use the default limit of 2 to distinguish no solution, unique solution and multiple solutions. Solution counting checks givens first and returns zero for invalid boards.
Reference the built .NET Standard 2.1 assembly in Unity 2022 or newer. Convert to int[,] only at an integration boundary with SudokuBoard.FromArray and ToArray. No Unity adapter or Unity package is required by the library.
SudokuBoard/SudokuCell: immutable 9×9 domain valuesSudokuGenerator: randomized full-grid backtracking and unique clue removalSudokuSolver: backtracking with minimum-remaining-values selectionSudokuValidator: structural validation, completed solutions and candidatesIRandomSource: replaceable source for generation randomness
Generation and solving use straightforward backtracking with bounded uniqueness counting. Local test measurements are informational and machine-dependent; no timing is guaranteed. Generation does not currently support cancellation.
dotnet restore OpenSudokuEngine.sln
dotnet build OpenSudokuEngine.sln --configuration Release
dotnet test OpenSudokuEngine.sln --configuration ReleaseTests include 40 deterministic generated-puzzle property samples and 25-puzzle timing samples for Medium, Hard and Expert. Timing results are printed for observation, not used as pass/fail performance promises.
- More solver techniques and an explainable difficulty estimator
- Optional symmetric clue-removal generation
- API compatibility policy and broader runtime benchmarks
See CONTRIBUTING.md, CODE_OF_CONDUCT.md and SECURITY.md. Contributions should keep the library Unity-independent and include tests for behavior changes.
MIT. See LICENSE.