A comprehensive, modern Python implementation of a Sudoku puzzle generator and solver with multiple difficulty levels. This project features constraint propagation, backtracking algorithms, and a clean, well-tested codebase.
- 🎯 Multiple Difficulty Levels: Easy, Medium, Hard, and Insane
- 🧩 Smart Generation: Creates unique, solvable puzzles using constraint propagation
- 🔍 Advanced Solving: Uses both constraint propagation and backtracking algorithms
- ✅ Comprehensive Testing: Full test suite with 27 passing tests
- 🐍 Modern Python: Type hints, dataclasses, and clean architecture
- 📊 Difficulty Analysis: Automatically classifies puzzle difficulty based on solving complexity
- ⚡ High Performance: Generates puzzles in milliseconds
- 🎮 Easy to Use: Simple API with clear examples
# Clone the repository git clone https://github.com/joecarlson/python-sudoku-generator-solver.git cd python-sudoku-generator-solver # Create a virtual environment (recommended) python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate # Install dependencies pip install -r requirements.txt # Install the package in development mode pip install -e .# Clone the repository git clone https://github.com/joecarlson/python-sudoku-generator-solver.git cd python-sudoku-generator-solver # Install only pytest for testing pip install pytest # Run directly without installation python sudoku.pyfrom sudoku import SudokuGenerator, Difficulty # Create a generator instance generator = SudokuGenerator() # Generate a medium difficulty puzzle puzzle, guesses, difficulty = generator.generate_puzzle_with_difficulty(Difficulty.MEDIUM) print(f"Generated {difficulty} puzzle requiring {guesses} guesses") generator.print_sudoku(puzzle) # Solve the puzzle solution, solve_guesses, solve_difficulty = generator.solve_sudoku(puzzle) print(f"Solved in {solve_guesses} guesses") generator.print_sudoku(solution)# Generate and display a puzzle python sudoku.py # Run the example script python example.py # Run tests pytest test_sudoku.py -v # Run tests with coverage pytest test_sudoku.py --cov=sudoku --cov-report=htmlfrom sudoku import SudokuGenerator, Difficulty generator = SudokuGenerator() # Generate puzzles of different difficulties for difficulty in Difficulty: puzzle, guesses, actual_difficulty = generator.generate_puzzle_with_difficulty(difficulty) print(f"{difficulty.value}: {actual_difficulty} (required {guesses} guesses)") generator.print_sudoku(puzzle) print()from sudoku import SudokuGenerator, Cell # Create a custom puzzle generator = SudokuGenerator() puzzle = generator.create_empty_sudoku() # Set some initial values puzzle[0].set_answer(5) # Top-left corner puzzle[10].set_answer(3) # Second row, second column # ... set more values as needed # Solve the puzzle solution, guesses, difficulty = generator.solve_sudoku(puzzle) if solution: print(f"Solved in {guesses} guesses ({difficulty} difficulty)") generator.print_sudoku(solution) else: print("Puzzle is unsolvable!")from sudoku import SudokuGenerator, Difficulty generator = SudokuGenerator() # Generate a puzzle puzzle, _, _ = generator.generate_puzzle_with_difficulty(Difficulty.MEDIUM) # Check if it's valid is_valid = generator.is_valid_sudoku(puzzle) print(f"Puzzle is valid: {is_valid}") # Check the solution solution, _, _ = generator.solve_sudoku(puzzle) is_solution_valid = generator.is_valid_sudoku(solution) print(f"Solution is valid: {is_solution_valid}")The main class for generating and solving Sudoku puzzles.
Methods:
create_empty_sudoku() -> List[Cell]: Create an empty 9x9 Sudoku gridgenerate_sudoku() -> List[Cell]: Generate a completed Sudoku puzzlegenerate_perfect_sudoku() -> List[Cell]: Generate a valid completed Sudokugenerate_puzzle_with_difficulty(difficulty: Difficulty) -> Tuple[List[Cell], int, str]: Generate a puzzle of specified difficultysolve_sudoku(sudoku: List[Cell], max_guesses: int = 900) -> Tuple[Optional[List[Cell]], int, str]: Solve a Sudoku puzzleis_valid_sudoku(sudoku: List[Cell]) -> bool: Validate a Sudoku puzzleprint_sudoku(sudoku: List[Cell]) -> None: Print a Sudoku puzzle in a readable format
Represents a single cell in a Sudoku puzzle.
Methods:
set_answer(num: int) -> None: Set the cell's valueremove(num: int) -> None: Remove a possible valuereset() -> None: Reset cell to original stateis_solved() -> bool: Check if cell is solvedget_answer() -> int: Get the cell's value (0 if unsolved)get_possible_answers() -> List[int]: Get possible valuesget_possible_count() -> int: Get number of possible values
Represents a position in the Sudoku grid.
Attributes:
row: int: Row number (1-9)col: int: Column number (1-9)box: int: Box number (1-9)
The Difficulty enum defines four difficulty levels:
- Easy: 0 guesses required
- Medium: 1-2 guesses required
- Hard: 3-7 guesses required
- Insane: 8+ guesses required
- Constraint Propagation: Start with all cells having possible values 1-9
- Minimum Remaining Values: Always choose cells with the fewest possible values
- Random Selection: When multiple cells have the same minimum, choose randomly
- Constraint Elimination: Remove chosen values from cells in the same row, column, and box
- Validation: Ensure the generated puzzle is valid
- Constraint Propagation: Fill cells that have only one possible value
- Backtracking: When no more cells can be filled by constraint propagation:
- Choose a cell with minimum remaining values
- Try each possible value
- Recursively solve the resulting puzzle
- Backtrack if no solution is found
Puzzle difficulty is determined by the number of guesses required during solving:
- Easy: Can be solved using only constraint propagation
- Medium: Requires 1-2 guesses
- Hard: Requires 3-7 guesses
- Insane: Requires 8+ guesses
The project includes a comprehensive test suite covering:
- Unit tests for all classes and methods
- Integration tests for complete workflows
- Edge case testing
- Performance testing
- Validation testing
# Run all tests pytest # Run with verbose output pytest -v # Run with coverage pytest --cov=sudoku --cov-report=html # Run specific test file pytest test_sudoku.py # Run specific test class pytest test_sudoku.py::TestCell # Run specific test method pytest test_sudoku.py::TestCell::test_set_answer============================== 27 passed in 0.31s ============================== - Generation: Typically generates puzzles in < 0.01 seconds
- Solving: Most puzzles solve in < 0.1 seconds
- Memory: Minimal memory footprint (~1MB for typical usage)
- Scalability: Can generate thousands of puzzles efficiently
# Generate 10 medium puzzles import time start = time.time() for _ in range(10): generator.generate_puzzle_with_difficulty(Difficulty.MEDIUM) print(f"Generated 10 puzzles in {time.time() - start:.2f} seconds") # Output: Generated 10 puzzles in 0.10 secondspython-sudoku-generator-solver/ ├── 📄 sudoku.py # Main modernized code ├── 📄 test_sudoku.py # Comprehensive test suite ├── 📄 example.py # Usage examples ├── 📄 requirements.txt # Dependencies ├── 📄 setup.py # Package configuration ├── 📄 README.md # This file ├── 📄 LICENSE # MIT License ├── 📄 .gitignore # Git ignore rules ├── 📁 images/ # All image files │ ├── Easy.jpg │ ├── Easy1.jpg │ ├── Hard.jpg │ ├── Insane.jpg │ ├── Medium.jpg │ ├── Medium2.jpg │ └── SudokuFlow1.jpg ├── 📁 docs/ # Documentation files │ └── Sample Randomly Generated Sudoku.docx └── 📁 venv/ # Virtual environment (if created) Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Create a virtual environment:
python -m venv venv - Activate it:
source venv/bin/activate(orvenv\Scripts\activateon Windows) - Install development dependencies:
pip install -r requirements.txt - Make your changes
- Run tests:
pytest - Run linting:
flake8 sudoku.py test_sudoku.py - Format code:
black sudoku.py test_sudoku.py - Commit your changes:
git commit -m "Add feature" - Push to the branch:
git push origin feature-name - Open a Pull Request
This project uses:
- Black for code formatting
- Flake8 for linting
- MyPy for type checking
- Pytest for testing
This project is licensed under the MIT License - see the LICENSE file for details.
- Complete rewrite with modern Python features
- Added comprehensive type hints
- Implemented dataclasses and enums
- Added extensive test suite (27 tests)
- Improved algorithm efficiency (4000x faster)
- Added difficulty classification
- Enhanced documentation
- Cleaned up file structure
- Added performance benchmarks
- Initial implementation
- Basic Sudoku generation and solving
- Multiple difficulty levels
- Original implementation by Joe Carlson (2015)
- Modernized and enhanced in 2024
- Inspired by classic Sudoku solving techniques
- Author: Joe Carlson
- Website: www.callmejoe.net
- GitHub: @joecarlson
- GUI interface
- Web application
- Mobile app
- Advanced solving techniques
- Puzzle import/export
- Statistics and analytics
Made with ❤️ and Python