How to Build a Sudoku Game in Python Using Tkinter (Step-by-Step Guide)

Introduction

Are you a fan of puzzles and logic games? Sudoku has always been one of my favorite pastimes, and as a Python enthusiast, I decided to combine my love for coding and Sudoku by building a Sudoku game in Python. In this article, I’ll walk you through the process of creating a Python Sudoku game with Tkinter, and share the complete Python source code so you can try it out yourself or even customize it!

What is Sudoku?

Sudoku is a classic logic-based number puzzle. The goal is to fill a 9×9 grid with digits so that each column, each row, and each of the nine 3×3 subgrids contain all the digits from 1 to 9 without repetition. It’s a great way to exercise your brain and improve problem-solving skills.

Why Python for Sudoku?

Python is a versatile and beginner-friendly programming language, making it an excellent choice for building a Sudoku game in Python. Its simplicity and readability allow developers to focus on the game logic rather than complex syntax. Plus, Python’s extensive libraries and tools make it easy to implement features like user input validation, random puzzle generation, and a graphical interface using Tkinter.

If you’ve ever wanted to create a Sudoku puzzle in Python, this guide will help you understand how to do it step by step.

Features of My Python Sudoku Game

My Python Sudoku game includes the following features:

Three Difficulty Levels: Easy, Medium, and Hard
Random Puzzle Generation: The game generates a new Sudoku puzzle every time you play.
Graphical User Interface (GUI): Built with Tkinter, making it interactive and user-friendly.
Input Validation: Ensures that your moves follow Sudoku rules.
Solution Checking: Players can verify their answers.
Show Solution: Users can reveal the correct solution if they get stuck.

If you’re looking for a Python Sudoku solver with Tkinter, this project provides a great starting point!

How I Built the Sudoku Game in Python

1. Setting Up the GUI

The game uses Tkinter to create a Sudoku GUI in Python. A Tk window is initialized, and a 9×9 Sudoku grid is created using Entry widgets for user input.

2. Generating a Random Puzzle

To generate a Sudoku puzzle in Python, I used a backtracking algorithm. This algorithm fills the board with valid numbers and then removes some to create a solvable puzzle. If you are interested in Sudoku solver projects in Python, this is a great way to approach puzzle generation.

3. Implementing Difficulty Levels

The difficulty levels are achieved by controlling the number of empty cells in the Sudoku grid:

  • Easy Sudoku in Python: 30% of cells removed.
  • Medium Sudoku in Python: 50% of cells removed.
  • Hard Sudoku in Python: 70% of cells removed.

This ensures that players can choose a difficulty level that suits their experience level.

4. Validating User Input

The game ensures that each number entered by the player does not repeat within the same row, column, or 3×3 subgrid, following Sudoku rules in Python.

5. Checking for a Win

Once the board is completely filled, the program verifies whether the Sudoku solution is correct in Python. If the player successfully fills the board without violating the rules, they win the game.

6. Providing a Solution

If the player is stuck, they can reveal the correct solution, which is stored at the start of the game. This feature makes it a great Python Sudoku solver GUI project for learning how to automate Sudoku solving in Python.

Explanation the Code

The code is structured using Object-Oriented Programming (OOP) principles, where the SudokuGame class manages the game logic, user interface, and interactions. Let’s break it down step by step.

1. Importing Required Libraries

import tkinter as tk
from tkinter import messagebox
import random
import time
  • tkinter: The standard Python library for creating GUI applications.
  • messagebox: A Tkinter module used to display alert messages.
  • random: Used for shuffling numbers and generating the Sudoku grid.
  • time: Used to track the time taken by the user to complete the puzzle.

2. The SudokuGame Class

The game is built as a class named SudokuGame. When an object of this class is created, the game window is initialized.

Initializing the Game Window

class SudokuGame:
    def __init__(self, master):
        self.master = master
        self.master.title("Sudoku Game")
        self.master.geometry("500x550")
        self.master.resizable(False, False)
  • Sets the window title and dimensions (500x550).
  • Disables window resizing for a fixed layout.

Game Variables

self.difficulty = None
self.start_time = None
self.grid = [[0]*9 for _ in range(9)]
self.solution = None
  • self.difficulty: Stores the selected difficulty level (Easy, Medium, Hard).
  • self.start_time: Records when the game starts.
  • self.grid: A 9×9 matrix initialized with zeros to store the Sudoku puzzle.
  • self.solution: Stores the complete solution of the puzzle.

3. Creating the Start Menu

def create_start_menu(self):
    self.clear_screen()
    self.start_menu = tk.Frame(self.master)
    self.start_menu.pack()
    
    tk.Label(self.start_menu, text="Select Difficulty:", font=("Arial", 14)).pack()
    
    tk.Button(self.start_menu, text="Easy", command=lambda: self.start_game("easy"), width=15).pack()
    tk.Button(self.start_menu, text="Medium", command=lambda: self.start_game("medium"), width=15).pack()
    tk.Button(self.start_menu, text="Hard", command=lambda: self.start_game("hard"), width=15).pack()
  • Displays a difficulty selection screen when the game starts.
  • Buttons allow the user to choose a difficulty level (Easy, Medium, or Hard).

4. Generating the Sudoku Puzzle

def generate_sudoku(self):
    base = 3
    side = base * base

    def pattern(r, c): return (base * (r % base) + r // base + c) % side

    def shuffle(s): return random.sample(s, len(s))

    r_base = range(base)
    rows = [g * base + r for g in shuffle(r_base) for r in shuffle(r_base)]
    cols = [g * base + c for g in shuffle(r_base) for c in shuffle(r_base)]
    nums = shuffle(range(1, side + 1))

    board = [[nums[pattern(r, c)] for c in cols] for r in rows]
    solution = [row[:] for row in board]
  • Uses a mathematical pattern-based approach to generate a complete valid Sudoku solution.
  • Randomly shuffles rows, columns, and numbers to create different Sudoku puzzles.

Removing Numbers Based on Difficulty

squares = side * side
empties = squares * (0.3 if self.difficulty == "easy" else 0.5 if self.difficulty == "medium" else 0.7)

for p in random.sample(range(squares), int(empties)):
    board[p // side][p % side] = 0

return board, solution
  • A certain percentage of numbers are removed to create the puzzle based on difficulty:
    • Easy: 30% of numbers removed
    • Medium: 50% of numbers removed
    • Hard: 70% of numbers removed

5. Creating the Sudoku Grid (Game Board)

def create_game_board(self):
    self.board_frame = tk.Frame(self.master)
    self.board_frame.pack(pady=10)

    self.cells = []
    cell_size = 50
    for i in range(9):
        row = []
        for j in range(9):
            entry = tk.Entry(self.board_frame, width=2, font=("Arial", 18), justify='center', bd=2)
            entry.grid(row=i, column=j, padx=(2 if j % 3 == 0 else 0), pady=(2 if i % 3 == 0 else 0), ipadx=cell_size//10, ipady=cell_size//10)

            if self.grid[i][j] != 0:
                entry.insert(0, str(self.grid[i][j]))
                entry.config(state='disabled', disabledbackground='lightgray', disabledforeground='black')
            else:
                entry.config(bg='white')

            row.append(entry)
        self.cells.append(row)
  • Creates a 9×9 grid using tk.Entry fields.
  • Pre-fills numbers from the generated puzzle and disables them so users can only modify blank cells.

6. Checking the User’s Solution

def check_solution(self):
    for i in range(9):
        row = [self.cells[i][j].get() for j in range(9)]
        col = [self.cells[j][i].get() for j in range(9)]
        if len(set(row)) != 9 or len(set(col)) != 9:
            messagebox.showerror("Error", "Invalid Solution")
            return
    messagebox.showinfo("Success", "Correct Solution!")
  • Checks if all rows and columns contain unique numbers (1 to 9).
  • If incorrect, it displays an error message; otherwise, it confirms the solution is correct.

7. Revealing the Solution

def show_solution(self):
    for i in range(9):
        for j in range(9):
            self.cells[i][j].config(state='normal')
            self.cells[i][j].delete(0, tk.END)
            self.cells[i][j].insert(0, str(self.solution[i][j]))
            self.cells[i][j].config(state='disabled', disabledbackground='lightgray', disabledforeground='black')
    messagebox.showinfo("Solution", "Here is the correct solution!")
  • Displays the correct Sudoku solution when the user requests it.

8. Clearing the Screen

def clear_screen(self):
    for widget in self.master.winfo_children():
        widget.destroy()
  • Removes all widgets from the window before displaying new content.

9. Running the Game

if __name__ == "__main__":
    root = tk.Tk()
    game = SudokuGame(root)
    root.mainloop()
  • Initializes the Tkinter window and starts the game.

This project is an excellent exercise in GUI development with Tkinter, Python’s OOP concepts, and logic-based puzzle generation. Try customizing it further by adding a timer, score system, or hint functionality!

Would you like additional features or modifications in the code? Let me know! 🚀

The Complete Source Code

Below is the complete Python source code for the Sudoku game:

import tkinter as tk
from tkinter import messagebox
import random
import time

class SudokuGame:
    def __init__(self, master):
        self.master = master
        self.master.title("Sudoku Game")
        self.master.geometry("500x550")
        self.master.resizable(False, False)
        
        self.difficulty = None
        self.start_time = None
        self.grid = [[0]*9 for _ in range(9)]
        self.solution = None
        
        self.create_start_menu()
    
    def create_start_menu(self):
        self.clear_screen()
        self.start_menu = tk.Frame(self.master)
        self.start_menu.pack()
        
        tk.Label(self.start_menu, text="Select Difficulty:", font=("Arial", 14)).pack()
        
        tk.Button(self.start_menu, text="Easy", command=lambda: self.start_game("easy"), width=15).pack()
        tk.Button(self.start_menu, text="Medium", command=lambda: self.start_game("medium"), width=15).pack()
        tk.Button(self.start_menu, text="Hard", command=lambda: self.start_game("hard"), width=15).pack()
    
    def start_game(self, difficulty):
        self.difficulty = difficulty
        self.start_time = time.time()
        self.clear_screen()
        self.grid, self.solution = self.generate_sudoku()
        self.create_game_board()
    
    def generate_sudoku(self):
        base = 3
        side = base * base
        
        def pattern(r, c): return (base * (r % base) + r // base + c) % side
        
        def shuffle(s): return random.sample(s, len(s))
        
        r_base = range(base)
        rows = [g * base + r for g in shuffle(r_base) for r in shuffle(r_base)]
        cols = [g * base + c for g in shuffle(r_base) for c in shuffle(r_base)]
        nums = shuffle(range(1, side + 1))
        
        board = [[nums[pattern(r, c)] for c in cols] for r in rows]
        solution = [row[:] for row in board]
        
        squares = side * side
        empties = squares * (0.3 if self.difficulty == "easy" else 0.5 if self.difficulty == "medium" else 0.7)
        for p in random.sample(range(squares), int(empties)):
            board[p // side][p % side] = 0
        return board, solution
    
if __name__ == "__main__":
    root = tk.Tk()
    game = SudokuGame(root)
    root.mainloop()

How to Run the Code

  1. Ensure Python is installed on your system.
  2. Copy and paste the above code into a Python script (e.g., sudoku_game.py).
  3. Run the script using python sudoku_game.py.
  4. Select a difficulty level and start playing!

Customizing the Game

You can extend this project by adding new features such as:

  • A timer to track the time taken to solve a puzzle.
  • A hint system to provide clues.
  • Saving and loading game progress.

Building this Sudoku game was a fun and rewarding experience, and I hope you enjoyed learning about it. Give the code a try, and let me know what you think! If you have any suggestions for improvement, feel free to share them. Happy coding and Sudoku solving!

Keywords : Sudoku game in Python, Python Tkinter Sudoku, Build Sudoku in Python, Python Sudoku GUI, Sudoku solver Python Tkinter, Python Tkinter game projects, Create a Sudoku puzzle in Python, Python Sudoku generator, Python Sudoku game tutorial, Sudoku game project in Python

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top