// Towers of Hanoi
//
// This program is the classical demonstration of
// recursion.
//
// Note that the current time is printed in the upper
// right corner of the window. This is done by an inter-
// rupt procedure that is called once every second.

USE Timer

PAGE

TimerEvent(1,IntProc)

DIM Number OF NumType
PRINT "The towers of HANOI"
PRINT
INPUT "Height of the tower ( 1-10): ": Number
init
Move(Number,1,2,3)

// ****   end of main program    *****

PROC Move(n OF NumType,Tower1 OF NumType,Tower2 OF NumType,Tower3 OF NumType)
  IF n>1 THEN Move(n-1,Tower1,Tower3,Tower2)
  Show(n,Tower1,Tower2)
  IF n>1 THEN Move(n-1,Tower3,Tower2,Tower1)
ENDPROC Move

PROC init
  PAGE
  DIM Height(3) OF NumType, pos(3) OF NumType
  DIM i OF NumType, y OF NumType
  Height(1):=Number
  pos(1):=5; pos(2):=30; pos(3):=55
  DIM Disk$(Number) OF 24
  DIM Empty$ OF 22
  DIM block$ OF 1
  block$:="#"
  Empty$:="                     "
  Disk$(1):="          "+block$+block$+"         "
  FOR i:=2 TO Number DO
    Disk$(i):=Disk$(i-1)(2..11)+block$+block$+Disk$(i-1)(12..21)
  ENDFOR i
  FOR i:=1 TO Number DO
    Disk$(i):=CHR$(129+i MOD 3)+Disk$(i)+CHR$(129)
  ENDFOR i
  FOR y:=20 TO 21-Number STEP -1 DO
    PRINT AT y,pos(1): Disk$(Number+y-20)
  ENDFOR y
ENDPROC init

PROC Show(n OF NumType,From OF NumType,To OF NumType)
  LOCAL x OF NumType, y OF NumType, Direction OF NumType
  x:=pos(From)
  FOR y:=20-Height(From) TO 20-Number STEP -1 DO
    PRINT AT y,x: Disk$(n)
    PRINT AT y+1,x: Empty$
  ENDFOR y
  Direction:=SGN(To-From)
  WHILE x<>pos(To) DO
    PRINT AT 20-Number,x: Disk$(n)
    x:+Direction
  ENDWHILE
  FOR y:=20-Number TO 20-Height(To) DO
    PRINT AT y,x: Disk$(n)
    PRINT AT y-1,x: Empty$
  ENDFOR y
  Height(From):=Height(From)-1; Height(To):=Height(To)+1
ENDPROC Show

PROC IntProc
  LOCAL x OF SHORT, y OF SHORT

  x:=CURCOL
  y:=CURROW
  PRINT AT 2,60: TIME$
  CURSOR  y,x
  TimerEvent(1,IntProc)
ENDPROC IntProc

TYPE NumType=LONG
