zoukankan      html  css  js  c++  java
  • Python实现汉诺塔问题的可视化(以动画的形式展示移动过程)

    学习Python已经有一段时间了,也学习了递归的方法,而能够实践该方法的当然就是汉诺塔问题了,但是这次我们不只是要完成对汉诺塔过程的计算,还要通过turtle库来体现汉诺塔中每一层移动的过程。

    一、设计一个类(Class)

    类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

    下面是此程序需用到的类(Class)代码:

     1 class Stack:
     2     def __init__(self):
     3         self.items = []
     4     def isEmpty(self):
     5         return len(self.items) == 0
     6     def push(self, item):
     7         self.items.append(item)
     8     def pop(self):
     9         return self.items.pop()
    10     def peek(self):
    11         if not self.isEmpty():
    12             return self.items[len(self.items) - 1]
    13     def size(self):
    14         return len(self.items)

    二、设计汉诺塔的底座

    为了还原汉诺塔的移动过程,增强可视化程度,我们给它加上三个底座,代码如下:

     1 def drawpole_3():#画出汉诺塔的poles
     2     t = turtle.Turtle()
     3     t.hideturtle()
     4     def drawpole_1(k):
     5         t.up()
     6         t.pensize(10)
     7         t.speed(100)
     8         t.goto(400*(k-1), 100)
     9         t.down()
    10         t.goto(400*(k-1), -100)
    11         t.goto(400*(k-1)-20, -100)
    12         t.goto(400*(k-1)+20, -100)
    13     drawpole_1(0)#画出汉诺塔的poles[0]
    14     drawpole_1(1)#画出汉诺塔的poles[1]
    15     drawpole_1(2)#画出汉诺塔的poles[2]

    三、制造汉诺塔的盘子

    汉诺塔当然少不了盘子了,我们要写一段代码来绘制若干个盘子,代码如下:

     1 def creat_plates(n):#制造n个盘子
     2     plates=[turtle.Turtle() for i in range(n)]
     3     for i in range(n):
     4         plates[i].up()
     5         plates[i].hideturtle()
     6         plates[i].shape("square")
     7         plates[i].shapesize(1,8-i)
     8         plates[i].goto(-400,-90+20*i)
     9         plates[i].showturtle()
    10     return plates

    四、制造一个底座的栈

    栈:栈作为一种数据结构,是一种只能在一端进行插入和删除操作。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。

    此处使用的栈并非Python中真正意义上的栈,而是与之意思相仿的说法,我们都知道,汉诺塔必须将最上的盘子取走方可移动第二层的盘子,以此类推,不移动上方的盘子,就无法移动下方的盘子,废话不多说,来看看这个代码吧:

    1 def pole_stack():#制造poles的栈
    2     poles=[Stack() for i in range(3)]
    3     return poles

    五、设计移动盘子的代码

    准备完前面的工作,现在就要开始移动盘子了,代码如下:

    1 def moveDisk(plates,poles,fp,tp):#把poles[fp]顶端的盘子plates[mov]从poles[fp]移到poles[tp]
    2     mov=poles[fp].peek()
    3     plates[mov].goto((fp-1)*400,150)
    4     plates[mov].goto((tp-1)*400,150)
    5     l=poles[tp].size()#确定移动到底部的高度(恰好放在原来最上面的盘子上面)
    6     plates[mov].goto((tp-1)*400,-90+20*l)

    六、设计操控盘子移动方向的代码

    可以移动盘子了当然还不够,只是胡乱地移动无法解决汉诺塔问题,我们要让盘子向着能够解决问题的方向移动,代码如下:

    1 def moveTower(plates,poles,height,fromPole, toPole, withPole):#递归放盘子
    2     if height >= 1:
    3         moveTower(plates,poles,height-1,fromPole,withPole,toPole)
    4         moveDisk(plates,poles,fromPole,toPole)
    5         poles[toPole].push(poles[fromPole].pop())
    6         moveTower(plates,poles,height-1,withPole,toPole,fromPole)

    七、调用

    终于完成了全部准备工作,现在就来调用函数,让他们一起发挥作用吧!

     1 import turtle
     2  
     3 class Stack:
     4     def __init__(self):
     5         self.items = []
     6     def isEmpty(self):
     7         return len(self.items) == 0
     8     def push(self, item):
     9         self.items.append(item)
    10     def pop(self):
    11         return self.items.pop()
    12     def peek(self):
    13         if not self.isEmpty():
    14             return self.items[len(self.items) - 1]
    15     def size(self):
    16         return len(self.items)
    17  
    18 def drawpole_3():#画出汉诺塔的poles
    19     t = turtle.Turtle()
    20     t.hideturtle()
    21     def drawpole_1(k):
    22         t.up()
    23         t.pensize(10)
    24         t.speed(100)
    25         t.goto(400*(k-1), 100)
    26         t.down()
    27         t.goto(400*(k-1), -100)
    28         t.goto(400*(k-1)-20, -100)
    29         t.goto(400*(k-1)+20, -100)
    30     drawpole_1(0)#画出汉诺塔的poles[0]
    31     drawpole_1(1)#画出汉诺塔的poles[1]
    32     drawpole_1(2)#画出汉诺塔的poles[2]
    33  
    34 def creat_plates(n):#制造n个盘子
    35     plates=[turtle.Turtle() for i in range(n)]
    36     for i in range(n):
    37         plates[i].up()
    38         plates[i].hideturtle()
    39         plates[i].shape("square")
    40         plates[i].shapesize(1,8-i)
    41         plates[i].goto(-400,-90+20*i)
    42         plates[i].showturtle()
    43     return plates
    44  
    45 def pole_stack():#制造poles的栈
    46     poles=[Stack() for i in range(3)]
    47     return poles
    48  
    49 def moveDisk(plates,poles,fp,tp):#把poles[fp]顶端的盘子plates[mov]从poles[fp]移到poles[tp]
    50     mov=poles[fp].peek()
    51     plates[mov].goto((fp-1)*400,150)
    52     plates[mov].goto((tp-1)*400,150)
    53     l=poles[tp].size()#确定移动到底部的高度(恰好放在原来最上面的盘子上面)
    54     plates[mov].goto((tp-1)*400,-90+20*l)
    55  
    56 def moveTower(plates,poles,height,fromPole, toPole, withPole):#递归放盘子
    57     if height >= 1:
    58         moveTower(plates,poles,height-1,fromPole,withPole,toPole)
    59         moveDisk(plates,poles,fromPole,toPole)
    60         poles[toPole].push(poles[fromPole].pop())
    61         moveTower(plates,poles,height-1,withPole,toPole,fromPole)
    62  
    63 myscreen=turtle.Screen()
    64 drawpole_3()
    65 n=int(input("请输入汉诺塔的层数并回车:
    "))
    66 plates=creat_plates(n)
    67 poles=pole_stack()
    68 for i in range(n):
    69     poles[0].push(i)
    70 moveTower(plates,poles,n,0,2,1)
    71 myscreen.exitonclick()

    八、效果

    首先输入一下我们想测试的汉诺塔层数,为节省时间我就选择了3层

    下面是移动过程

    看来效果还不错,这样汉诺塔的可视化就实现啦!

  • 相关阅读:
    Java泛型
    Java多态
    Anaconda+pycharm配置pytorch1.1.0+cuda 9.0+python3.7环境
    anaconda+fbprophet安装
    pycharm显示所有的tabs
    联想拯救者15-isk安装固态硬盘与系统迁移教程
    VS2017 C++操作mysql数据库
    mfc动态演示排序算法
    模拟处理机作业调度---短作业优先调度算法
    P3327 [SDOI2015]约数个数和
  • 原文地址:https://www.cnblogs.com/ReganWhite/p/10595719.html
Copyright © 2011-2022 走看看