to hnt_a :n
;汉诺塔问题
:n是塔的层数 建议不超过20层
cs ht
;pu setxy -100 150 seth 90
pd label "超级图形化编程汉诺塔 ;显示文字提示
;seth 0 pu
;setxy -240 -90
;画图形外框
;pd repeat 2[fd 280 rt 90
fd 480 rt 90]pu
;setactivearea [-250 -100 250 200]
;设定获取GIF图像区域
;make "append
"false
;设定:append附加变量为"false
make "aa
"a
;把杆号赋值给变量
make "bb "b make "cc
"c
make "ag iseq 1
:n
;建立a杆初始盘号
make "bg [] make "cg []
;建立bc杆空堆栈
make "hp
[]
;hp是画图输出时的数据中转堆栈
make "pk rseq 120/:n 120
:n ;计算1~:n号盘宽度
make "gg
25*:n+25
;计算杆的高度
make "gw (array 3
1) ;建立杆位置X坐标
for [i 1 3][setitem :i :gw
:i*125-250] ;杆的X位置
;make "hp
:ag ;hp是中转堆栈
;psx "a
stop
make "bz
0
;计算步骤数计数器清零
make "ms
selectbox[请选择输出方式][数字输出模式 图形输出模式]
if
:ms=2[
;图形输出时画底座
make
"sudu selectbox[选择显示速度][快速 中速 慢速]
setfc 1
pu setxy -200 -45 bitblock 400 43
;画底座
setpc 7
pu setxy -130 -10 seth 90 label "a
;写abc
pu setx
-3 label "b setx 121 label "c seth 0
make
"hp :ag psx "a make "hp :bg psx "b
make
"hp :cg psx "c wait 30]
;(gifsave "hnt.gif 300 :append 0)
;记录GIF动画帧间隔时间300
; make
"append "True
;语法规定:append附加变量回归"ture
move_a :n :aa :bb
:cc
end
to move_a :n :aa :bb :cc
;递归实现盘的移动
if
:n>0[
move_a
:n-1 :aa :cc :bb
make
"bz :bz+1 pri_a
move_a
:n-1 :bb :aa :cc
]
end
to pri_a
make "sc
[]
;把文字输出答案串联在:SC变量中
make "sc lput :bz :sc make
"sc lput "- :sc
make "sc lput "被移动盘 :sc
make "sc lput :n :sc
make "sc lput :aa
:sc make "sc lput "-> :sc
make "sc lput :cc
:sc
ifelse
:ms=1[
pr
:sc][
;输出文本答案
setfc 7
pu setxy -120 -73 bitblock 260 25
;在图形下面显示答案
seth 90
setpc 4 pu setxy -100 -50 label :sc seth 0
if
:aa="a [
; :a:b:c数据出栈操作
make "chu first :ag make "ag bf :ag make "hp :ag
psx "a]
if
:aa="b [
make "chu first :bg make "bg bf :bg make "hp :bg
psx "b]
if
:aa="c [
make "chu first :cg make "cg bf :cg make "hp :cg
psx "c]
if
:cc="a [make "ag fput :chu :ag make "hp :ag psx "a]
;入栈操作
if
:cc="b [make "bg fput :chu :bg make "hp :bg psx
"b]
if
:cc="c [make "cg fput :chu :cg
make "hp :cg psx "c]
]
end
to psx :name
;汉诺塔刷新子程序:name是杆号
make "hao (ascii
:name)-96 ;求杆号数组索引
make "gwz item :hao
:gw
;求杆的X位置
pu setxy :gwz-65 0
pd
;刷新原杆盘
setfc 7 bitblock 130
:gg+10
pu setxy :gwz 0 pd setpc
4 ;画杆
setpensize[4 4] fd
:gg
make "len count
:hp
;检测堆栈中盘子总数
if :len > 0
[
;必须有盘才开始画
setfc
14
;画每个盘
repeat
:len[
make "whith_ item (item (:len-repcount+1) :hp)
:pk ;读出盘宽
pu setxy :gwz-:whith_/2
(repcount-1)*25+5
;画盘
bitblock int(:whith_) 20
;这个命令只支持整数像素画图所以用int取整
]]
;(gifsave "hnt.gif
300 :append 0)
;记录GIF动画帧间隔时间300
;
make "append "True
;语法规定:append附加变量回归"ture
wait
:sudu*:sudu*8
;延时控制
end
本程序只适用于MSWLogo-FMSLogo系统
加上框和标注文字的程序语句仅能适应hnt_a
3画三层汉诺塔GIF图形
三层的汉诺塔原理搞通了
64层的道理是一样的
将程序复制黏贴到代码编辑器中就能运行