Mar-30-2018, 08:26 PM
(This post was last modified: Mar-30-2018, 08:26 PM by Gribouillis.)
I made it work by using the active state recipe, which I saved verbatim as a file
tkcallasync.py
. Then I changed your code a little in a file solvesudo.py
# solvesudo.py sudoku = [[' ',' ',' ','2','1',' ',' ',' ',' '], [' ',' ','7','3',' ',' ',' ',' ',' '], [' ','5','8',' ',' ',' ',' ',' ',' '], ['4','3',' ',' ',' ',' ',' ',' ',' '], ['2',' ',' ',' ',' ',' ',' ',' ','8'], [' ',' ',' ',' ',' ',' ',' ','7','6'], [' ',' ',' ',' ',' ',' ','2','5',' '], [' ',' ',' ',' ',' ','7','3',' ',' '], [' ',' ',' ',' ','9','8',' ',' ',' ']] def printSUDOKU(matrix): for row in range(9): print("|-----------------------------------|") for col in range(9): print("| " + matrix[row][col] + " ",end='') print("|") print("|-----------------------------------|") def consistent(matrix, row, col, value): for i in range(9): if matrix[row][i]==value: return False if matrix[i][col]==value: return False rowStart = row - row%3 colStart = col - col%3 for m in range(3): for k in range(3): if matrix[rowStart+k][colStart+m]==value: return False return True class SolutionFound(Exception): pass def wsolve(sudoku): try: solve(sudoku, 0) except SolutionFound: return True return False def solve(sudoku, num): if num==81: raise SolutionFound return True else: row = int(num / 9) col = num % 9 if sudoku[row][col]!=' ': solve(sudoku, num+1) else: for value in range(1,10): if consistent(sudoku, row, col, str(value)): sudoku[row][col] = str(value) if solve(sudoku, num+1): return True sudoku[row][col]=' ' return False if __name__ == '__main__': printSUDOKU(sudoku) solve(sudoku, 0)Finally, I wrote a small tkinter code,
tksudo.py
, similar to the example in the active state recipe# tksudo.py from tkinter import Tk, Frame, Entry, Label, Button, IntVar, StringVar, LEFT from tkinter import messagebox from tkcallasync import tk_call_async, MULTIPROCESSING import solvesudo def do_solve(sudoku): status = solvesudo.wsolve(sudoku) return status, sudoku disabled = False def execute_solver(): global disabled if disabled: messagebox.showinfo("warning", "It's still calculating...") return def callback(result): global disabled disabled = False status, sudoku = result solvesudo.printSUDOKU(sudoku) result_var.set('Found!' if status else 'Not Found!') disabled = True tk_call_async(root, do_solve, args=(solvesudo.sudoku,), callback=callback, method=MULTIPROCESSING) root = Tk() row = Frame(root) row.pack() Button(row, text="Solve Sudoku", command =execute_solver).pack(side=LEFT) Button(row, text="It's responsive", command= lambda: messagebox.showinfo("info", "it's responsive")).pack(side=LEFT) result_var = StringVar() Label(root, textvariable=result_var).pack() root.mainloop()The result is that it works very well (in linux), and the small GUI remains responsive while the peer process computes the solution.
Output:λ python3 tksudo.py
|-----------------------------------|
| 6 | 4 | 3 | 2 | 1 | 5 | 8 | 9 | 7 |
|-----------------------------------|
| 1 | 2 | 7 | 3 | 8 | 9 | 6 | 4 | 5 |
|-----------------------------------|
| 9 | 5 | 8 | 7 | 6 | 4 | 1 | 2 | 3 |
|-----------------------------------|
| 4 | 3 | 5 | 8 | 7 | 6 | 9 | 1 | 2 |
|-----------------------------------|
| 2 | 7 | 6 | 9 | 5 | 1 | 4 | 3 | 8 |
|-----------------------------------|
| 8 | 9 | 1 | 4 | 3 | 2 | 5 | 7 | 6 |
|-----------------------------------|
| 7 | 8 | 9 | 6 | 4 | 3 | 2 | 5 | 1 |
|-----------------------------------|
| 5 | 6 | 4 | 1 | 2 | 7 | 3 | 8 | 9 |
|-----------------------------------|
| 3 | 1 | 2 | 5 | 9 | 8 | 7 | 6 | 4 |
|-----------------------------------|