当前位置: 首页 > ops >正文

Python桌面版数独(二版)-增加4X4、6X6

增加选择4x4、6x6模式,以下是三种模式的不同解析:

  1. 4x4模式

    • 数独大小:4x4
    • 每个宫格大小:2x2
    • 数字范围:1-4
  2. 6x6模式

    • 数独大小:6x6
    • 每个宫格大小:2x3
    • 数字范围:1-6
  3. 9x9模式

    • 数独大小:9x9
    • 每个宫格大小:3x3
    • 数字范围:1-9

主要优化点:
4. 添加了模式选择下拉框,可以选择4x4、6x6、9x9模式
5. 根据选择的模式动态创建不同大小的棋盘
6. 生成不同大小的数独题目
7. 验证输入的合法性
8. 检查是否完成数独

以下为非完整代码,完整代码资源有下载


class SudokuGame:# 常量定义CELL_WIDTH = 3CELL_FONT = ('Arial', 18)ORIGINAL_COLOR = 'black'PLAYER_COLOR = 'blue'BG_COLOR = 'white'READONLY_BG_COLOR = 'lightgray'MIN_REMOVE_COUNT = 1  # 至少保留一个数字MODE_CONFIG = {"4x4": {"base": 2, "remove_count": 8, "size": 4},  # 4x4棋盘,每个宫格为2x2,数字范围1-4,移除数字数量为8个"6x6": {"base": 2, "remove_count": 20, "size": 6},  # 6x6棋盘,数字范围1-6,移除数字数量为20个"9x9": {"base": 3, "remove_count": 40, "size": 9}   # 9x9棋盘,数字范围1-9,移除数字数量为40个
}def __init__(self, root):self.root = rootself.root.title("数独游戏")self.board = []self.original = []self.entries = [[None for _ in range(9)] for _ in range(9)]self.mode = "9x9"  # 默认模式self.create_mode_selection()self.create_widgets()def create_mode_selection(self):# 创建模式选择区域self.mode_frame = tk.Frame(self.root)self.mode_frame.grid(row=0, column=0, pady=10)tk.Label(self.mode_frame, text="选择模式:").pack(side="left", padx=5)self.mode_var = tk.StringVar(value="9x9")modes = ["4x4", "6x6", "9x9"]for mode in modes:tk.Radiobutton(self.mode_frame, text=mode, variable=self.mode_var, value=mode, command=self.update_mode).pack(side="left", padx=5)def update_mode(self):# 更新模式并生成新棋局self.mode = self.mode_var.get()self.clear_board()self.generate_sudoku()def clear_board(self):# 清理现有的输入框for row in range(9):for col in range(9):if self.entries[row][col]:self.entries[row][col].destroy()self.entries[row][col] = Nonedef create_widgets(self):# 创建数独棋盘self.frame = tk.Frame(self.root)self.frame.grid(row=1, column=0, padx=10, pady=10)# 根据模式设置棋盘大小config = self.MODE_CONFIG.get(self.mode, self.MODE_CONFIG["9x9"])size = config["size"]for row in range(size):for col in range(size):entry = tk.Entry(self.frame, width=self.CELL_WIDTH, font=self.CELL_FONT, justify='center')entry.grid(row=row, column=col, padx=(0 if col % 3 != 2 else 5),pady=(0 if row % 3 != 2 else 5))self.entries[row][col] = entry# 按钮self.btn_frame = tk.Frame(self.root)self.btn_frame.grid(row=2, column=0, pady=10)self.reset_button = tk.Button(self.btn_frame, text="重新开始本局", command=self.reset_board)self.reset_button.pack(side="left", padx=10)self.new_button = tk.Button(self.btn_frame, text="生成新棋局", command=self.generate_sudoku)self.new_button.pack(side="left", padx=10)def generate_sudoku(self):# 根据选择的模式生成数独config = self.MODE_CONFIG.get(self.mode, self.MODE_CONFIG["9x9"])base = config["base"]remove_count = config["remove_count"]size = config["size"]side = size  # 棋盘边长等于sizedef pattern(r, c): return (base * (r % base) + r // base + c) % sidefrom random import sampledef shuffle(s): return sample(s, len(s))rBase = range(base)rows = [g * base + r for g in shuffle(rBase) for r in shuffle(rBase)]cols = [g * base + c for g in shuffle(rBase) for c in shuffle(rBase)]nums = shuffle(range(1, size + 1))  # 数字范围根据棋盘大小调整# 创建棋盘时使用正确的尺寸board = [[0 for _ in range(side)] for _ in range(side)]# 填充棋盘for r in range(side):for c in range(side):board[r][c] = nums[pattern(r, c)]# 移除部分数字,生成题目squares = side * side# 确保不会尝试移除超过可用数量的数字remove_count = min(remove_count, squares - self.MIN_REMOVE_COUNT)  # 至少保留一个数字# 安全地随机移除数字available_positions = [(r, c) for r in range(side) for c in range(side) if r < side and c < side]if available_positions:# 确保至少保留一个数字safe_remove_count = min(remove_count, len(available_positions))for r, c in sample(available_positions, safe_remove_count):if r < side and c < side:  # 再次检查边界board[r][c] = 0# 清空未使用区域self.clear_board()# 重新创建对应当前模式的输入框# 使用安全的size值current_size = config["size"]for row in range(current_size):for col in range(current_size):# 确保不会越界访问if row < len(self.entries) and col < len(self.entries[row]):entry = tk.Entry(self.frame, width=self.CELL_WIDTH, font=self.CELL_FONT, justify='center')entry.grid(row=row, column=col, padx=(0 if col % 3 != 2 else 5),pady=(0 if row % 3 != 2 else 5))entry.bind("<Key>", self.on_key)self.entries[row][col] = entryself.board = boardself.original = copy.deepcopy(board)self.update_gui()def update_gui(self):# 根据模式更新GUIconfig = self.MODE_CONFIG.get(self.mode, self.MODE_CONFIG["9x9"])size = config["base"] ** 2# 确保board已初始化if not self.board:returnfor row in range(size):for col in range(size):val = 0# 安全访问board元素if row < len(self.board) and col < len(self.board[row]):val = self.board[row][col]entry = self.entries[row][col]if entry:entry.delete(0, tk.END)# 安全访问board元素if row < len(self.board) and col < len(self.board[row]):val = self.board[row][col]if val != 0:entry.insert(0, str(val))entry.config(fg=self.ORIGINAL_COLOR, readonlybackground=self.READONLY_BG_COLOR)entry.bind("<Key>", lambda e: "break")  # 不可编辑原始数字else:entry.config(fg=self.PLAYER_COLOR, bg=self.BG_COLOR)entry.bind("<Key>", self.on_key)def on_key(self, event):widget = event.widgetif event.char.isdigit() or event.keysym in ('BackSpace', 'Delete'):# 允许输入数字或删除passelse:return "break"def reset_board(self):self.board = copy.deepcopy(self.original)self.update_gui()
http://www.xdnf.cn/news/15840.html

相关文章:

  • 元宇宙经济的四个要素
  • python 字典中取值
  • SpringBoot的配置文件
  • python的pywebview库结合Flask和waitress开发桌面应用程序简介
  • 反欺诈业务 Elasticsearch 分页与导出问题分析及解决方案
  • 基于单片机的智能家居安防系统设计
  • Linux文件系统三要素:块划分、分区管理与inode结构解析
  • Linux: rsync+inotify实时同步及rsync+sersync实时同步
  • Claude Code 逆向工程分析,探索最新Agent设计
  • 【机器学习深度学习】量化与选择小模型的区别:如何理解两者的优势与局限?
  • Day1||Vue指令学习
  • PyTorch的基础概念和复杂模型的基本使用
  • Facebook 开源多季节性时间序列数据预测工具:Prophet 快速入门 Quick Start
  • macOs上交叉编译ffmpeg及安装ffmpeg工具
  • 测试中的bug
  • 基于深度学习的自然语言处理:构建情感分析模型
  • urllib.parse.urlencode 的使用详解
  • AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年7月20日第144弹
  • Uniapp 纯前端台球计分器开发指南:能否上架微信小程序 打包成APP?
  • 安全信息与事件管理(SIEM)系统架构设计
  • 【前端】懒加载(组件/路由/图片等)+预加载 汇总
  • AI绘画生成东汉末年赵云全身像的精细提示词
  • 四、多频技术与复杂场景处理
  • 基于卷积傅里叶分析网络 (CFAN)的心电图分类的统一时频方法
  • SpringBoot3集成MapstructPlus
  • GaussDB select into和insert into的用法
  • 基于智慧经营系统的学校住宿登记报表分析与应用探究-毕业论文—仙盟创梦IDE
  • Qt--Widget类对象的构造函数分析
  • 上电复位断言的自动化
  • 网络安全初级(前端页面的编写分析)