使用 turtle 库制作汉诺塔动画

本文介绍了使用Python的Turtle库实现汉诺塔的动画过程,包括递归算法和图形界面展示。首先详细解释了汉诺塔的递归移动规则,然后展示了如何绘制柱子和创建不同颜色的圆盘。接着,定义了Stack类用于存储圆盘,并实现了移动圆盘的操作。最后,通过修改原始递归程序,创建了一个动态的汉诺塔动画。整个过程结合了编程和算法,使抽象的汉诺塔问题变得直观易懂。
摘要由CSDN通过智能技术生成

先看效果吧:


1. 汉诺塔递归

如果需要把 n 个 plates 从 A 柱移到 C 柱:

  1. 先将上面的 n-1 个 plates 从 A 移到 B
  2. 将 A 最后一个 plates 移到 C
  3. 再将 n-1 个 plates 从 B 移到 C
def hano(n, A, B, C):
    if n == 1:
        print(A + ' -> ' + C)
    else:
        hano(n-1, A, C, B)
        print(A + ' -> ' + C)
        hano(n-1, B, A, C)

hano(3, 'A', 'B', 'C')

结果如下:

A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C


2. 绘制柱子

使用 Turtle 库绘制三跟柱子 poles:

# 绘制三跟柱子
def drawpoles():
    t = turtle.Turtle()
    t.hideturtle()
    t.color('gray')
    for i in range(3):
        t.up()
        t.pensize(10)
        t.speed('fast')
        t.goto(250*(i-1), 100)
        t.down()
        t.goto(250*(i-1), -100)
        t.goto(250*(i-1)-100, -100)
        t.goto(250*(i-1)+100, -100)

调用后结果如下:



3. 创建圆盘

创建若干圆盘,所有圆盘都是一个 Turtle() 对象
所有圆盘存放在三个栈上,对应 A B 和 C 三跟柱子

3.1 创建 Stack 类
class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return len(self.items) == 0

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[len(self.items) - 1]

    def size(self):
        return len(self.items)

3.2 生成圆盘

先创建若干圆盘:

# 生成 plates
HEIGHT = 25
colors = ['peru', 'tomato', 'darkorange',
          'gold', 'palegreen', 'paleturquoise', 'skyblue', 'plum']

def create_plates(n):
    plates = [turtle.Turtle() for i in range(n)]
    for i in range(n):
        plates[i].speed(5)
        plates[i].hideturtle()
        c = colors[i]
        plates[i].color(c)
        plates[i].up()
        plates[i].hideturtle()
        plates[i].shape('square')
        plates[i].shapesize(1.2, 8-1.1*i)
        plates[i].goto(-250, -82 + HEIGHT*i)
        plates[i].showturtle()
    return plates

通过下面的语句调用函数创建 plates,将 plates 装载到第一个栈 Stack 中:

plates_num = 5
plates = create_plates(plates_num)
poles = [Stack() for i in range(3)]
for plate in plates:
    poles[0].push(plate)


4. 移动操作

如何将一个盘移动呢?

  1. 获取要移动的盘所在柱子最顶部的盘(对应柱子的栈弹栈)
  2. 将盘先搬起来,再移动到目标柱顶部,再下落
  3. 盘放到目标柱后,目标柱对应的栈压栈
# 一次移动
def moveDisk(poles, fromPole, toPole):
    plate = poles[fromPole].pop()
    plate.goto((fromPole - 1) * 250, 120)
    plate.goto((toPole - 1) * 250, 120)
    y = poles[toPole].size() * HEIGHT - 82
    plate.goto((toPole - 1) * 250, y)
    poles[toPole].push(plate)


5. 动起来

对原来的汉诺塔递归程序修改,就可以得到动画:

def hano(n, poles, fromPole, withPole, toPole):
    if n == 1:
        moveDisk(poles, fromPole, toPole)
    else:
        hano(n-1, poles, fromPole, toPole, withPole)
        moveDisk(poles, fromPole, toPole)
        hano(n-1, poles, withPole, fromPole, toPole)

接着在主程序中调用函数:

myscreen = turtle.Screen()
drawpoles()
plates_num = 5
plates = create_plates(plates_num)
poles = [Stack() for i in range(3)]
for plate in plates:
    poles[0].push(plate)

hano(plates_num, poles, 0, 1, 2)
turtle.done()

大功告成 🍻


源代码丢进 github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值