{ ╔═════════════════════════════════════════════════════════════════════════╗ }
{ ║   Hussein Suleman    :  "it's a kinda magic"  :   Durban, RSA           ║ }
{ ╟─────────────────────────────────────────────────────────────────────────╢ }
{ ║  Package  : Towers of Hanoi                                             ║ }
{ ║  Descrip. : Solution to famous recursive problem                        ║ }
{ ║  Date     : 05/91                  Version : 1.0                        ║ }
{ ║  Language : Turbo Pascal v6.0                                           ║ }
{ ╚═════════════════════════════════════════════════════════════════════════╝ }

program Towers_of_Hanoi;
uses Crt;

type
   TowerType       = record
                        Pos            : array [1..20] of byte;
                        No             : byte;
                     end;

const
   MaxHeight       = 10;

var
   i               : integer;
   Tower           : array [1..3] of TowerType;


procedure WriteBlock ( tow, block : byte ; state : boolean );
var
   a,
   Axis            : integer;
begin
   case tow of
      1 : Axis:=13;
      2 : Axis:=40;
      3 : Axis:=67;
   end;
   GotoXY ((Axis-Tower[tow].Pos[block]), (23-block));
   For a:=1 to Tower[tow].Pos[block] do
      If state
         then
            Write ('▓▓')
         else
            Write ('  ');
   Writeln;
end;

procedure MoveBlock ( source, dest : byte );
begin
   Inc (Tower[dest].No);
   Tower[dest].Pos[Tower[dest].No]:=Tower[source].Pos[Tower[source].No];
   Dec (Tower[source].No);
   Delay (100);
end;

procedure MoveTower ( source, dest, size : byte );
begin
   If size=0
      then
         Exit;
   If size=1
      then
         MoveBlock (source, dest)
      else
         begin
            MoveTower (source, (6-source-dest), size-1);
            MoveBlock (source, dest);
            MoveTower ((6-source-dest), dest, size-1);
         end;
end;


begin

   ClrScr;

   For i:=1 to MaxHeight do
      begin
         Tower[1].Pos[i]:=i;
         Tower[2].Pos[i]:=0;
         Tower[3].Pos[i]:=0;
      end;

   Tower[1].No:=MaxHeight;
   Tower[2].No:=0;
   Tower[3].No:=0;

   For i:=1 to MaxHeight do
      begin
         WriteBlock (1, Tower[1].Pos[i], true);
      end;

   MoveTower (1, 3, MaxHeight);

end.
