Spaces:
Sleeping
Sleeping
| import tkinter as tk | |
| from tkinter import messagebox | |
| class SudokuSolver: | |
| def __init__(self, grid): | |
| self.grid = grid | |
| def is_valid(self, row, col, num): | |
| for i in range(9): | |
| if self.grid[row][i] == num: | |
| return False | |
| if self.grid[i][col] == num: | |
| return False | |
| start_row, start_col = 3 * (row // 3), 3 * (col // 3) | |
| for r in range(start_row, start_row + 3): | |
| for c in range(start_col, start_col + 3): | |
| if self.grid[r][c] == num: | |
| return False | |
| return True | |
| def solve_logic(self): | |
| cycles = 0 | |
| while True: | |
| changed = False | |
| for digit in range(1, 10): | |
| for box_row in range(3): | |
| for box_col in range(3): | |
| possible = [] | |
| for r in range(box_row * 3, (box_row + 1) * 3): | |
| for c in range(box_col * 3, (box_col + 1) * 3): | |
| if self.grid[r][c] == 0 and self.is_valid(r, c, digit): | |
| possible.append((r, c)) | |
| if len(possible) == 1: | |
| r, c = possible[0] | |
| self.grid[r][c] = digit | |
| changed = True | |
| cycles += 1 | |
| if not changed: | |
| break | |
| print(f"\n=== Logic Solve Completed After {cycles} Cycle(s) ===") | |
| for row in self.grid: | |
| print(row) | |
| def solve_backtracking(self): | |
| empty = self.find_empty() | |
| if not empty: | |
| return True | |
| r, c = empty | |
| for num in range(1, 10): | |
| if self.is_valid(r, c, num): | |
| self.grid[r][c] = num | |
| if self.solve_backtracking(): | |
| return True | |
| self.grid[r][c] = 0 | |
| return False | |
| def find_empty(self): | |
| for r in range(9): | |
| for c in range(9): | |
| if self.grid[r][c] == 0: | |
| return (r, c) | |
| return None | |
| class SudokuUI: | |
| def __init__(self, root): | |
| self.root = root | |
| self.root.title("Sudoku Solver (Logic + Backtracking)") | |
| self.entries = [[None for _ in range(9)] for _ in range(9)] | |
| self.build_grid() | |
| self.build_buttons() | |
| def build_grid(self): | |
| frame = tk.Frame(self.root) | |
| frame.pack() | |
| for r in range(9): | |
| for c in range(9): | |
| e = tk.Entry(frame, width=2, font=('Arial', 18), justify='center') | |
| e.grid(row=r, column=c, padx=(2 if c % 3 == 0 else 0), pady=(2 if r % 3 == 0 else 0)) | |
| self.entries[r][c] = e | |
| def build_buttons(self): | |
| btn_frame = tk.Frame(self.root) | |
| btn_frame.pack(pady=10) | |
| logic_btn = tk.Button(btn_frame, text="Logic Solve", command=self.logic_solve) | |
| logic_btn.pack(side='left', padx=5) | |
| backtrack_btn = tk.Button(btn_frame, text="Start Backtracking", command=self.backtracking_solve) | |
| backtrack_btn.pack(side='left', padx=5) | |
| clear_btn = tk.Button(btn_frame, text="Clear", command=self.clear) | |
| clear_btn.pack(side='left', padx=5) | |
| def read_grid(self): | |
| grid = [] | |
| print("\n=== Input Grid ===") | |
| for r in range(9): | |
| row = [] | |
| for c in range(9): | |
| val = self.entries[r][c].get() | |
| if val == '': | |
| row.append(0) | |
| else: | |
| try: | |
| num = int(val) | |
| if not (1 <= num <= 9): | |
| raise ValueError | |
| row.append(num) | |
| except ValueError: | |
| messagebox.showerror("Invalid input", f"Invalid number at row {r+1}, col {c+1}") | |
| return None | |
| print(row) | |
| grid.append(row) | |
| return grid | |
| def write_grid(self, grid): | |
| for r in range(9): | |
| for c in range(9): | |
| self.entries[r][c].delete(0, tk.END) | |
| if grid[r][c] != 0: | |
| self.entries[r][c].insert(0, str(grid[r][c])) | |
| def logic_solve(self): | |
| grid = self.read_grid() | |
| if grid is None: | |
| return | |
| solver = SudokuSolver(grid) | |
| solver.solve_logic() | |
| self.write_grid(solver.grid) | |
| def backtracking_solve(self): | |
| grid = self.read_grid() | |
| if grid is None: | |
| return | |
| solver = SudokuSolver(grid) | |
| print("\nStarting backtracking...") | |
| solver.solve_backtracking() | |
| print("\n=== Final Solved Grid ===") | |
| for row in solver.grid: | |
| print(row) | |
| self.write_grid(solver.grid) | |
| def clear(self): | |
| for r in range(9): | |
| for c in range(9): | |
| self.entries[r][c].delete(0, tk.END) | |
| if __name__ == "__main__": | |
| root = tk.Tk() | |
| app = SudokuUI(root) | |
| root.mainloop() | |