【发布时间】:2020-04-18 23:44:46
【问题描述】:
我最近成功编写了一个递归代码,它使用回溯来解决一个简单的数独难题。我想创建它,以便我实时解决难题,即数字实时变化,并希望使用 tkinter 模块来做到这一点。我创建了一个 9*9 的板,每个数字都作为一个特定的标签,并将标签的文本存储在 StringVar() 中,这样我就可以不断更新它。所有的 StringVar 都存储在一个 9*9 数组(称为 textvars)中,因此它们对应于我想要解决的原始数独板,因此我可以使用行号和列号来更新文本。以下是这部分的代码:
def main():
textvars = []
t1 = []
board = [[3, 0, 6, 5, 0, 8, 4, 0, 0],
[5, 2, 0, 0, 0, 0, 0, 0, 0],
[0, 8, 7, 0, 0, 0, 0, 3, 1],
[0, 0, 3, 0, 1, 0, 0, 8, 0],
[9, 0, 0, 8, 6, 3, 0, 0, 5],
[0, 5, 0, 0, 9, 0, 6, 0, 0],
[1, 3, 0, 0, 0, 0, 2, 5, 0],
[0, 0, 0, 0, 0, 0, 0, 7, 4],
[0, 0, 5, 2, 0, 6, 3, 0, 0]]
for i in range(9):
t1 = []
for j in range(9):
txt = StringVar()
if board[i][j]==0:
txt.set('')
else:
txt.set(str(board[i][j]))
Label(root,height = 2, width = 4, textvariable = txt, relief = "solid").grid(row = i, column = j)
t1.append(txt)
textvars.append(t1)
solve_board(board, textvars)
这些文本变量和板被传递给使用回溯的 solve_board() 函数,当更新板时,它使用 .set() 函数更新文本,如下所示:
def solve_board(board,textvars):
for rowno in range(9):
for colno in range(9):
if board[rowno][colno] == 0:
for i in range(1,10):
if (is_valid(board,rowno,colno,i)):
board[rowno][colno]=i
textvars[rowno][colno].set(str(i))
solve_board(board,textvars)
board[rowno][colno]=0
textvars[rowno][colno].set('')
return False
print (np.matrix(board))
所有与 gui 或 tkinter 无关的位都可以完美地工作,尽管它们是匆忙输入的,导致代码不是最优的。
运行此代码时,tkinter 窗口上显示的板是未解决的板,而正在打印的板已完全解决。
我希望你能帮助我弄清楚为什么这段代码不起作用,我附上了其余的代码、一个 is_valid 函数和一个主要的函数,以供进一步参考。谢谢。
def is_valid(b,r,c,n): #check if number insertion is valid
if n in b[r]: #if in row
return False
for x in range(0,9):
if n == b[x][c]: #check for column
return False
sr = r - r%3
sc = c - c%3
for x in range(sr,sr+3):
for y in range(sc,sc+3):
if b[x][y]==n:
return False
return True
if __name__ == "__main__":
root = Tk()
root.title("Sudoku")
main()
root.mainloop()
编辑:
代码:
board[rowno][colno]=0
textvars[rowno][colno].set('')
这用于反映回溯过程,即如果做出的选择不正确,程序会返回上次做出选择的时间,并通过将其设置为 0 来重置选择。将文本设置为 '' 是只是为了反映重置使我的程序在 tkinter 窗口中。
【问题讨论】:
-
我也尝试将所有标签存储在另一个数组中,输出相同。
-
我认为你需要把
t1 = []放在for j in range(9)之前。 -
哦,是的,我的错!我忘了说 - 它解决了顶行从输出中消失但标签仍然没有在 tkinter 窗口中更新的问题,并且在我打印的电路板解决时显示的电路板仍未解决!
-
我认为这是因为您在内部
if块的末尾调用了textvars[rowno][colno].set('')。尝试删除该行。 -
最好更新
StringVar末尾的solve_board()。
标签: python user-interface tkinter tk sudoku