设计思路详解:Python 桌面版 数独游戏
1. 功能需求分析
- 构建一个 9x9 的数独游戏界面。
- 支持玩家手动输入数字。
- 提供两个按钮:
- “重新开始本局”:恢复当前棋盘到初始状态(保留原始数字)。
- “生成新棋局”:生成一个新的随机数独题目。
- 使用标准库实现,无需额外安装。
2. 技术选型
- 使用
tkinter:Python 标准 GUI 库,适合小型桌面应用。 - 使用
random和copy:用于生成数独题目和深拷贝原始题目。 - 采用回溯算法生成完整数独解,再随机移除部分数字生成题目。
3. 核心模块设计
- 数独生成器:
- 使用数学规律生成完整解。
- 随机移除部分数字,生成玩家可玩的题目。
- GUI 界面:
- 使用
tkinter.Entry构建 9x9 网格。 - 原始数字不可编辑,玩家输入的数字可修改。
- 使用
- 按钮功能:
- “重新开始本局”:恢复当前棋盘状态。
- “生成新棋局”:调用数独生成器生成新题目并更新界面。
4. 完整代码实现
import tkinter as tk
from tkinter import messagebox
import random
import copy
class SudokuGame:
def __init__(self, root):
self.root = root
self.root.title("数独游戏")
self.board = []
self.original = []
self.entries = [[None for _ in range(9)] for _ in range(9)]
self.create_widgets()
self.generate_sudoku()
def create_widgets(self):
# 创建数独棋盘
self.frame = tk.Frame(self.root)
self.frame.grid(row=0, column=0, padx=10, pady=10)
for row in range(9):
for col in range(9):
entry = tk.Entry(self.frame, width=3, font=('Arial', 18), 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=1, 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):
# 生成完整数独解
base = 3
side = base * base
def pattern(r, c): return (base * (r % base) + r // base + c) % side
from random import sample
def 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, base * base + 1))
board = [[nums[pattern(r, c)] for c in cols] for r in rows]
# 移除部分数字,生成题目
squares = side * side
for p in sample(range(squares), 40): # 保留 41 个数字
board[p // side][p % side] = 0
self.board = board
self.original = copy.deepcopy(board)
self.update_gui()
def update_gui(self):
for row in range(9):
for col in range(9):
val = self.board[row][col]
entry = self.entries[row][col]
entry.delete(0, tk.END)
if val != 0:
entry.insert(0, str(val))
entry.config(fg='black', readonlybackground='lightgray')
entry.bind("<Key>", lambda e: "break") # 不可编辑原始数字
else:
entry.config(fg='blue', bg='white')
entry.bind("<Key>", self.on_key)
def on_key(self, event):
widget = event.widget
if event.char.isdigit() or event.keysym in ('BackSpace', 'Delete'):
# 允许输入数字或删除
pass
else:
return "break"
def reset_board(self):
self.board = copy.deepcopy(self.original)
self.update_gui()
# 启动程序
if __name__ == "__main__":
root = tk.Tk()
game = SudokuGame(root)
root.mainloop()
运行说明
-
运行环境:
- Python 3.6+
- 无需额外安装库(使用标准库)
-
运行方式:
- 将代码保存为
sudoku_game.py - 执行命令:
python sudoku_game.py
- 将代码保存为
功能验证
| 功能 | 描述 |
|---|---|
| 数独生成 | 点击“生成新棋局”按钮,将生成一个新的数独题目 |
| 手动输入 | 可以在空白格子中输入数字(蓝色) |
| 重新开始 | 点击“重新开始本局”按钮,将恢复当前题目状态 |
| 输入限制 | 原始数字不可编辑(灰色),玩家输入仅限数字 |
后续扩展功能
| 功能 | 描述 |
|---|---|
| 自动验证 | 点击按钮验证当前解是否正确 |
| 提示功能 | 高亮错误数字或给出提示 |
| 计时器 | 添加游戏计时功能 |
| 难度选择 | 提供简单、中等、困难选项(控制移除数字数量) |
| 格数选择 | 提供3X3,6X6,9X9模式 |
630

被折叠的 条评论
为什么被折叠?



