diff --git a/UI.py b/UI.py index 633b797..e10f194 100644 --- a/UI.py +++ b/UI.py @@ -7,6 +7,7 @@ # -*- encoding: utf-8 -*- import tkinter as tk +from pprint import pprint from tkinter import * from data import * import time @@ -26,7 +27,7 @@ GREY = '#808080' GREYLESS = '#CCCCCC' -BC = 40 +side = 40 # 构建主窗口 width, height = 840, 610#设置长宽 @@ -35,16 +36,17 @@ root.title("数独")#设置窗口标题 root.config(bg=BLACK)#设置背景 root.geometry(f'{width}x{height}')#设置窗口大小 root.resizable(0, 0) # 防止用户调整尺寸 -cv = tk.Canvas(root, bg=WHITE, bd=2, relief="sunken", width=width, height=height, background=ORANGE, - borderwidth=0, highlightthickness=0)#设置画布 -cv.place(x=0, y=0, anchor=NW)#设置画布位置 +canvas = tk.Canvas(root, bg=WHITE, bd=2, width=width, height=height, background=ORANGE, + highlightthickness=0)#设置画布 -bc = 40 +canvas.place(x=0, y=0, anchor=NW)#设置画布位置 + +side = 40 """文字框""" -top_x = (bc + 3) * 11 # 文本框顶点x +top_x = (side + 3) * 11 # 文本框顶点x top_y = 50 # 文本框顶点y -bc_x = (bc + 3) * 7 + 20 # 文本框宽度 -bc_y = (bc + 3) * 12 # 文本框高度 +bc_x = (side + 3) * 7 + 20 # 文本框宽度 +bc_y = (side + 3) * 12 # 文本框高度 right = tk.Frame(root, bg=WHITE, relief="sunken", width=bc_x, height=bc_y) right.place(x=top_x, y=top_y, anchor=NW) # 右边栏 @@ -93,10 +95,10 @@ class MyTimer: self.min.set(now // 60) self.sec.set(now - self.min.get() * 60) -def rect_draw(bc, row, col): +def rect_draw(side, row, col): ''' 绘制一个方格 - :param bc: 方格大小 + :param side: 方格边长 :param row: 行 :param col: 列 :return: @@ -108,9 +110,32 @@ def rect_draw(bc, row, col): color = "#FAE067" else: color = 'white' - cv.create_rectangle(row * (bc + 3) + 50, col * (bc + 3) + 50, row * (bc + 3) + 50 + bc, col * (bc + 3) + 50 + bc, - fill=color, width=0) # 绘制一个方格 + canvas.create_rectangle(row * (side + 3) + 50, col * (side + 3) + 50, row * (side + 3) + 50 + side, col * (side + 3) + 50 + side, + fill=color, width=0) # 绘制一个方格 +def draw_all_rect(): + """ + 左上角开始 + :param left_x: + :param top_y: + :return: + """ + for i in range(9): + for n in range(9): + rect_draw(side, i, n) + + +martix_position_mapping = dict() +def creat_martix_mapping(side): + mapping_dict = dict() + offeset_x = 50 + side = side + 3 + for i in range(9): # 坐标映射 + for n in range(9): + x = side *i+offeset_x + y = side *n+offeset_x + mapping_dict[n, i] = [x, y] + return mapping_dict def show_Time(timer: MyTimer): ''' @@ -125,10 +150,10 @@ def show_Time(timer: MyTimer): Sec = tk.Label(right, textvariable=timer.sec, bg=WHITE, fg=BLACK, font=('幼圆', 16, 'bold')) # 秒钟计数 Sec.place(x=220, y=30, width=30, height=30) -def num_draw(bc, row, col, martix, u_martix): +def num_draw(side, row, col, martix, u_martix): ''' 绘制方格中的数字 - :param bc: 方格大小 + :param side: 方格大小 :param row: 行 :param col: 列 :param martix: 原矩阵 @@ -145,10 +170,8 @@ def num_draw(bc, row, col, martix, u_martix): else: color = 'purple' # 用户填的数字的颜色 if martix[row, col] != 0 or u_martix[row, col] != 0: #如果该格子有数据要显示 - cv.create_text(col * (bc + 3) + 50 + bc / 2, row * (bc + 3) + 50 + bc / 2, - text=f"{u_martix[row, col]}", font=('幼圆', 18, 'bold'), fill=color) - - + canvas.create_text(col * (side + 3) + 50 + side / 2, row * (side + 3) + 50 + side / 2, + text=f"{u_martix[row, col]}", font=('幼圆', 18, 'bold'), fill=color, tags="num") def Difficulty(empty): @@ -191,9 +214,6 @@ def seq_recode(right, STEP): - - - def empty(u_martix): count = 0 # 计数 for i in range(9): @@ -224,15 +244,30 @@ if __name__ == "__main__": [0, 2, 8, 0, 5, 1, 0, 6, 9], [0, 1, 3, 0, 6, 0, 7, 4, 8], [0, 5, 0, 4, 0, 0, 0, 1, 2]]) - # text_enter(BC) + # text_enter(side) # time1.start() # 计时开始 - # draw((5, 5),M,u_M) - + # draw((5, 5),M,u_martix) - BC = 40 + side = 40 def left1(event): print(event.x, event.y) - cv.bind('', left1) + x = event.x + y = event.y + for key, posit_lt in martix_position_mapping.items(): + if posit_lt[0] < x < posit_lt[0]+side and posit_lt[1] < y < posit_lt[1]+side: + print(key) + canvas.bind('', left1) + draw_all_rect() + martix_position_mapping = creat_martix_mapping(side) + seq_recode(right,[]) + + time1 = MyTimer() # 实例计时器 + show_Time(time1) + + emp = empty(u_M) + Difficulty(emp) + noter(True) + mainloop() \ No newline at end of file diff --git a/hello.py b/hello.py new file mode 100644 index 0000000..00950d9 --- /dev/null +++ b/hello.py @@ -0,0 +1 @@ +print('hello world') \ No newline at end of file diff --git a/new_UI.py b/new_UI.py new file mode 100644 index 0000000..9756aa5 --- /dev/null +++ b/new_UI.py @@ -0,0 +1,1108 @@ +# -*- encoding: utf-8 -*- +""" +@File : new_UI.py +@License : (C)Copyright 2021-2023 + +@Modify Time @Author @Version @Description +------------ ------- -------- ----------- +2023/10/11 16:14 zart20 1.0 None +""" +import re +import time +import tkinter as tk +from pprint import pprint +from tkinter import scrolledtext +from typing import List + +import data +from data import * + +BLACK = "#000000" +HINT = '#6D2DFA' +SILVER = '#FFFFFF' +u_NUMBER = '#6D2DFA' +WHITE = "#FFFFFF" +ORANGE = '#FF8C00' +RED = "#C80000" +YELLOW = "#FAE067" +GREY = '#808080' +GREYLESS = '#CCCCCC' + +martix_position_mapping = dict() +side = 40 # 方格边长 +# martix = np.load("martix.npy") + +quest = [[0, 1, 0, 8, 5, 2, 0, 6, 9], + [0, 6, 5, 7, 9, 3, 0, 0, 0], + [9, 0, 8, 0, 0, 4, 0, 5, 7], + [0, 7, 2, 4, 3, 0, 9, 0, 0], + [6, 0, 9, 2, 0, 8, 1, 3, 0], + [0, 8, 0, 1, 0, 0, 0, 2, 5], + [7, 9, 1, 5, 2, 6, 8, 4, 3], + [5, 4, 0, 9, 0, 1, 6, 7, 2], + [8, 0, 0, 3, 4, 7, 0, 0, 0]] + +martix = np.array(quest) + +u_martix = martix.copy() +info_labels = [] # label对象列表 +note_mark = False # 笔记标志 +all_hint_mark = False # 一键笔记标记 +STEP = [] # 回撤存储列表 +wait_time = 0.1 # 运行阻滞时间 +set_question_mark = False # 手动修改数组标志 +running = True # 运行状态 +r_step = list() # 单步记录列表 +hint_mark = None # 提示状态 +possible_num_mark = False # 手动预期功能标志 + +row = None +col = None + + +def creat_note_dict(): + usr_note_dict = dict() + for i in range(9): + for n in range(9): + usr_note_dict[i, n] = set() + return usr_note_dict + + +usr_note_dict = creat_note_dict() # 记录对应单元格笔记数字 + + +def creat_martix_mapping(side): + mapping_dict = dict() + offeset_x = 50 + side = side + 3 + for i in range(9): # 坐标映射 + for n in range(9): + x = side * i + offeset_x + y = side * n + offeset_x + mapping_dict[n, i] = [x, y] + return mapping_dict + + +mapping = creat_martix_mapping(side) + + +class MyTimer: + # 计时器 + def __init__(self, root): + self.root = root + self.elapsed = 0.0 + self.running = False + self.last_start_time = None + self.timestr = tk.IntVar() # 创建可变数据类型 + self.min = tk.IntVar() # 创建可变数据类型 + self.sec = tk.IntVar() # 创建可变数据类型 + self.timestr.set(0) # 只能数值不能等于号 + + self.starttime = 0 # 开始计时时间 + self.elapsedtime = 0.0 # 计时器统计到的时间 + self.timer = None + self.starttime = time.time() - self.elapsedtime + self.update() + self.win = 0 + + def update(self): + self.elapsedtime = int(time.time() - self.starttime) + self.timestr.set(self.elapsedtime) + self.min.set(self.elapsedtime // 60) + self.sec.set(self.elapsedtime - self.min.get() * 60) + self.timer = self.root.after(100, self.update) + + def restart(self): + self.win = 0 + self.elapsedtime = 0.0 + self.starttime = time.time() - self.elapsedtime + self.update() + + def stop(self): + if self.win: + pass + else: + self.win = 1 + self.root.after_cancel(self.timer) + self.elapsedtime = int(time.time() - self.starttime) + now = int(time.time() - self.starttime) + self.timestr.set(now) + self.min.set(now // 60) + self.sec.set(now - self.min.get() * 60) + + +def draw_all_rect(canvas): + rect_mapping = dict() + block_color = [3, 4, 5] # 显色宫格依据 + for row in range(9): + for col in range(9): + logi_row = row in block_color and col in block_color # 显色逻辑 + logi_col = row in block_color or col in block_color # 显色逻辑 + if not logi_row and logi_col: + color = "#FAE067" + else: + color = 'white' + x, y = mapping[row, col] + rect = canvas.create_rectangle(x, y, x + side, y + side, fill=color, width=0) # 绘制一个方格 + rect_mapping[row, col] = rect + return rect_mapping + + +def draw_info(canvas): + top_x = (side + 3) * 11 # 文本框顶点x + top_y = 50 # 文本框顶点y + bc_x = (side + 3) * 7 + 20 # 文本框宽度 + bc_y = (side + 3) * 12 # 文本框高度 + + info = tk.Frame(canvas, bg=WHITE, relief="sunken", width=bc_x, height=bc_y) + info.place(x=top_x, y=top_y, anchor=tk.NW) # 右边栏 + info_labels.append(info) + return info + + +# def label_destroy_info(labels: list[tk.Label], canvas): +# """销毁label""" +# for label in labels: +# label.destroy() +# draw_info(canvas) + +def label_destroy_info(labels: List[tk.Label], canvas): + """销毁label""" + for label in labels: + label.destroy() + draw_info(canvas) + +def show_Time(right: tk.Frame, timer: MyTimer): + ''' + 显示计时器 + :param timer:计时器示例 + :return: + ''' + Time = tk.Label(right, text="运行时间: 分 秒", bg=WHITE, fg=BLACK, font=('幼圆', 16, 'bold'), anchor=tk.W) + Time.place(x=30, y=30, width=340, height=30) + Min = tk.Label(right, textvariable=timer.min, bg=WHITE, fg=BLACK, font=('幼圆', 16, 'bold')) # 分钟计数 + Min.place(x=150, y=30, width=30, height=30) + Sec = tk.Label(right, textvariable=timer.sec, bg=WHITE, fg=BLACK, font=('幼圆', 16, 'bold')) # 秒钟计数 + Sec.place(x=220, y=30, width=30, height=30) + info_labels.append(Time) + info_labels.append(Min) + info_labels.append(Sec) + + +def difficulty(): + """ + 难度显示: + :param empty: 原始空格数目 + :return: + """ + count = 0 # 计数 + for i in range(9): + for j in range(9): + if martix[i][j] == 0 or martix[i][j] == 10: + count += 1 + Level = tk.Label(info, text="难度:{:.2f}".format(count / 81), bg=WHITE, fg=BLACK, font=('幼圆', 16, 'bold'), + anchor=tk.W) + Level.place(x=30, y=60, width=300, height=30) + info_labels.append(Level) + + +def noter(): + ''' + 显示笔记提示 + :param mark: 笔记模式是否开启 + :return: + ''' + note_help1 = tk.Label(info, text=f"False 时保存笔记,当前笔记:{note_mark}", bg=WHITE, fg=RED, + font=('幼圆', 12, 'bold'), anchor=tk.W) + note_help1.place(x=30, y=90, width=300, height=30) + info_labels.append(note_help1) + + +def seq_recode(): + ''' + 显示步骤 + ''' + note_help1 = tk.Label(info, text=f"步骤记录:", bg=WHITE, fg=RED, font=('幼圆', 12, 'bold'), anchor=tk.W) + note_help1.place(x=30, y=120, width=300, height=30) + scr = scrolledtext.ScrolledText(info, fg='red', font=('幼圆', 16, 'bold')) # 设置一个可滚动文本框 + scr.place(x=30, y=150, width=280, height=300) # + + for i in range(len(STEP)): + scr.insert('end', f"{i + 1} {STEP[i][:2]}\n") # 末尾插入 + scr.config(state=tk.DISABLED) # 设置文本框为 “不能编辑” + scr.see(tk.END) # 将视图移到末尾 + + info_labels.append(note_help1) + info_labels.append(scr) + + +def basics_info(): + difficulty() + noter() + seq_recode() + + +def draw_one_num(x, y, num, color="black", tags=None): + """显示一个数字""" + if num != 0: + canvas.create_text(x + side / 2, y + side / 2, text=num, + font=('幼圆', 18, 'bold'), fill=color, tags=tags) + + +def show_usr_num(): + """显示所有用户数字""" + canvas.delete("usr_input") + canvas.delete("usr_num") + for row in range(9): + for col in range(9): + if martix[row, col] == 0: + x, y = mapping[row, col] + draw_one_num(x, y, u_martix[row, col], "blue", tags="usr_num") + if all_hint_mark: + show_all_hint() + +def show_fixa_num(): + """显示固定数字""" + canvas.delete("fixa_num") + canvas.delete("set_fixa_num") + for i in range(9): + for n in range(9): + x, y = mapping[i, n] + draw_one_num(x, y, martix[i, n], tags="fixa_num") + + +def show_set_all_num(): + global set_martix + canvas.delete("fixa_num") + canvas.delete("set_fixa_num") + for i in range(9): + for n in range(9): + x, y = mapping[i, n] + draw_one_num(x, y, set_martix[i, n], tags="set_fixa_num") + + +def click_event(event): + print(event.x, event.y) + global row, col, set_martix, cell_info_label # 全局坐标映射,方便其他功能知道操作单元格 + x = event.x + y = event.y + for key, posit_lt in mapping.items(): + if posit_lt[0] < x < posit_lt[0] + side and posit_lt[1] < y < posit_lt[1] + side: + row, col = key[0], key[1] + if set_question_mark: + set_martix[row, col] = 0 + show_set_all_num() + else: + draw(row, col) + print(key) + if possible_num_mark: + if row >= 0: + if cell_info_label: + # cell_info_label = tk.Label(info, text=f"当前选中单元格:{row}-{col}", bg=WHITE, font=("幼圆", 12, "bold")) + cell_info_label.config(text=f"当前选中单元格:{row}-{col}") + lebel_width = cell_info_label.winfo_reqwidth() + x = 160 + x = x - lebel_width / 2 + cell_info_label.place(x=x, y=105, ) + else: + if cell_info_label: + cell_info_label.config(text=f"请选中一个单元格以开始实验") + lebel_width = cell_info_label.winfo_reqwidth() + x = 160 + x = x - lebel_width / 2 + cell_info_label.place(x=x, y=105, ) + + +def draw_mini_num(row, col, possible: set, color: str, tags="mini_num"): + hint_bc = int(side // 3) # 小数字的间距 + x, y = mapping[row, col] + x, y = x + side / 2, y + side / 2 # 计算大方格中点坐标 + x = x - hint_bc # 计算左上角第一个数字坐标 + y = y - hint_bc # 计算左上角第一个数字坐标 + for ii in range(3): # 按照九宫格显示小数字 + for jj in range(3): + n = ii * 3 + jj + 1 # 遍历1~9 + if len(possible) != 0: # 在用户已填的部分有可能导致部分格子无解,所以先加一个判断 + for k in possible: + if n == k: # 如果possible[row][col]中含有k,则说明该格子可以填k,则将k显示在方格中 + canvas.create_text(x + ii * hint_bc, y + jj * hint_bc, + text=f"{n}", font=('hei', 12, "bold"), fill=color, tags=tags) + + +def hint_on_off(): + global hint_mark + if hint_mark == None: + show_hint() + hint_mark = 1 + else: + canvas.delete("one_hint") + hint_mark = None + + +def show_hint(): + """提示""" + global row, col + tags = "one_hint" + canvas.delete(tags) + if row != None and u_martix[row, col] == 0: + possible = GetPossible(u_martix, row, col) + draw_mini_num(row, col, possible, "green", tags) + + +def all_note_on_off(): + """一键笔记控制""" + global all_hint_mark + if not all_hint_mark: + show_all_hint() + all_hint_mark = True + else: + canvas.delete("mini_num") + all_hint_mark = False + + +def show_all_hint(): + """一键笔记""" + canvas.delete("mini_num") + for row in range(9): + for col in range(9): + if set_question_mark: + if set_martix[row, col] == 0: + possible = GetPossible(set_martix, row, col) + draw_mini_num(row, col, possible, "grey") + else: + if u_martix[row, col] == 0: + possible = GetPossible(u_martix, row, col) + draw_mini_num(row, col, possible, "grey") + + +def note_on_off(): + global note_mark, usr_note_dict + if not note_mark: + note_mark = True + else: + note_mark = False + noter() + + +def number_button(root): + ''' + 绘制数字按钮 + :param side: 全局按钮大小 + :return: + ''' + for i in range(9): # 遍历0~9 + top_x, top_y = i * (side + 3) + 50, 12 * (side + 3) + 10 # 计算每个按钮左上角坐标 + B = tk.Button(root, text=f"{i + 1}", bg='white', fg='black', + font=('幼圆', 14, 'bold'), command=lambda num=i + 1: usr_input(row, col, num)) + B.place(x=top_x, y=top_y, width=side + 3, height=side + 3) # 绘制按钮到图上 + + +def control_button(root, side): + ''' + 绘制五个控制按键 + :param side:全局按钮大小 + :return: + ''' + global loca, loca_o + lon = 9 * (side + 3) + 50 + lon = lon // 5 - 12 # 控制按键长度 + ctl = ["撤回", "擦除", "笔记", "一键笔记", "提示"] + # 撤回 + B1 = tk.Button(root, text=f"撤回", bg='white', fg='black', + font=('幼圆', 12, 'bold'), command=backspace) + B1.place(x=(lon + 2) * 0 + 50, y=(side + 3) * 11 + 8, width=lon, height=side) + # 擦除 + B2 = tk.Button(root, text=f"擦除", bg='white', fg='black', + font=('幼圆', 12, 'bold'), command=delete_ctrl) + B2.place(x=(lon + 2) * 1 + 50, y=(side + 3) * 11 + 8, width=lon, height=side) + # 笔记 + B3 = tk.Button(root, text=f"笔记", bg='white', fg='black', + font=('幼圆', 12, 'bold'), command=note_on_off) + B3.place(x=(lon + 2) * 2 + 50, y=(side + 3) * 11 + 8, width=lon, height=side) + # 一键笔记 + B4 = tk.Button(root, text=f"一键笔记", bg='white', fg='black', + font=('幼圆', 12, 'bold'), command=all_note_on_off) + B4.place(x=(lon + 2) * 3 + 50, y=(side + 3) * 11 + 8, width=lon, height=side) + # 提示 + B5 = tk.Button(root, text=f"提示", bg='white', fg='black', + font=('幼圆', 12, 'bold'), command=hint_on_off) + B5.place(x=(lon + 2) * 4 + 50, y=(side + 3) * 11 + 8, width=lon, height=side) + + +def restart(): + for child in info.winfo_children(): + child.destroy() + canvas.delete("usr_input") + global u_martix, info_labels, note_mark, all_hint_mark, STEP, row, col + global usr_note_dict, mapping, time1, set_question_mark, r_step, hint_mark + global possible_num_mark + u_martix = martix.copy() + info_labels = [] # label对象列表 + note_mark = False # 笔记标志 + all_hint_mark = False # 一键笔记标记 + STEP = [] # 回撤存储列表 + set_question_mark = False # 手动挖空标志 + r_step = list() # 单步记录列表 + hint_mark = None # 提示状态 + possible_num_mark = False + + row = None + col = None + + usr_note_dict = creat_note_dict() # 记录对应单元格笔记数字 + mapping = creat_martix_mapping(side) + basics_info() + + seq_recode() + show_usr_num() + show_fixa_num() + canvas.delete("mini_num") + time1 = MyTimer(root) + show_Time(info, time1) + + +def game_menu(menu: tk.Menu): + """游戏菜单显示""" + menu_node = tk.Menu(menu, tearoff=False) + menu_node.add_command(label="重新开始", command=lambda: restart()) + menu_node.add_command(label="暂停计时", command=lambda: time1.stop()) + menu_node.add_command(label="载入题目", command=lambda: load_game()) + # 在主目录菜单上新增"菜单"选项,并通过menu参数与下拉菜单绑定 + menu.add_cascade(label="游戏设置", menu=menu_node) + + +def auto_menu(menu: tk.Menu): + """自动求解菜单显示""" + menu_node = tk.Menu(menu, tearoff=False) + menu_node.add_command(label="自动求解-顺序求解", command=launch_auto) + menu_node.add_command(label="自动求解-优化", command=launch_auto_better) + fmenu = tk.Menu(menu, tearoff=False) + fmenu.add_command(label='低速', command=lambda: speed_set(0.5)) + fmenu.add_command(label='中速', command=lambda: speed_set(0.2)) + fmenu.add_command(label='高速', command=lambda: speed_set(0)) + menu_node.add_cascade(label="求解速度选择", menu=fmenu) + # 在主目录菜单上新增"菜单"选项,并通过menu参数与下拉菜单绑定 + menu.add_cascade(label="自动求解", menu=menu_node) + + +def question_menu(menu: tk.Menu): + menu_node = tk.Menu(menu, tearoff=False) + menu_node.add_command(label="手动出题", command=lambda: auto_question()) + menu_node.add_command(label="挖空出题", command=lambda: set_question()) + menu_node.add_command(label="单步求解模式", command=lambda: one_step_ctrl()) + menu_node.add_command(label="手动解预期数", command=lambda: show_possible_num()) + menu.add_cascade(label="手动模式", menu=menu_node) + + +def one_step_ctrl(): + global martix, u_martix + for w in info.winfo_children(): + w.destroy() + + info_label = tk.Label(info, text="单步求解模式", bg=WHITE, font=("幼圆", 12, "bold")) + info_label.place(x=120, y=21) + + next_step_button = tk.Button(info, text="下一步", font=("幼圆", 12, "bold"), command=lambda: one_step_start(1)) + next_step_button.place(x=100, y=60) + + next_step_button = tk.Button(info, text="上一步", font=("幼圆", 12, "bold"), command=lambda: one_step_start(-1)) + next_step_button.place(x=180, y=60) + + one_martix = martix.copy() + one_step_solve(one_martix) # 运行单步求解函数,获得满记录的r_step列表 + + +def one_step_start(step): + global STEP, u_martix, row, col + index = len(STEP) - 1 + if step == 1 and index + 1 < len(r_step): + item = r_step[index + 1] + u_martix = item[2] + row, col = item[0][0], item[0][1] + STEP.append(item) + seq_recode() + draw(row, col) + show_usr_num() + + + elif step == -1: + if len(STEP) > 1: + item = r_step[index - 1] + u_martix = item[2] + row, col = item[0][0], item[0][1] + else: + u_martix = martix + try: + STEP.pop() + except: + pass + seq_recode() + draw(row, col) + show_usr_num() + + +def one_step_solve(martix): + for row in range(9): + for col in range(9): + if martix[row, col] == 0: + possible = GetPossible(martix, row, col) # 所有的可能的数字 + for value in possible: + martix[row, col] = value # 将可能的数组填入 + recoder_one(row, col, value, martix) + if one_step_solve(martix): # 继续深度优先遍历填入数字 + return True # 填完最后一个数字 + martix[row, col] = 0 # 如果当前状况无解则归位,然后回溯 + recoder_one(row, col, value, martix) + return False + # 当所有的数字填完,数独求解完毕 + return True + + +def get_user_input(entry: tk.Entry): + global martix, u_martix + num = entry.get() + martix = data.InitMartix(int(num)) + u_martix = martix.copy() + restart() + + +def auto_question(): + global martix, u_martix + for w in info.winfo_children(): + w.destroy() + num_info = tk.Label(info, text="输入挖空数", bg=WHITE, font=('幼圆', 12, 'bold'), anchor=tk.W) + num_info.place(x=15, y=21) + num_entry = tk.Entry(info) + num_entry.config(font=('幼圆', 12, 'bold'), width=10) + num_entry.place(x=110, y=23) + get_input_button = tk.Button(info, text="出题", font=('幼圆', 12, 'bold'), + command=lambda: get_user_input(num_entry)) + get_input_button.place(x=90, y=60) + + +def question_ok(set_martix): + global martix, u_martix, set_question_mark + martix = set_martix + set_question_mark = False + restart() + + +def set_question(): + global martix, u_martix, set_question_mark, set_martix + martix = data.InitMartix(0) + set_martix = martix.copy() + show_fixa_num() + + for w in info.winfo_children(): + w.destroy() + num_info = tk.Label(info, text="鼠标左键点击你想挖空的单元格", bg=WHITE, font=('幼圆', 12, 'bold'), anchor=tk.W) + num_info.place(x=30, y=21) + + set_question_mark = True + + get_input_button = tk.Button(info, text="确认", font=('幼圆', 12, 'bold'), + command=lambda: question_ok(set_martix=set_martix)) + get_input_button.place(x=90, y=60) + + get_input_button = tk.Button(info, text="取消", font=('幼圆', 12, 'bold'), + command=set_question) + get_input_button.place(x=150, y=60) + + # pprint(martix) + + +def show_possible_num(): + global martix, u_martix, row_entry, col_entry, big_cell_entry, cell_entry, cell_info_label + global possible_num_mark + + possible_num_mark = True + for w in info.winfo_children(): + w.destroy() + jx = 75 + info_label = tk.Label(info, text="手动解预期数", bg=WHITE, font=("幼圆", 12, "bold")) + info_label.place(x=120, y=21) + + if row and col: + cell_info_label = tk.Label(info, text=f"当前选中单元格:{row}-{col}", bg=WHITE, font=("幼圆", 12, "bold")) + lebel_width = cell_info_label.winfo_reqwidth() + x = 160 + x = x - lebel_width / 2 + cell_info_label.place(x=x, y=105, ) + else: + cell_info_label = tk.Label(info, text=f"请选中一个单元格以开始实验", bg=WHITE, fg=RED, + font=("幼圆", 12, "bold")) + lebel_width = cell_info_label.winfo_reqwidth() + x = 160 + x = x - lebel_width / 2 + cell_info_label.place(x=x, y=105, ) + + next_cell_button = tk.Button(info, text="自动解", font=("幼圆", 12, "bold"), command=lambda: auto_possible_verify()) + next_cell_button.place(x=100, y=60) + + next_cell_button1 = tk.Button(info, text="验证", font=("幼圆", 12, "bold"), command=lambda: possible_verify()) + next_cell_button1.place(x=180, y=60) + + row_label = tk.Label(info, text=f"当前行可填数字:", bg=WHITE, font=("幼圆", 12, "bold")) + row_label.place(x=20, y=150) + + row_entry = tk.Entry(info) + row_entry.place(x=20, y=175) + row_entry.config(font=('幼圆', 12, 'bold'), width=10) + + col_label = tk.Label(info, text=f"当前列可填数字:", bg=WHITE, font=("幼圆", 12, "bold")) + col_label.place(x=20, y=150 + jx) + + col_entry = tk.Entry(info) + col_entry.place(x=20, y=175 + jx) + col_entry.config(font=('幼圆', 12, 'bold'), width=10) + + big_cell = tk.Label(info, text=f"当前宫格可填数字:", bg=WHITE, font=("幼圆", 12, "bold")) + big_cell.place(x=20, y=150 + 2 * jx) + + big_cell_entry = tk.Entry(info) + big_cell_entry.place(x=20, y=175 + 2 * jx) + big_cell_entry.config(font=("幼圆", 12, "bold"), width=10) + + cell = tk.Label(info, text=f"当前格可能填写数字:", bg=WHITE, font=("幼圆", 12, "bold")) + cell.place(x=20, y=150 + 3 * jx) + + cell_entry = tk.Entry(info) + cell_entry.place(x=20, y=175 + 3 * jx) + cell_entry.config(font=("幼圆", 12, "bold"), width=10) + + +def possible_verify(): + """验证功能""" + global martix, u_martix, row_entry, col_entry, big_cell_entry, cell_entry + global row, col + + if row is not None: + row_nums = row_entry.get() + row_nums = trans_int_set(row_nums) + + col_nums = col_entry.get() + col_nums = trans_int_set(col_nums) + + big_cell_nums = big_cell_entry.get() + big_cell_nums = trans_int_set(big_cell_nums) + + cell_nums = cell_entry.get() + cell_nums = trans_int_set(cell_nums) + + row_entry.delete(0, tk.END) + if get_row_possible(u_martix, row, col) == row_nums: + row_entry.insert(0, "正确") + else: + row_entry.insert(0, "错误") + + col_entry.delete(0, tk.END) + if get_col_possible(u_martix, row, col) == col_nums: + col_entry.insert(0, "正确") + else: + col_entry.insert(0, "错误") + + big_cell_entry.delete(0, tk.END) + if get_big_cell_possible(u_martix, row, col) == big_cell_nums: + big_cell_entry.insert(0, "正确") + else: + big_cell_entry.insert(0, "错误") + + cell_entry.delete(0, tk.END) + if GetPossible(u_martix, row, col) == cell_nums: + cell_entry.insert(0, "正确") + else: + cell_entry.insert(0, "错误") + + print(row_nums, col_nums, big_cell_nums, cell_nums) + print(get_row_possible(u_martix, row, col), get_col_possible(u_martix, row, col), + get_big_cell_possible(u_martix, row, col), GetPossible(u_martix, row, col)) + + +def auto_possible_verify(): + """验证功能""" + global martix, u_martix, row_entry, col_entry, big_cell_entry, cell_entry + global row, col + + if row is not None: + row_entry.delete(0, tk.END) + row_nums = get_row_possible(u_martix, row, col) + row_nums = [str(i) for i in row_nums] + row_nums = ",".join(row_nums) + row_entry.insert(0, row_nums) + + col_entry.delete(0, tk.END) + col_nums = get_col_possible(u_martix, row, col) + col_nums = [str(i) for i in col_nums] + col_nums = ",".join(col_nums) + col_entry.insert(0, col_nums) + + big_cell_entry.delete(0, tk.END) + big_cell_nums = get_big_cell_possible(u_martix, row, col) + big_cell_nums = [str(i) for i in big_cell_nums] + big_cell_nums = ",".join(big_cell_nums) + big_cell_entry.insert(0, big_cell_nums) + + cell_entry.delete(0, tk.END) + cell_nums = GetPossible(u_martix, row, col) + cell_nums = [str(i) for i in cell_nums] + cell_nums = ",".join(cell_nums) + cell_entry.insert(0, cell_nums) + + print(row_nums, col_nums, big_cell_nums, cell_nums) + print(get_row_possible(u_martix, row, col), get_col_possible(u_martix, row, col), + get_big_cell_possible(u_martix, row, col), GetPossible(u_martix, row, col)) + + +def trans_int_set(nums: str): + nums = re.findall(r"\d+", nums) + nums = "".join(nums) + Set = set() + for num in list(nums): + Set.add(int(num)) + return Set + + +def get_row_possible(martix, row, col): + """当前行的可能数字""" + Nums = {1, 2, 3, 4, 5, 6, 7, 8, 9} + Set = set() + for i in range(9): + if i == row: + continue + Set.add(int(martix[i, col])) # 将所在列出现数字加入集合 + # print(martix[i,col]) + return Nums - Set + + +def get_col_possible(martix, row, col): + """当前列的可能数字""" + Nums = {1, 2, 3, 4, 5, 6, 7, 8, 9} + Set = set() + for i in range(9): + if i == col: + continue + Set.add(int(martix[row, i])) # 将所在列出现数字加入集合 + # print(martix[row,i]) + return Nums - Set + + +def get_big_cell_possible(martix, row, col): + """当前宫格可能的数字""" + Nums = {1, 2, 3, 4, 5, 6, 7, 8, 9} + Set = set() + m, n = row // 3, col // 3 # 计算所在九宫格的编号 + for i in range(m * 3, m * 3 + 3): + for j in range(n * 3, n * 3 + 3): + if row == i and j == col: + continue + Set.add(int(martix[i, j])) # 将所在九宫格出现数字加入集合 + # print(martix[i,j]) + return Nums - Set # 返回1~9中没出现过的数字,即可选的 + + +def next_cell_query(): + for row in range(9): + for col in range(9): + if martix[row, col] == 0: + return row, col + + +def speed_set(num): + global wait_time + wait_time = num + + +def launch_auto(): + time1.restart() + auto_Solve(u_martix) + win(u_martix, time1) + + +def auto_Solve(martix): + for row in range(9): + for col in range(9): + if martix[row, col] == 0: + possible = GetPossible(martix, row, col) # 所有的可能的数字 + for value in possible: + martix[row, col] = value # 将可能的数组填入 + + draw(row, col) + recoder(row, col, value, u_martix) + show_usr_num() + canvas.update_idletasks() + time.sleep(wait_time) # 防止运算过快,减慢演算步骤 + + if auto_Solve(martix): # 继续深度优先遍历填入数字 + return True # 填完最后一个数字 + + martix[row, col] = 0 # 如果当前状况无解则归位,然后回溯 + recoder(row, col, value, u_martix) + draw(row, col) + show_usr_num() + canvas.update() + time.sleep(wait_time) # 防止运算过快,减慢演算步骤 + + return False + # 当所有的数字填完,数独求解完毕 + return True + + +def recoder_one(row, col, num, u_martix): + # 返回记录表 + global r_step + step_martix = u_martix.copy() + r_step.append([(row, col), num, step_martix]) + + +def recoder(row, col, num, u_martix): + global STEP + step_martix = u_martix.copy() + if len(STEP) > 0: + old_row, old_col = STEP[-1][0] + if old_row == row and old_col == col: + STEP[-1] = [(row, col), num, step_martix] + else: + STEP.append([(row, col), num, step_martix]) + else: + STEP.append([(row, col), num, step_martix]) + seq_recode() + + +def launch_auto_better(): + time1.restart() + auto_Solve_better(u_martix) + win(u_martix, time1) + noter() + + +def auto_Solve_better(u_M): + global note_mark + note_mark = False # 关闭笔记 + + flag = 0 + # 优化:如果某个位置只有一个可能值,则先填这个格子 + for row in range(9): + for col in range(9): + if u_M[row, col] == 0: + possible = GetPossible(u_M, row, col) # 所有的可能的数字 + if len(possible) == 1: + flag = 1 # 标记可以进行求解优化 + value = possible.pop() # 只有一个可能数组,则直接将该数字填入 + u_M[row, col] = value # 将确定的数字填入填入 + + draw(row, col) + canvas.update() + time.sleep(wait_time) # 防止运算过快,减慢演算步骤 + recoder(row, col, value, u_martix) + show_usr_num() + + time.sleep(wait_time) # 停顿一段时间,显示求解步骤 + if auto_Solve_better(u_M): # 继续深度优先遍历填入数字 + return True # 填完最后一个数字 + u_M[row, col] = 0 # 如果当前填入的数字会导致后面无解则依然填入0表示空白待填 + + draw(row, col) + canvas.update() + time.sleep(wait_time) # 防止运算过快,减慢演算步骤 + recoder(row, col, value, u_martix) + + show_usr_num() + time.sleep(wait_time) # 停顿一段时间,显示求解步骤 + if not flag: # 若没有能直接确定的格子,则按原方法进行求解 + for row in range(9): + for col in range(9): + if u_M[row, col] == 0: + possible = GetPossible(u_M, row, col) # 所有的可能的数字 + + for value in possible: + u_M[row, col] = value # 将可能的数组填入 + recoder(row, col, value, u_martix) + draw(row, col) + + canvas.update() + time.sleep(wait_time) # 防止运算过快,减慢演算步骤 + + show_usr_num() + + time.sleep(wait_time) # 停顿一段时间,显示求解步骤 + if auto_Solve_better(u_M): # 继续深度优先遍历填入数字 + return True # 填完最后一个数字 + u_M[row, col] = 0 # 如果当前填入的数字会导致后面无解则依然填入0表示空白待填 + + draw(row, col) + + canvas.update() + time.sleep(wait_time) # 防止运算过快,减慢演算步骤 + recoder(row, col, value, u_martix) + + show_usr_num() + + time.sleep(wait_time) # 停顿一段时间,显示求解步骤 + return False + return True # 当所有的数字填完,数独求解完毕 + + +def win(u_martix, timer: MyTimer): + count = 0 # 计数 + + for i in range(9): + for j in range(9): + if u_martix[i][j] == 0 or u_martix[i][j] == 10: + count += 1 + if count == 0: + if Judge(u_martix): + for w in info.winfo_children(): + w.destroy() + timer.stop() + win_words = tk.Label(info, text=f"游戏结束,恭喜通过", bg='white', fg='red', font=('幼圆', 16, 'bold'), + anchor=tk.W) + win_words.place(relx=0.1, rely=0.3) + win_time = tk.Label(info, text=f"耗时:{timer.min.get()}分{timer.sec.get()}秒", bg='white', fg='red', + font=('幼圆', 16, 'bold'), anchor=tk.W) + win_time.place(relx=0.1, rely=0.4) + win_step = tk.Label(info, text=f"花费步数:{len(STEP)}步", bg='white', fg='red', + font=('幼圆', 16, 'bold'), anchor=tk.W) + win_step.place(relx=0.1, rely=0.5) + re = tk.Button(info, text=f"重新开始", bg='white', fg='black', + font=('幼圆', 14, 'bold'), command=lambda: restart()) + re.place(relx=0.1, rely=0.6, relwidth=0.5) + + +def load_game(): + global martix, u_martix + martix = data.InitMartix(30) + pprint(martix) + restart() + + +def draw(row, col): + rect_color(row, col) + select_rect_color(row, col) + # show_usr_num() + + +def show_all_note(): + canvas.delete("usr_note") + for i in range(9): + for n in range(9): + possible = usr_note_dict[i, n] + draw_mini_num(i, n, possible, "red", "usr_note") + + +def delete_ctrl(): + """擦除功能""" + global u_martix, usr_note_dict + if row != None: + if martix[row, col] == 0: + canvas.delete("usr_input") + u_martix[row, col] = 0 + show_usr_num() + if len(usr_note_dict[row, col]) != 0: + usr_note_dict[row, col] = set() + show_all_note() + + +def backspace(): + """撤回功能""" + global STEP, u_martix, row, col + if len(STEP) > 0: + loca, num, step_martix = STEP.pop() + u_martix = step_martix + row, col = loca + seq_recode() + delete_ctrl() + draw(row, col) + + +def usr_input(row, col, num, color="blue"): + global STEP + if not note_mark: + if row != None and martix[row, col] == 0: + canvas.delete("usr_input") + canvas.delete("usr_note") + canvas.delete("mini_num") + + step_martix = u_martix.copy() + + u_martix[row, col] = num + usr_note_dict[row, col] = set() + x, y = mapping[row, col] + draw_one_num(x, y, num, color, "usr_input") + u_martix[row, col] = num + show_all_note() + show_usr_num() + + if len(STEP) > 0: + old_row, old_col = STEP[-1][0] + if old_row == row and old_col == col: + STEP[-1] = [(row, col), num, step_martix] + else: + STEP.append([(row, col), num, step_martix]) + else: + STEP.append([(row, col), num, step_martix]) + seq_recode() + win(u_martix, time1) + else: + if row != None and martix[row, col] == 0: + u_martix[row, col] = 0 + usr_note_dict[row, col].add(num) + draw_mini_num(row, col, usr_note_dict[row, col], "red", "usr_note") + show_usr_num() + + +def rect_color(row, col): # 显示当前选中格之外所有颜色 + block_color = [3, 4, 5] # 显色宫格依据 + for key, item in rect_mapping.items(): + if key[0] != row and key[1] != col: + logi_row = key[0] in block_color and key[1] in block_color # 显色逻辑 + logi_col = key[0] in block_color or key[1] in block_color # 显色逻辑 + if not logi_row and logi_col: + color = "#FAE067" + canvas.itemconfig(item, fill=color) + else: + color = 'white' + canvas.itemconfig(item, fill=color) + + +def select_rect_color(row, col): # 突出显示当前选中格 + for key, item in rect_mapping.items(): + if key[0] == row and key[1] == col: + canvas.itemconfig(item, fill='#DCA0DC') + elif key[0] == row or key[1] == col: + canvas.itemconfig(item, fill='#ECD0EC') + + +if __name__ == '__main__': + root = tk.Tk() + root.title("数独") # 设置窗口标题 + width, height = 840, 610 # 设置长宽 + root.geometry(f'{width}x{height}') # 设置窗口大小 + canvas = tk.Canvas(root, bg=WHITE, bd=2, width=width, height=height, background=ORANGE, + highlightthickness=0) # 设置画布 + canvas.place(x=0, y=0, anchor=tk.NW) # 设置画布位置 + + info = draw_info(canvas) + time1 = MyTimer(root) + show_Time(info, time1) + + main_menu = tk.Menu(root) + root.config(menu=main_menu) + game_menu(main_menu) + auto_menu(main_menu) + question_menu(main_menu) + + rect_mapping = draw_all_rect(canvas) + number_button(root) + control_button(root, side) + + basics_info() + canvas.bind('', click_event) + # info.bind('', click_event) + + # time.sleep(3) + # label_destroy_info(info_labels, canvas) + + show_fixa_num() + + tk.mainloop() + # test2() diff --git a/requirements.txt b/requirements.txt index 0408cb4..7c946f0 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..4a7a3e7 --- /dev/null +++ b/run.sh @@ -0,0 +1,6 @@ +xrandr --addmode VNC-0 "1920x1200" +xrandr --output VNC-0 --mode "1920x1200" +nohup python3 /home/headless/Desktop/workspace/myshixun/src/new_UI.py +echo "执行开始" +echo "过程正确" +echo "执行完成" \ No newline at end of file diff --git a/sudoku.py b/sudoku.py index 5638bf5..b204267 100644 --- a/sudoku.py +++ b/sudoku.py @@ -35,6 +35,7 @@ main_menu = tk.Menu(root) root.config(menu=main_menu) game_menu(main_menu) auto_menu(main_menu) +martix_position_mapping = creat_martix_mapping(side) def speed_set(spd): global wait_time @@ -176,6 +177,8 @@ def load_game(): draw(loca, martix, u_martix, STEP) + + def left1(event): ''' martix坐标映射 @@ -185,21 +188,17 @@ def left1(event): """""" x = event.x y = event.y - row = -1 - col = -1 global STEP, loca, loca_o - for cur_col in range(9): - for cur_row in range(9): - top_x, top_y = cur_col * (bc + 3) + 50, cur_row * (bc + 3) + 50# 计算每个方格的四个角 - ud_x, ud_y = (cur_col + 1) * (bc + 3) + 50, (cur_row + 1) * (bc + 3) + 50# 计算每个方格的四个角 - if x < ud_x and x > top_x:#计算点击的列数 - col = cur_col - if y < ud_y and y > top_y:#计算点击的行数 - row = cur_row - if row >= 0 and col >= 0 and not martix[row, col]: + + for key, posit_lt in martix_position_mapping.items(): + if posit_lt[0] < x < posit_lt[0] + side and posit_lt[1] < y < posit_lt[1] + side: + print(key) + + if key[0] >= 0 and key[1] >= 0 and not martix[key[0], key[1]]: + # print(col, row, "dks") if loca:#若已经点击过坐标 loca_o = loca # 保留上次点击过的坐标 - loca = (row + 1, col + 1) # 更新选中的格子位置 + loca = (key[0] + 1, key[1] + 1) # 更新选中的格子位置 draw(loca, martix, u_martix, STEP)#绘制界面 return @@ -267,17 +266,17 @@ def u_number(num, loca): possible[row][col].add(num) draw(loca, martix, u_martix, STEP)#重新绘制界面 -def control_draw_old(bc): +def control_draw_old(side): ''' 绘制数字按钮 - :param bc: 全局按钮大小 + :param side: 全局按钮大小 :return: ''' for i in range(9):#遍历0~9 - top_x, top_y = i * (bc + 3) + 50, 12 * (bc + 3) + 10#计算每个按钮左上角坐标 + top_x, top_y = i * (side + 3) + 50, 12 * (side + 3) + 10#计算每个按钮左上角坐标 B = tk.Button(root, text=f"{i + 1}", bg='white', fg='black', font=('幼圆', 14, 'bold'), command=lambda num=i + 1: u_number(num, loca)) - B.place(x=top_x, y=top_y, width=bc + 3, height=bc + 3)#绘制按钮到图上 + B.place(x=top_x, y=top_y, width=side + 3, height=side + 3)#绘制按钮到图上 def control_draw(bc, u_martix): ''' 绘制数字按钮 @@ -331,19 +330,19 @@ def listen_all_note(possible, u_martix): u_martix[row][col] = 10#标记这个格子为存在提示 draw(loca, martix, u_martix, STEP)#重新绘制界面 -def show_hint(bc, u_martix, possible): +def show_hint(side, u_martix, possible): ''' 显示提示信息 - :param bc: 方格大小 + :param side: 方格大小 :return: ''' - hint_bc = int(bc // 3)# 小数字的间距 + hint_bc = int(side // 3)# 小数字的间距 for row in range(9): for col in range(9): if not u_martix[row][col] == 10: possible[row][col].clear()# 只有u_martix[j][i]为10才表示该格子有笔记存在 continue# 若该格无笔记,则跳过该格 - x, y = col * (bc + 3) + 50 + bc / 2, row * (bc + 3) + 50 + bc / 2# 计算大方格中点坐标 + x, y = col * (side + 3) + 50 + side / 2, row * (side + 3) + 50 + side / 2# 计算大方格中点坐标 x = x - hint_bc#计算左上角第一个数字坐标 y = y - hint_bc#计算左上角第一个数字坐标 for ii in range(3):# 按照九宫格显示小数字 @@ -352,9 +351,9 @@ def show_hint(bc, u_martix, possible): if possible[row][col]: # 在用户已填的部分有可能导致部分格子无解,所以先加一个判断 for k in possible[row][col]: if n == k:# 如果possible[row][col]中含有k,则说明该格子可以填k,则将k显示在方格中 - cv.create_text(x + ii * hint_bc, y + jj * hint_bc, - text=f"{n}", font=('楷体', 10), fill='purple') - cv.update()#更新画布 + canvas.create_text(x + ii * hint_bc, y + jj * hint_bc, + text=f"{n}", font=('楷体', 10), fill='purple', tags="mini_num") + @@ -430,6 +429,15 @@ def control(bc): font=('幼圆', 12, 'bold'), command=lambda: listen_hint(loca, u_martix)) B5.place(x=(lon + 2) * 4 + 50, y=(bc + 3) * 11 + 8, width=lon, height=bc) +# def draw(loca, martix, u_martix, STEP): + +def draw_fixation_num(): + for i in range(9): + for n in range(9): + x,y = martix_position_mapping[i,n] + canvas.create_text(x+ side / 2, x + side / 2, + text=f"{u_martix[i, n]}", font=('幼圆', 18, 'bold'), fill="black", tags="fixa_num") + num_draw(side,i,n,martix,u_martix) def draw(loca, martix, u_martix, STEP): ''' @@ -437,33 +445,33 @@ def draw(loca, martix, u_martix, STEP): :param loca: 当前位置 :return: ''' - for i in range(9): - for j in range(9):# 绘制小方格 - rect_draw(BC, i, j) if loca != ():#根据当前选中位置绘制阴影 + canvas.delete("rect") row, col = loca[0] - 1, loca[1] - 1 for i in range(9): for j in range(9): if col == i and row == j:#当前选中的方格使用灰色标记 - cv.create_rectangle(col * (BC + 3) + 52, row * (BC + 3) + 52, col * (BC + 3) + 48 + BC, - row * (BC + 3) + 48 + BC, fill='grey', width=0) + canvas.create_rectangle(col * (side + 3) + 52, row * (side + 3) + 52, col * (side + 3) + 48 + side, + row * (side + 3) + 48 + side, fill='grey', width=0, tags="rect") elif col == i or row == j:#当前选中方格所在行列使用浅灰色标记 - cv.create_rectangle(i * (BC + 3) + 52, j * (BC + 3) + 52, i * (BC + 3) + 48 + BC, - j * (BC + 3) + 48 + BC, fill='#CCCCCC', width=0) - show_hint(BC, u_martix, possible)# 显示提示信息 - for row in range(9): - for col in range(9):# 在小方格上绘制数字 - num_draw(BC, row, col, martix, u_martix) - print(u_martix.tolist()) - print(loca) - control(BC)# 绘制五个控制按键 - control_draw(BC, u_martix)# 绘制9个数字按钮 + canvas.create_rectangle(i * (side + 3) + 52, j * (side + 3) + 52, i * (side + 3) + 48 + side, + j * (side + 3) + 48 + side, fill='#CCCCCC', width=0, tags="rect") + canvas.delete("num") + num_draw(side, row, col, martix, u_martix) + + canvas.delete("mini_num") + show_hint(side, u_martix, possible)# 显示提示信息 + + + # print(u_martix.tolist()) + # print(loca) + empty_count = empty(martix)# 计算数组空格 Difficulty(empty_count)# 根据空格数量显示难度 noter(note_mark)# 显示笔记提示 seq_recode(right, STEP)# 显示步骤 win(u_martix, time1, STEP)# 检查游戏是否结束 - cv.update()# 更新画布 + # canvas.update()# 更新画布 N = 30 # 空白格子数 martix = InitMartix(N) @@ -488,12 +496,18 @@ step = [] # 操作步骤 STEP = [[0, (0, 0), 0, martix]] # 记录每一步的状态 seq = 1 # 全局操作次序初始化 + +draw_all_rect() # 显示底图 +control(side) # 绘制五个控制按键 +control_draw(side, u_martix) # 绘制9个数字按钮 +draw_fixation_num() + time1 = MyTimer() # 实例计时器 # 显示时间信息 show_Time(time1) draw(loca, martix, u_martix, STEP) -cv.bind('', left1) +canvas.bind('', left1) if __name__ == "__main__": mainloop() \ No newline at end of file diff --git a/函数调用.py b/函数调用.py new file mode 100644 index 0000000..17cfb92 --- /dev/null +++ b/函数调用.py @@ -0,0 +1,15 @@ + +from pycallgraph2 import PyCallGraph +from pycallgraph2.output import GraphvizOutput +from pycallgraph2 import Config +from pycallgraph2 import GlobbingFilter + +def main(): + # TODO: 调用各种类、函数 + return + +if __name__ == "__main__": + graphviz = GraphvizOutput() + graphviz.output_file = 'graph.png' + with PyCallGraph(output=graphviz): + main() diff --git a/对勾.png b/对勾.png new file mode 100644 index 0000000..cd030a0 Binary files /dev/null and b/对勾.png differ diff --git a/错叉.png b/错叉.png new file mode 100644 index 0000000..6d9152e Binary files /dev/null and b/错叉.png differ