import tkinter as tk
from tkinter import messagebox
class PuzzleGame:
def __init__(self, master):
self.master = master
self.moves = 0
# 初始状态(外围随机排列,中间为空)
self.board = [
[1, 2, 3],
[8, 0, 4],
[7, 5, 6] # 5和6位置交换作为初始可解状态
]
# 目标状态(顺时针排列)
self.target = [
[1, 2, 3],
[8, 0, 4],
[7, 6, 5]
]
self.empty_pos = (1, 1) # 初始空格位置
self.buttons = [[None]*3 for _ in range(3)]
self.init_ui()
self.update_buttons()
def init_ui(self):
self.master.title("九宫格棋盘游戏")
# 创建棋盘按钮
for i in range(3):
for j in range(3):
text = str(self.board[i][j]) if self.board[i][j] != 0 else ""
btn = tk.Button(
self.master, text=text, width=6, height=3,
command=lambda row=i, col=j: self.on_click(row, col),
font=("Arial", 14))
btn.grid(row=i, column=j, padx=2, pady=2)
self.buttons[i][j] = btn
# 移动计数器
self.move_counter = tk.Label(self.master, text=f"移动次数: {self.moves}", font=("Arial", 12))
self.move_counter.grid(row=3, columnspan=3, pady=10)
def on_click(self, row, col):
# 检查是否与空格相邻
if self.is_adjacent(row, col, self.empty_pos):
# 移动棋子
self.swap_tiles(row, col, self.empty_pos[0], self.empty_pos[1])
self.empty_pos = (row, col)
self.moves += 1
self.update_buttons()
# 检查是否胜利
if self.check_victory():
messagebox.showinfo("游戏胜利", f"恭喜!您用 {self.moves} 步完成拼图!")
self.master.quit()
def is_adjacent(self, r1, c1, empty_pos):
# 判断是否相邻
er, ec = empty_pos
return (abs(r1 - er) == 1 and c1 == ec) or (abs(c1 - ec) == 1 and r1 == er)
def swap_tiles(self, r1, c1, r2, c2):
# 交换两个棋子的位置
self.board[r2][c2], self.board[r1][c1] = self.board[r1][c1], self.board[r2][c2]
def update_buttons(self):
# 更新界面显示
for i in range(3):
for j in range(3):
text = str(self.board[i][j]) if self.board[i][j] != 0 else ""
self.buttons[i][j].config(text=text)
self.move_counter.config(text=f"移动次数: {self.moves}")
def check_victory(self):
# 检查是否达成目标状态
return self.board == self.target
if __name__ == "__main__":
root = tk.Tk()
game = PuzzleGame(root)
root.mainloop()
1. 核心功能
- 棋盘初始化:
- 生成一个 3x3 的九宫格棋盘。
- 初始状态为:数字 1-8 随机排列在外围,中间位置为空(用 0 表示)。
- 棋子移动:
- 玩家可以点击与空格相邻的数字棋子,将其移动到空格位置。
- 每次移动后,棋盘状态会更新,并记录移动次数。
- 胜利条件:
- 当棋盘达到目标状态(数字 1-8 按顺时针排列,中间为空)时,游戏结束。
- 弹出提示框显示胜利信息,包括总移动次数。
- 移动计数:
- 每次移动后,程序会更新并显示当前移动次数。
2. 交互方式
- 界面布局:
- 使用 Tkinter 创建一个 3x3 的网格界面。
- 每个格子是一个按钮,显示数字或空白(空格)。
- 玩家操作:
- 玩家通过点击按钮移动棋子。
- 只能移动与空格相邻的棋子(上下左右)。
- 实时反馈:
- 每次移动后,界面会立即更新棋盘状态。
- 移动次数会实时显示在界面底部。
3. 游戏规则
- 初始状态:
- 数字 1-8 随机排列在外围,中间为空。
- 例如:
- 复制
- [1, 2, 3] [7, 0, 4] [8, 6, 5]
- 目标状态:
- 数字 1-8 按顺时针方向排列,中间为空。
- 例如:
- 复制
- [1, 2, 3] [8, 0, 4] [7, 6, 5]
- 移动规则:
- 只能移动与空格相邻的棋子。
- 每次移动会交换棋子和空格的位置。
- 胜利条件:
- 当棋盘状态与目标状态完全一致时,游戏胜利。
4. 实现细节
- 数据结构:
- 使用一个 3x3 的二维列表 self.board 存储棋盘状态。
- 空格用 0 表示。
- 界面实现:
- 使用 Tkinter 的 Button 组件实现棋盘格子。
- 每个按钮绑定点击事件,触发 on_click 方法。
- 逻辑实现:
- 移动检查:通过 is_adjacent 方法判断点击的棋子是否与空格相邻。
- 棋子交换:通过 swap_tiles 方法交换棋子和空格的位置。
- 胜利判断:通过 check_victory 方法比较当前棋盘状态与目标状态。
- 状态更新:
- 每次移动后,调用 update_buttons 方法更新界面显示。
- 移动次数通过 self.moves 变量记录,并在界面底部显示。
5. 程序特点
- 简单易用:
- 界面清晰,操作直观,适合所有年龄段玩家。
- 可扩展性:
- 可以修改初始状态或目标状态,增加游戏难度。
- 可以添加计时功能、撤销功能等。
- 教育意义:
- 帮助玩家锻炼逻辑思维和空间想象力。
- 适合用于算法教学(如搜索算法、状态空间问题)。
6. 示例运行
- 初始界面:
- 复制
- [1, 2, 3] [7, , 4] [8, 6, 5]
- 移动次数:0
- 移动棋子:
- 点击 6,将其移动到空格位置。
- 更新后的棋盘:
- 复制
- [1, 2, 3] [7, 6, 4] [8, , 5]
- 移动次数:1
- 游戏胜利:
- 当棋盘达到目标状态时,弹出提示框:
- 复制
- 恭喜!您用 X 步完成拼图!
7. 适用场景
- 休闲娱乐:
- 作为一款简单的益智游戏,适合休闲时玩耍。
- 教学演示:
- 用于演示状态空间搜索、广度优先搜索(BFS)等算法。
- 编程练习:
- 适合 Python 初学者练习 GUI 开发和逻辑实现。