!--------------------------------------------------------------
!
! Towers of Hanoi
!
! The Towers of Hanoi is an ancient puzzle. You start with
! a set of disks on a peg, with each disk smaller than the one
! below it. There are also two other pegs that you can move the
! disks to. The puzzle is to move all of the disks from the
! starting peg to a different peg, moving one disk at a time,
! in such a way that you never put a disk on top of another
! disk that is smaller.
!
! In this graphical solution, the pegs are not shown, and the
! disks are seen from the side as colored lines.
!
! This is a classic recursion problem in programming courses.
! The solution involves learning to think about the problem
! recursively instead of algorithmicly. Instead of thinking of
! the problem of what to do with the top disk, you concentrate
! on the last move: Move all of the disks on top of the bottom
! one to the space peg, then move the bottom disk to the finish
! peg, then move all of the disks from the space peg to the
! finish peg. Of course, you can't move all of the disk on top
! of the bottom disk at once, but what worked for the bottom
! disk will work for any disk: Just move everything on top
! of the disk to a spare peg, move the disk, then move the
! stack back on top of the disk. The problem proceeds like this
! until there is only one disk to move, which is the trivial
! (or Nike) case: Just do it.
!
! Mike Westerfield
!
! Copyright 1998
! Byte Works, Inc.
!
!--------------------------------------------------------------

CONST DISKS% = 10

DIM D AS INTEGER
DIM T AS INTEGER
DIM TOWER(2, DISKS%) AS INTEGER

HGR
FOR D = 0 TO DISKS%
   FOR T = 1 TO 2
      TOWER(T, D) = 0
   NEXT
   TOWER(0, D) = DISKS% - D
   IF D <> DISKS% THEN
      CALL DRAW(0, D, DISKS% - D, DISKS% - D)
   END IF
NEXT

CALL MOVEDISK(TOWER(), (DISKS%), 0, 2, 1)

INPUT ""; A$
END


SUB DRAW (PEG AS INTEGER, HEIGHT AS INTEGER, DISK AS INTEGER, COLOR AS INTEGER)
DIM X1 AS INTEGER
DIM X2 AS INTEGER
DIM Y AS INTEGER

X1 = 50 + PEG * 100 - DISK * 2
X2 = 50 + PEG * 100 + DISK * 2
Y = 150 - HEIGHT * 3
HCOLOR= COLOR
HPLOT X1, Y TO X2, Y
END SUB


SUB MOVEDISK (TOWER() AS INTEGER, COUNT AS INTEGER, SRC AS INTEGER, DEST AS INTEGER, SPARE AS INTEGER)
DIM HEIGHT AS INTEGER
DIM DISK AS INTEGER

IF COUNT = 1 THEN
   HEIGHT = 0
   WHILE TOWER(SRC, HEIGHT + 1) <> 0
      HEIGHT = HEIGHT + 1
   WEND
   DISK = TOWER(SRC, HEIGHT)
   TOWER(SRC, HEIGHT) = 0
   CALL DRAW(SRC, HEIGHT, DISK, 0)
   HEIGHT = 0
   WHILE TOWER(DEST, HEIGHT) <> 0
      HEIGHT = HEIGHT + 1
   WEND
   CALL DRAW(DEST, HEIGHT, DISK, DISK)
   TOWER(DEST, HEIGHT) = DISK
ELSE
   CALL MOVEDISK(TOWER(), COUNT - 1, SRC, SPARE, DEST)
   CALL MOVEDISK(TOWER(), 1, SRC, DEST, SPARE)
   CALL MOVEDISK(TOWER(), COUNT - 1, SPARE, DEST, SRC)
END IF
END SUB
