-
Notifications
You must be signed in to change notification settings - Fork 1
/
GUI_v2.py
215 lines (155 loc) · 8.97 KB
/
GUI_v2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
from tkinter import*
from math import sqrt
class Sudoku:
def __init__(self, root,dic,size,squareDim=35):
#coordenadas por defecto al inicializar
self.cordx = 10
self.cordy = 10
#clases como atributos
self.dic = dic
self.game = root
self.table = Canvas(root, height= squareDim*size + 20, width=squareDim*size + 20)
#variables clave para construir la GUI
self.sz = size #nxn sudoku (tamaño)
self.squaredim = squareDim #ancho y alto del cuadrado
self.numRange = "" #string con el rango de números validos
for i in range(1,size+1):
self.numRange += str(i)
#funciones que son corridas una sola vez
self.createGrid(size, squareDim) #creacion de la rejilla del juego
self.table.pack()
self.solve = Button(root, text = "Solve", command = self.solveSudoku) #boton para solucionar el sudoku
self.solve.pack()
self.solve = Button(root, text = "Clear all", command = self.clearCells) #boton de refrescar sudoku
self.solve.pack()
#eventos a los que la interfaz está atenta
self.table.bind('<Button-1>', self.click) #click izq
self.game.bind('<Key>', lambda ev: self.keypressed(ev, "write")) #cualquier tecla
self.game.bind('<Delete>', lambda ev: self.keypressed(ev, "supr")) #boton de 'supr'
self.game.bind('<BackSpace>', lambda ev: self.keypressed(ev, "del")) #boton de 'del'
def createGrid(self, sz, squaredim):
"""estos dos primeros for se encargan de crear la rejilla de filas"""
for i in range (0, int(sqrt(sz)) + 1): # (int(sqrt(sz)) + 1
x0 = 10 #(margen)
y0 = (10 + squaredim*int(sqrt(sz))*i) #(alto de cuadrado) * (no. cuadrados por subregión) * (iteración) + margen
x1 = ( squaredim*sz +10 ) #(ancho de cuadrado) * (no. cuadrados por fila) + margen
y1 = y0 #(misma posición en y0)
self.table.create_line( x0, y0, x1, y1, width=2.5)
if(i!= int(sqrt(sz))):
for i2 in range(0, int(sqrt(sz))): # (int(sqrt(sz)) - 1) + 1
y2 = squaredim*i2
self.table.create_line( x0, y0+y2, x1, y0+y2, width = 1.25)
"""estos dos for se encargan de crear la rejilla de columnas"""
for i in range (0, int(sqrt(sz)) + 1): # (int(sqrt(sz)) + 1
x0 = ( 10 + i*squaredim*sqrt(sz) ) # (ancho del cuadrado) * (no. cuadrados por subregión)* (iteración) + margen
x1 = x0 # (misma posicion de x0)
y0 = 10 # (margen)
y1 = (10 + squaredim*sz) # (alto del cuadrado) * (no. cuadrados por columna) + (margen)
self.table.create_line( x0, y0, x0, y1, width=2.5)
if(i!= int(sqrt(sz))):
for i2 in range(0, int(sqrt(sz))): # (int(sqrt(sz)) - 1) + 1
x2 = squaredim*i2
self.table.create_line( x0 + x2, y0, x0 + x2, y1, width = 1.25)
def click(self, event):
posx = int( (event.x - 10)/self.squaredim ) + 1 #encuentra el indice(int) en x de la casilla clicada
posy = int( (event.y - 10)/self.squaredim ) + 1 #encuentra el indice(int) en y de la casilla clicada
#desde (1,1) hasta (n,n)
cond1 = ((event.x - 10) > 0) and ((event.y - 10) > 0) #si no está cliclando en los margenes
cond2 = (1<= posx <=self.sz) and (1<= posy <=self.sz) #Si está clicando en una de las casillas del sudoku
if ( cond1 and cond2 ):
#print("Todo en orden -> ", "casilla: ", "(" , posx , "," , posy ,")")
#sobreescritura de valores de posiciones 'cordx', 'cordy'
#lo cual permite tomar entradas de numeros desde el teclado y modificar la interfaz
self.cordx = posx
self.cordy = posy
#ejecuta funcion que marca en rojo la casilla clicada
self.clickedOnCell()
else:
print("click no válido")
def keypressed(self, event, operation):
"""recibe la <key> input y analiza si es una input válida para el juego o no
y ejecuta los comandos necesarios en caso de ser una input válida"""
if (operation=="del" or operation == "supr"):
"""****punto de conexión con la estructura de datos****"""
self.dic.valueWrite( self.cordx-1, self.cordy -1 )
#print("borrado en el dict")
self.writeinGUI("del")
elif (event.char in self.numRange):
"""****punto de conexión con la estructura de datos****"""
self.dic.valueWrite(self.cordx-1, self.cordy -1, int(event.char)- 1 )
#print("escritura en el dict en:", "casilla: ", "(" , self.cordx , "," , self.cordy, ")", event.char, operation)
#ejecuta funcion que marca el numero seleccionado
self.writeinGUI(event.char)
else:
print("por favor ingrese valores válidos")
def writeinGUI(self,order):
#busca la coordenada x y y del punto medio de la celda clicada por última vez
x = ( 10 + (self.cordx * self.squaredim) - (self.squaredim)/2 )
y = ( 10 + (self.cordy * self.squaredim) - (self.squaredim)/2 )
print("coordenada x=",int(x/self.squaredim) + 1, "coordenada y=",int(y/self.squaredim) + 1 ,"numer0 =", order)
#identificador del texto que va a ser creado
tag = str(x) + str(y) #misteriosamente si se cambia el tag todo falla
if (order == "del"):
self.table.delete(tag)
else:
self.table.delete(tag)
self.table.create_text( x, y, text=order, tag=tag, fill="black", activefill="blue", font=("Arial", 16) )
def clickedOnCell(self):
"""funcion que encierra un recuadro cuando es clicado"""
self.table.delete("cellclicked")
#coordenadas del recuadro que se va a dibujar
x1 = 10 + (self.cordx * self.squaredim)
x0 = 10 + ( (self.cordx - 1) * self.squaredim)
y1 = 10 + (self.cordy * self.squaredim)
y0 = 10 + ( (self.cordy - 1) * self.squaredim)
#dibujo del recuadro que indica click
self.table.create_rectangle(x0, y0, x1, y1, outline= "blue", tags="cellclicked")
def solveSudoku(self):
"""****punto de conexión con la estructura de datos****"""
#[antes de eso necesito una función que me envie una lista de listas con la tupla (x,y) y el numero]
#[ ((x,y), NUM), ((x,y), NUM)]
print("solving... this can take a while... :)")
solution , A = self.dic.solve()
if solution != []:
for numAndCoord in solution:
coord = numAndCoord[0]
num = numAndCoord[1] +1
self.cordx = coord[0] + 1
self.cordy = coord[1] + 1
self.writeinGUI(num)
else:
print("El sudoku no tiene una solucion para este caso")
if A == "Satisfacible":
A = '¡¡' + "Satisfiable" + '!!'
self.solve = Label(self.game, text=A , fg="Green" ).pack()
else:
A = '¡¡' + "Unsatisfiable" + '!!'
self.solve = Label(self.game, text=A , fg="Red" ).pack()
def clearCells(self):
"""****punto de conexión con la estructura de datos****"""
for i in range(1, self.sz+1):
x = ( 10 + (i * self.squaredim) - (self.squaredim)/2 )
for j in range(1, self.sz+1):
y = ( 10 + (j * self.squaredim) - (self.squaredim)/2 )
tag = str(x) + str(y) #misteriosamente si se cambia el tag todo falla
self.table.delete(tag)
self.dic.clearData()
class StartWindows():
def __init__(self, root):
self.root = root
self.size = -1
self.startMenu()
def startMenu(self):
self.root.title("Sudoku solver")
self.root.geometry("400x325")
Label(self.root, text= "What sudoku size do you want?",font=("Agency FB", 18)).pack()
Label(self.root, text= ' ',font=("Agency FB", 18)).pack()
Button(self.root, text="2 x 2",command= lambda: self.endStart(4), font=("Agency FB", 18)).pack()
Button(self.root, text="3 x 3",command= lambda: self.endStart(9), font=("Agency FB", 18)).pack()
Label(self.root, text= ' ',font=("Agency FB", 18)).pack()
Label(self.root, text= 'Remember:',font=("Agency FB", 18)).pack()
Label(self.root, text= 'Run "Guardar_reglas_2x2.py" to use 2x2 sudoku',font=("Agency FB", 18)).pack()
Label(self.root, text= 'Run "Guardar_reglas_3x3.py" to use 3x3 sudoku',font=("Agency FB", 18)).pack()
def endStart(self,sz):
self.size = sz
self.root.destroy()