小信息学复赛题汉诺塔LOGO编程详解A

厦门市教育局-市科协官方联办的2023年小学生LOGO语言竞赛复赛
“汉诺塔”动态作图题是一个值得深入研究的练习题。汉诺塔是一个源远流长的经典命题。无论是小学还是中学的任何一门编程语言(LOGO、C、C++、PASCAL、PYTHON、VB、QB)差不多都会讨论到汉诺塔编程。但SCRATCH是不讨论汉诺塔编程的,且使用C++语言、PASCAL等语言编程一般都只能以文字输出结果,难以用图形输出显示。所有的教程、教科书都教你使用“递归”编程——用递归编程4层的LOGO汉诺塔的范例在MSWLogo-FMSLogo自带的演示程序里面就有一个,但是这个“原装”的程序毛病多多,画图中“盘”会出现许多不连续的“断口”,大家可以自己打开来运行看看。而厦门地区的这道题明确只运行3层的汉诺塔,除了初始状态画面外,总共只有7个画面,其实可以另辟蹊径用“依样画葫芦”的方式来画。这样的编程思路非常地“不传统”、“不经典”,可是难度就大大降低了,在参赛中会省下不少时间。我们小学生自己编写的汉诺塔LOGO程序,无论是“依样画葫芦”式的,还是“递归”式的,似乎都要比LOGO编程系统中自带的演示程序要强许多——所有人都可以自己来评判一下。
现在来考虑怎么使用“依样画葫芦”的方式来画3层的汉诺塔:
1.
我们定义从大到小的盘号:ph变量为3、2、1。
2.
3个盘的颜色(画框的颜色及填充色)是:ph*2。对应的颜色是6、4、2,就是黄红绿三种颜色。
3.
每个盘都是从底部中央用3个Π门框形的“半框”组成的。半框的宽度:bank可以这样子计算::ph*20+20。这就满足了题目中要求三个盘宽度为160、120、80的要求。
先画两个Π“半框”,然后移动到完整框中填色,再移动会到框底中央,接着画第3个Π“半框”移动到盘的上方中央。这有个好处,上面如果还有盘方便继续画,没有盘了就画中央直立的黑色的杆。
4.
我们所说的“依样画葫芦”是定义3、2、1盘的8个画面(初始状态加上移动的7个画面)的“动作表”,其实是每一个画面3
根杆上盘的分布状态表:
make "dzb [ ;定义搬盘运动作的表
[321 0 0]
[32 0 1]
[3 2 1]
[3 21 0]
[0 21 3]
[1 2 3]
[1 0 32]
[0 0 321]]
这个表的数据很简单,如果看不懂就无法理解整个程序。这是整个程序的核心。
5. 现在我们用for[i 1
8][ ];显示从初始状态到搬运完成的8个画面
每个画面依次读取一组类似[321 0
0]这样的数据,分别表示3根杆上各有哪些盘。有321数字的就有对应的盘。在单个321数字中,左边数字的盘在下面,右边数字的盘在上面,数字为0的杆上没有盘。
画好一个画面按照题目要求wait
50延时,然后CS清屏,再读取下一组数据继续画。
用一个hzz画塔盘子程序画所有8个画面的汉诺塔,真正是“依样画葫芦”,找规律画图,其中并没有任何“递归”运算操作。
这种不包含递归的汉诺塔编程,在所有的类似编程中是独树一帜的,巧妙、简单、易懂、高效。
源程序:
to hnt_3
make "dzb
[ ;定义搬盘运动作的表
[321 0 0]
[32 0 1]
[3 2 1]
[3 21 0]
[0 21 3]
[1 2 3]
[1 0 32]
[0 0 321]]
for[i 1
8][ ;显示从初始状态到搬运完成的8个画面
make "zt item :i :dzb ;读取当前画面状态数据
cs ht
pu setxy -350 -2
;画底线
setpc 0 setpensize 5
pd setx 350
for[j 1 3][
;画当前状态3个柱子上塔盘
make "dq item :j :zt
;读取当前柱子数据
pu setxy :j*200-400 0
;当前柱子底部定位
pd hzz
;调用画塔盘子程序
]
wait 50
;形成动画的时间间隔
]
end
to hzz ;画塔盘子程序
make "n count
:dq ;读取当前柱子盘层数
if
:dq<>0[
;只有数据不为0才有盘子可画
for[k 1 :n][
;画n层盘子
make "ph item :k
:dq ;读取要画的这一个盘号
setpensize 1
setpc :ph*2
;盘的线条颜色
setfc :ph*2
;盘的填充色
make "bank :ph*20+20
;计算盘的半个宽度
pd lt 90 hbk
hbk
;画盘框
pu rt 90 fd 10 pd
fill ;画好整个盘后填色
pu bk 10 lt 90 hbk lt 90
;运动到盘的上中点
]
pd setpc 0 setpensize 5 sety 100
;画顶部剩余柱子
]
if :dq=0
[
;画无塔盘的空柱子
pd setpc 0 setpensize 5 fd 100
]
end
to hbk ;画盘子半个框的子程序
pd
fd :bank rt 90 fd 20 rt 90 fd :bank
end
加载中,请稍候......