Python作业-汉诺塔
设计要求:
设计 GUI 界面的 Hannoi 塔,用户可以通过拖动鼠标移动各个
塔上的盘子,程序也可以自动演示盘子的移动过程。选择自动演示时程序将以动
画形式演示把 A 塔上的盘子全部移到 C 塔的过程,并将移动过程以文本形式显
示在一个文本区中
import tkinter as tk import time root = tk.Tk() root.title('Hannoi塔') root.geometry('800x400') # 创建画布,并绘制3个柱子 canvas = tk.Canvas(root, bg='white', width=600, height=300) canvas.pack(side='left') canvas.create_rectangle(200, 50, 210, 250, width=0, fill='black') canvas.create_rectangle(300, 50, 310, 250, width=0, fill='black') canvas.create_rectangle(400, 50, 410, 250, width=0, fill='black') # 创建文本区域 text = tk.Text(root, width=30, height=10) text.pack(side='right') # 初始化盘子状态 disk_size = [3, 2, 1] towers = [[], [], []] for i in range(len(disk_size)): towers[0].append(disk_size[i]) # 创建盘子列表 disks = [] colors = ['red', 'blue', 'green'] for i in range(len(disk_size)): disk = canvas.create_rectangle(0, 0, 0, 0, width=0, fill=colors[i]) disks.append(disk) # 记录鼠标位置 x, y = 0, 0 moving_disk = None moving_tower = None # 鼠标拖拽盘子事件处理函数 def on_press(event): global moving_disk, x, y, moving_tower x, y = event.x, event.y tags = canvas.gettags(tk.CURRENT) if len(tags) > 0: index = int(tags[0]) tower = int(tags[1]) if len(towers[tower]) > 0 and towers[tower][-1] == disk_size[index]: moving_disk = disks[index] moving_tower = tower canvas.tag_raise(moving_disk) def on_move(event): global moving_disk if moving_disk: dx, dy = event.x - x, event.y - y canvas.move(moving_disk, dx, dy) x, y = event.x, event.y def on_release(event): global moving_disk, x, y, moving_tower, towers if moving_disk: cy = canvas.coords(moving_disk)[1] + 20 tx = int((event.x - 200) / 100) if tx != moving_tower and (len(towers[tx]) == 0 or towers[tx][-1] > towers[moving_tower][-1]): moving_disk_x = canvas.coords(moving_disk)[0] + 10 moving_disk_y = canvas.coords(moving_disk)[1] + 10 canvas.coords(moving_disk, moving_disk_x, cy - 10, moving_disk_x + 100 - disk_size.index(towers[moving_tower][-1]) * 20, cy + 10) towers[tx].append(towers[moving_tower].pop()) text.insert(tk.END, f'将盘子{disk_size.index(towers[tx][-1]) + 1}从柱子{moving_tower+1}移动到柱子{tx+1}\n') if check_win(): text.insert(tk.END, '游戏胜利!\n') else: canvas.coords(moving_disk, 200 + moving_tower * 100 + 10 - disk_size.index(towers[moving_tower][-1]) * 20, cy - 10, 200 + moving_tower * 100 + 10 + 100 - disk_size.index(towers[moving_tower][-1]) * 20, cy + 10) moving_disk = None moving_tower = None # 检查游戏是否胜利 def check_win(): if len(towers[0]) == 0 and len(towers[1]) == 0: if towers[2] == [3, 2, 1]: return True return False # 移动盘子的递归函数 def move_disc(canvas, size, source, target, spare, n): if n == 0: return move_disc(canvas, size, source, spare, target, n - 1) draw_disc(canvas, size[n - 1], source[n - 1], source.index + 1) draw_disc(canvas, size[n - 1], 0, target.index + 1) target.append(source.pop()) root.update() canvas.after(500) move_disc(canvas, size, spare, target, source, n - 1) # 绘制盘子 def draw_disc(canvas, size, pos, pole): global towers x1, y1, x2, y2 = 0, 0, 0, 0 if pole == 1: x1, y1, x2, y2 = 180 - size * 10, 250 - pos * 20, 220 + size * 10, 260 - pos * 20 elif pole == 2: x1, y1, x2, y2 = 280 - size * 10, 250 - pos * 20, 320 + size * 10, 260 - pos * 20 else: x1, y1, x2, y2 = 380 - size * 10, 250 - pos * 20, 420 + size * 10, 260 - pos * 20 for i in range(len(towers[pole-1])): if towers[pole-1][i] == size: canvas.coords(disks[size-1], x1, y1 + (len(towers[pole-1])-1-i)*20, x2, y2 + (len(towers[pole-1])-1-i)*20) break # 自动演示移动过程 def animate(): global disks size, source, target, spare = [3, 2, 1], [], [], [] source, target, spare = source[::-1], target[::-1], spare[::-1] for i in range(len(size)): source.append(i) move_disc(canvas, size, source, target, spare, len(size)) # 鼠标拖拽事件绑定 canvas.tag_bind('disc', '<ButtonPress-1>', on_press) canvas.tag_bind('disc', '<B1-Motion>', on_move) canvas.tag_bind('disc', '<ButtonRelease-1>', on_release) # 开始自动演示 animate() root.mainloop()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人