zoukankan      html  css  js  c++  java
  • python汉诺塔问题

    python汉诺塔问题

    实现python汉诺塔动画,需要分成两个部分来进行:

    (1)绘制塔和圆盘

    (2)移动绘制后的形状

    这里需要用到递归

    1、递归的定义:间接或直接调用自身的函数被称为递归函数。

    2、递归三原则

    (1)要有个基础条件,来退出递归

    (2)递归过程要向1靠拢

    (3)要不断的调用自身

    一、思路分析

    移动过程

    设 A塔是圆盘出发的塔,称之为起点塔
        C塔是圆盘最终要达到的塔,称之为目标塔
        B塔起辅助中转作用,称之为中转塔

    当n=1时,只需要将盘1从起点塔A移动到目标塔C即可。

    当n=2时,需要将盘1从起点塔A移动到中转塔B,

                           再将盘2从起点塔A移动到目标塔C,

                           最后将盘1从中转塔B移动到目标塔C即可。

    当n=3时,先将盘12看做一个整体从起点塔A移动到中转塔B,

                          再将盘3从起点塔A移动到目标塔C,

                          最后将盘12作为一个整体从中转塔B移动到目标塔C即可。

                         (参照n=2)

    当n=k时, 先将盘1到k-1看做一个整体从起点塔A移动到中转塔B,

                          再将盘k从起点塔A移动到目标塔C,

                          最后将盘1到k-1作为一个整体从中转塔B移动到目标塔C即可。

    以下以三层汉诺塔为例。

    1、首先,定义一个moveDisk(diskIndex,fromPole,toPole) 函数:移动指定层圆盘diskIndex,从fromPole出发,到达toPole

    def moveDisk(diskIndex, fromPole, toPole):
    	print_str = 'Move disk %s form %s to %s' % (diskIndex,fromPole,toPole)
    	print(print_str)
    

      

    2、接下来,定义一个movetower函数,其中,WithPole表示中转塔B

    def moveDisk(diskIndex,fromPole,toPole):
    	print_str = 'Move disk %s form %s to %s' % (diskIndex, fromPole,,toPole)
    	print(print_str)
    
    def moveTower(height, fromPole, withPole,,toPole):
    	if height == 1 :
    		moveDisk(1,fromPole,,toPole)
    	else:
    		moveTower(height-1,fromPole,,toPole, withPole)
    		moveDisk(height,fromPole,,toPole)
    		moveTower(height-1, withPole,fromPole,,toPole)
    
    if __name__ == '__main__':
    	moveTower(3, "A", "B", "C")
    

      

    3、绘制塔和圆盘

    turtle函数 作用
    turtle.begin_poly() 开始记录多边形的顶点。当前的乌龟位置是多边形的第一个顶点。
    turtle.end_poly() 停止记录多边形的顶点。当前的乌龟位置是多边形的最后一个顶点。将与第一个顶点相连。
    turtle.get_poly() 返回最后记录的多边形。
    turtle.hideturtle() 隐藏画笔的turtle形状


    register函数用于注册程序退出时的回调函数,然后在回调函数中做一些资源清理的操作

    import turtle
    
    size = 20
    TowerP=5    # Tower的线宽
    TowerW=100  # Tower的底座宽度
    TowerH=200  # Tower的高度
    TowerSpace=260  # Tower的之间的距离,从中心到中心
    HORIZON=-100    # Tower的底座高度,用于定位
    towerD = 250
    towerA = -100
    
     
    # 设置圆盘形状
    def set_plate(i):
        l = size * (i+2) 
        t = turtle.Turtle()
        t.hideturtle()
        t.penup()
        t.begin_poly()
        t.left(90)
        t.forward(l)
        t.circle(size, 180)
        t.forward(l * 2)
        t.circle(size, 180)
        t.forward(l)
        t.end_poly()
        p = t.get_poly()
        turtle.register_shape("plate_%s"%i, p)
     
     
    # 设置塔柱形状
    def set_tower():
        t = turtle.Turtle()
        t.hideturtle()
        t.penup()
        t.begin_poly()
        t.left(90)
        t.forward(TowerW)
        t.circle(-TowerP, 180)
        t.forward(TowerW)
        t.forward(TowerW)
        t.circle(-TowerP, 180)
        t.forward(TowerW-TowerP/2)
     
        t.left(90)
        t.forward(TowerH)
        t.circle(-TowerP, 180)
        t.forward(TowerH)
        t.end_poly()
        p = t.get_poly()
        SCR.register_shape('tower', p)
     
     
    # 绘制塔柱
    def draw_towers():
        set_tower()
        tower = turtle.Turtle("tower")
        tower.penup()
        tower.goto(-towerD,towerA)
        tower.stamp()
        tower.goto(0,towerA)
        tower.stamp()
        tower.goto(towerD,towerA)
     
     
    # 绘制圆盘
    def draw_plates(pn):
        plates=[]
        for i in range(pn):
            set_plate(i)
            _plate='plate_%s'%i
            pi=turtle.Turtle(_plate)
            pi.penup()
            plates.append(pi)
        return plates
    

    最后,将绘制函数和移动函数结合起来

    import turtle
    
    size = 20
    TowerP=5    # Tower的线宽
    TowerW=100  # Tower的底座宽度
    TowerH=200  # Tower的高度
    TowerSpace=260  # Tower的之间的距离,从中心到中心
    HORIZON=-100    # Tower的底座高度,用于定位
    towerD = 250
    towerA = -100
    
    #记录塔的位置
    tower_loc = {
        "A":-1,
        "B":0,
        "C":1,
    }
    
    #记录塔上有几个圆盘
    tower_poles = {
        "A":[],
        "B":[],
        "C":[],
    }
    
    # 建立窗体
    SCR=turtle.Screen()
    # SCR.tracer()
    SCR.setup(800,600) #设置窗体大小
     
     
    # 设置圆盘形状
    def set_plate(i):
        l = size * (i+2) 
        t = turtle.Turtle()
        t.hideturtle()
        t.penup()
        t.begin_poly()
        t.left(90)
        t.forward(l)
        t.circle(size, 180)
        t.forward(l * 2)
        t.circle(size, 180)
        t.forward(l)
        t.end_poly()
        p = t.get_poly()
        turtle.register_shape("plate_%s"%i, p)
     
     
    # 设置塔柱形状
    def set_tower():
        t = turtle.Turtle()
        t.hideturtle()
        t.penup()
        t.begin_poly()
        t.left(90)
        t.forward(TowerW)
        t.circle(-TowerP, 180)
        t.forward(TowerW)
        t.forward(TowerW)
        t.circle(-TowerP, 180)
        t.forward(TowerW-TowerP/2)
     
        t.left(90)
        t.forward(TowerH)
        t.circle(-TowerP, 180)
        t.forward(TowerH)
        t.end_poly()
        p = t.get_poly()
        SCR.register_shape('tower', p)
     
     
    # 绘制塔柱
    def draw_towers():
        set_tower()
        tower = turtle.Turtle("tower")
        tower.penup()
        tower.goto(-towerD,towerA)
        tower.stamp()
        tower.goto(0,towerA)
        tower.stamp()
        tower.goto(towerD,towerA)
     
     
    # 绘制圆盘
    def draw_plates(pn):
        plates=[]
        for i in range(pn):
            set_plate(i)
            _plate='plate_%s'%i
            pi=turtle.Turtle(_plate)
            pi.penup()
            plates.append(pi)
        return plates
    
     
    # 绘制移动过程
    def draw_move(plate,fromPole,toPole):
        to_x = tower_loc[toPole] * towerD
        toPole_count = len(tower_poles[toPole])
        to_y = towerA +2 * TowerP + toPole_count * size * 2
        if fromPole:
            tower_poles[fromPole].remove(plate)
        plate.goto(to_x,to_y)
        tower_poles[toPole].append(plate)
        
     
     
    # 移动指定层圆盘diskIndex,从fromPole出发,到达toPole
    def moveDisk(diskIndex,fromPole,toPole):
    
        draw_move(diskIndex, fromPole, toPole)
     
     
    # 核心函数,入口
    def moveTower(height,fromPole, withPole, toPole,plates):
        if height == 1:
            draw_move(plates[0],fromPole, toPole)
        else:
            moveTower(height-1,fromPole,toPole,withPole,plates)
            draw_move(plates[height-1],fromPole,toPole)
            moveTower(height-1,withPole,fromPole,toPole,plates)
     
     
    if __name__ == '__main__':
        draw_towers()
        n=3
        plates=draw_plates(n)
        for i in range(n):
            draw_move(plates[n-1-i],'','A')
        moveTower(n,"A","B","C",plates)
        turtle.done()
    

     

      

      

     

  • 相关阅读:
    将一张图片的人物融入另一张图片中
    填充---内容识别图片
    使用蒙版--渐变--制作瓶子倒影
    form表单基础知识
    表格排版及其表格嵌套
    HTML表格,table,thead,tbody,tfoot,th,tr,td,的属性以及跨行,跨列
    垃圾收集,内存问题
    JS预解析机制
    python ==》 内置函数
    python ==》 递归
  • 原文地址:https://www.cnblogs.com/deng11/p/12594078.html
Copyright © 2011-2022 走看看