1
+ from tkinter import *
2
+
3
+ root = Tk ()
4
+ root .geometry ('275x283' )
5
+
6
+ class SolveSudoku ():
7
+ def __init__ (self ):
8
+ self .allZero ()
9
+ self .startSolution ()
10
+
11
+ # Set the empty cells to 0
12
+ def allZero (self ):
13
+ for i in range (9 ):
14
+ for j in range (9 ):
15
+ if savedNumbers [i ][j ].get () not in ['1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ]:
16
+ savedNumbers [i ][j ].set (0 )
17
+
18
+ # Start the Algorithm
19
+ def startSolution (self , i = 0 , j = 0 ):
20
+ i ,j = self .findNextCellToFill (i , j )
21
+
22
+ # If i == -1 the position is Ok or the Sudoku is Solved
23
+ if i == - 1 :
24
+ return True
25
+ for e in range (1 ,10 ):
26
+ if self .isValid (i ,j ,e ):
27
+ savedNumbers [i ][j ].set (e )
28
+ if self .startSolution (i , j ):
29
+ return True
30
+ # Undo the current cell for backtracking
31
+ savedNumbers [i ][j ].set (0 )
32
+ return False
33
+
34
+ # Search the Nearest Cell to fill
35
+ def findNextCellToFill (self , i , j ):
36
+ for x in range (i ,9 ):
37
+ for y in range (j ,9 ):
38
+ if savedNumbers [x ][y ].get () == '0' :
39
+ return x ,y
40
+
41
+ for x in range (0 ,9 ):
42
+ for y in range (0 ,9 ):
43
+ if savedNumbers [x ][y ].get () == '0' :
44
+ return x ,y
45
+
46
+ return - 1 ,- 1
47
+
48
+ # Check the Validity of savedNumbers[i][j]
49
+ def isValid (self , i , j , e ):
50
+ for x in range (9 ):
51
+ if savedNumbers [i ][x ].get () == str (e ):
52
+ return False
53
+
54
+ for x in range (9 ):
55
+ if savedNumbers [x ][j ].get () == str (e ):
56
+ return False
57
+
58
+ # Finding the Top x,y Co-ordinates of the section containing the i,j cell
59
+ secTopX , secTopY = 3 * int ((i / 3 )), 3 * int ((j / 3 ))
60
+ for x in range (secTopX , secTopX + 3 ):
61
+ for y in range (secTopY , secTopY + 3 ):
62
+ if savedNumbers [x ][y ].get () == str (e ):
63
+ return False
64
+
65
+ return True
66
+
67
+ class Launch ():
68
+ # Set Title, Grid and Menu
69
+ def __init__ (self , master ):
70
+ # Title and settings
71
+ self .master = master
72
+ master .title ("Sudoku Solver" )
73
+
74
+ font = ('Arial' , 18 )
75
+ color = 'white'
76
+
77
+ # Front-end Grid
78
+ self .__table = []
79
+ for i in range (1 ,10 ):
80
+ self .__table += [[0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ]]
81
+
82
+ for i in range (0 ,9 ):
83
+ for j in range (0 ,9 ):
84
+ self .__table [i ][j ]= Entry (master ,width = 2 ,font = font ,bg = color ,cursor = 'arrow' ,borderwidth = 0 ,highlightcolor = 'yellow' ,highlightthickness = 1 ,highlightbackground = 'black' ,textvar = savedNumbers [i ][j ])
85
+ self .__table [i ][j ].bind ('<Motion>' , self .correctGrid )
86
+ self .__table [i ][j ].bind ('<FocusIn>' , self .correctGrid )
87
+ self .__table [i ][j ].bind ('<Button-1>' , self .correctGrid )
88
+ self .__table [i ][j ].grid (row = i , column = j )
89
+
90
+ # Front-End Menu
91
+ menu = Menu (master )
92
+ master .config (menu = menu )
93
+ menu .add_command (label = 'Exit' , command = master .quit )
94
+ menu .add_command (label = 'Solve' , command = self .solveInput )
95
+ menu .add_command (label = 'Clear' , command = self .clearAll )
96
+
97
+ # Correct the Grid if inputs are uncorrect
98
+ def correctGrid (self , event ):
99
+ for i in range (9 ):
100
+ for j in range (9 ):
101
+ if savedNumbers [i ][j ].get () == '' :
102
+ continue
103
+ if len (savedNumbers [i ][j ].get ()) > 1 or savedNumbers [i ][j ].get () not in ['1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ]:
104
+ savedNumbers [i ][j ].set ('' )
105
+
106
+ # Clear the Grid
107
+ def clearAll (self ):
108
+ for i in range (9 ):
109
+ for j in range (9 ):
110
+ savedNumbers [i ][j ].set ('' )
111
+
112
+ # Calls the class SolveSudoku
113
+ def solveInput (self ):
114
+ solution = SolveSudoku ()
115
+
116
+ # Global Matrix where are stored the numbers
117
+ savedNumbers = []
118
+ for i in range (1 ,10 ):
119
+ savedNumbers += [[0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ]]
120
+ for i in range (0 ,9 ):
121
+ for j in range (0 ,9 ):
122
+ savedNumbers [i ][j ] = StringVar (root )
123
+
124
+ app = Launch (root )
125
+ root .mainloop ()
0 commit comments