本文实现了一个完整的Hanoi塔问题动态演示程序,由用户输入盘子数,盘子数目限定在1至10之间,盘子太多,屏幕显示不下。程序编写、运行环境为windows xp+vb6.0,屏幕分辩率为1024×768。
Dim i As Integer, j As Integer, k As Integer 'i、k表示纵坐标,j表示横坐标
Form1.Caption = "汉诺塔问题-第" & n & "个盘子正在移动..."
'向上移动到first柱子顶端
For i = baseCoordinateY(pillarnum(getone)) To 600 - 210 Step -stepC
'把矩形本次移动前的图形擦掉
Form1.Line ((pillarnum(getone) * 4000 - (n * 400) / 2), i)-((pillarnum(getone) * 4000 + (n * 400) / 2), i + 200), Form1.BackColor, BF
fixpillar (getone)
Form1.Line ((pillarnum(getone) * 4000 - (n * 400) / 2), i - stepC)-((pillarnum(getone) * 4000 + (n * 400) / 2), i - stepC + 200), , BF
delay
Next i
'当前i =600-200-stepC,此时i值表示盘子的当前纵坐标
'向左、右平移到third柱子顶端
If pillarnum(getone) < pillarnum(putone) Then
'向右移
For j = (pillarnum(getone) * 4000 - (n * 400) / 2) To (pillarnum(putone) * 4000 - (n * 400) / 2) - stepC Step stepC
Form1.Line (j, i)-(j + n * 400, i + 200), Form1.BackColor, BF
Form1.Line (j + stepC, i)-(j + stepC + n * 400, i + 200), , BF
delay
Next j
Else
'向左移
For j = (pillarnum(getone) * 4000 - (n * 400) / 2) To (pillarnum(putone) * 4000 - (n * 400) / 2) + stepC Step -stepC
Form1.Line (j, i)-(j + n * 400, i + 200), Form1.BackColor, BF
Form1.Line (j - stepC, i)-(j - stepC + n * 400, i + 200), , BF
delay
Next j
End If
'向下移动到third柱子底端
For k = i To baseCoordinateY(pillarnum(putone)) - 210 - stepC Step stepC
'把矩形本次移动前的图形擦掉
Form1.Line ((pillarnum(putone) * 4000 - (n * 400) / 2), k)-((pillarnum(putone) * 4000 + (n * 400) / 2), k + 200), Form1.BackColor, BF
fixpillar (putone)
Form1.Line ((pillarnum(putone) * 4000 - (n * 400) / 2), k + stepC)-((pillarnum(putone) * 4000 + (n * 400) / 2), k + stepC + 200), , BF
delay
Next k
'最后在柱子底端再补画一次高度为210的矩形,
'因为k循环最后一次执行循环体时,k值未必正好等于循环终值baseCoordinateY(pillarnum(putone)) - 210 - stepC,
'所以要补一个上沿纵坐标为baseCoordinateY(pillarnum(putone)) - 210 - stepC矩形
Form1.Line ((pillarnum(putone) * 4000 - (n * 400) / 2), k)-((pillarnum(putone) * 4000 + (n * 400) / 2), k + 200), Form1.BackColor, BF
fixpillar (putone)
Form1.Line ((pillarnum(putone) * 4000 - (n * 400) / 2), baseCoordinateY(pillarnum(putone)) - 210)-((pillarnum(putone) * 4000 + (n * 400) / 2), baseCoordinateY(pillarnum(putone)) - 210 + 200), , BF
'更新各柱子最面一个盘子上沿的纵坐标
baseCoordinateY(pillarnum(getone)) = baseCoordinateY(pillarnum(getone)) + 210
baseCoordinateY(pillarnum(putone)) = baseCoordinateY(pillarnum(putone)) - 210
End Sub
Private Function pillarnum(ch As String) As Integer
pillarnum = Asc(ch) + 1 - Asc("A")
End Function
Private Sub fixpillar(pillarABC As String)
'纵坐标减10只是为了显示时看的效果更好一些,其实是不应该减的,减了后柱子底端纵坐标与底线上沿纵坐标就不一致了
If pillarnum(pillarABC) < 3 Then
Form1.Line (pillarnum(pillarABC) * 4000 - 5, 700)-(pillarnum(pillarABC) * 4000 + 5, hLevel - 10), vbBlack, BF '修补柱子
Else
Form1.Line (pillarnum(pillarABC) * 4000 - 5, 700)-(pillarnum(pillarABC) * 4000 + 8, hLevel - 10), vbBlack, BF '修补柱子
End If
另外,需要注意的一点是当盘子垂直移动时,在盘子的原位置重新绘制盘子为窗体背景色时,由于会导致一段柱子也会被覆盖成窗体背景色,因此在原位置绘制盘子为背景色之后应立即重新绘制一次柱子。
由于目前技术水平下PC机的CPU性能比较高,程序的执行时间非常短,为了得到一个适度缓慢的盘子移动速度,在盘子移动到下一个位置时应该暂停一个时间段。本程序中通过设置一个延迟函数以达到目的,当盘子从子路径的一端移动到另一端时立即调用自定义延迟函数delay(),delay()函数只是起到暂停程序执行的作用,不执行任何改变盘子现状的指令。一个delay()函数的例子如下:
Private Sub delay()
Dim tt As Double
tt = Timer
While Timer - tt < 0.001 '延迟
DoEvents
Wend
End Sub
4 结束语
本文实现了一个完整的Hanoi塔问题动态演示程序,由用户输入盘子数,盘子数目限定在1至10之间,盘子太多,屏幕显示不下。程序编写、运行环境为windows xp+vb6.0,屏幕分辩率为1024×768。
3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.com/exam/