python123汉诺塔实践_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()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值