用VB编写Hanoi塔问题的动态演示程序
来源:优易学  2011-3-3 11:01:00   【优易学:中国教育考试门户网】   资料下载   IT书店

 

 3.2 盘子移动的实现
  盘子的移动过程主要有两种类型的移动,一种是垂直移动(包括自上而下和自下而上),另一种是水平移动(包括从左至右和从右至左)。盘子移动过程程序实现的主要思想是将每一次盘子从原位置移动到目标位置的路线分割成足够多的子路径,每个子路径的距离足够小,盘子从某子路径一端移动至另一端通过两个步骤来实现:第一步将原位置上的套友丈柚梦猣orm窗体背景色Form1.
  BackColor,以达到将盘子从原位置移开的显示效果;第二步在盘子将要到达的新位置重新绘制该盘子,从而达到盘子移动到另一端的显示效果。
  例如某个用Form1.Line (4000, i)-( 4000 +400), i + 200)语句绘制的长为400像素、宽为200像素的盘子需要从矩形左上角坐标为(4000, i)的位置垂直向上移动到下一位置,则可能将该矩形在原位置重新绘制成窗体背景色,在矩形左上角坐标为(4000, i-stepC)位置重新绘制一个矩形来达到将该矩形从位置(4000, i)移动到位置(4000, i-stepC)的目的,其中stepC是移动步长,也即子路径的长度。stepC值不能设置的过大,如果设置的太大,则盘子移动过程中将会出现不连续的移动效果。盘子移动过程程序实现的核心代码如下:
  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。

上一页  [1] [2] 

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训