Írjunk programot, mely a közismert Hanoi tornyai játékot mutatja be grafikus képernyőn. A korongok áthelyezése animációs legyen, azaz a korong induljon el az aktuális helyéről, és a valóságos mozgáshoz hasonlóan, foglalja el az új helyét. (Aki nem ismerné: egy oszlopon egyre csökkenő méretű korongok vannak. További két üres oszlop áll rendelkezésünkre, hogy a korongokat egy másik oszlopra áthelyezzük. Egyszerre csak egy korongot rakhatunk át, és az átrakás során soha nem fordulhat elő, hogy kisebb korongra ráhelyezünk egy nagyobbat.)

 

         A program futásának egy pillanata, ahol kezdetben minden korong az a jelű oszlopon volt, és a 101. lépés után a program le lett állítva:

 

 

         És a program listája:

 

Program Hanoi;

Uses NewDelayCrtGraph;

Const Db=12;

Var MxMyGdGm: Integer;
    Lsz: Integer;

Type TKorObject
             FX, FY, FD, FV, FS: Integer;
             Procedure Init(IX, IY, ID, IV, IS: Integer);
             Procedure Show;
             Procedure Hide;
             Procedure MoveRel(DX, DY: Integer);
             Function GetX: Integer;
             Function GetY: Integer;
             Function GetV: Integer;
           End;

Procedure TKor.Init(IX, IY, ID, IV, IS: Integer);
Begin
  FX:= IX; FY:= IY; FD:= ID; FV:= IV; FS:= IS;
End;

Procedure TKor.Show;
Var WsString;
Begin
  Bar(FX-FD, FY, FX, FY+FV);
  Bar(FX+Round(0.022*Mx), FY, 

      FX+FD+Round(0.022*Mx), FY+FV);
  SetTextStyle(0,0,1);
  SetColor(6);
  Str(FS, Ws);
  OutTextXY(FX-FD+2,FY+2, Ws);
End;

Procedure TKor.Hide;
Begin
  SetViewPort(FX-FD, FY, FX, FY+FV, ClipOn);
  ClearViewPort;
  SetViewPort(FX+Round(0.022*Mx), FY, 

              FX+FD+Round(0.022*Mx), FY+FV, ClipOn);
  ClearViewPort;
  SetViewPort(0, 0, MxMyClipOff);
End;

Procedure TKor.MoveRel(DX, DY: Integer);
Begin
  Hide; FX:= FX+DX; FY:= FY+DY; Show
End;

Function TKor.GetX: Integer;
Begin
  GetX:=FX;
End;

Function TKor.GetY: Integer;
Begin
  GetY:= FY;
End;

Function TKor.GetV: Integer;
Begin
  GetV:=FV;
End;

Const Ac=0.144; Bc=0.484; Cc=0.824;

Var KorTArray[1..Db] Of TKor;
    Darab: Array['a'..'c'] Of Byte;

Procedure KorongAtr(N: Byte; F, G: Char);
Var E: Byte;
    WsString;
Begin
  If (F='a') And (G='b') Then E:=1;
  If (F='b') And (G='c') Then E:=2;
  If (F='c') And (G='a') Then E:=3;
  If (F='a') And (G='c') Then E:=4;
  If (F='b') And (G='a') Then E:=5;
  If (F='c') And (G='b') Then E:=6;
  While KorT[N].GetY>0.3*My Do KorT[N].MoveRel(0,-1);
  Dec(Darab[F]);
  With KorT[N] Do

  Case E of
      1: While GetX<Bc*Mx Do MoveRel(1,0);
    2,4: While GetX<Cc*Mx Do MoveRel(1,0);
    3,5: While GetX>Ac*Mx Do MoveRel(-1,0);
      6: While GetX>Bc*Mx Do MoveRel(-1,0);
  End;
  While KorT[N].GetY<0.87*My-Darab[G]*1.5*KorT[N].GetV Do
  KorT[N].MoveRel(0,1);
  Inc(Darab[G]);
  Inc(Lsz);
  SetViewPort(Mx-100, 0, Mx, 100, ClipOn);
  ClearViewPort;
  SetViewPort(0, 0, MxMyClipOff);
  Str(Lsz,Ws);
  SetTextStyle(0,0,3);
  OutTextXY(Mx-100,2, Ws);
End;

Procedure ToronyAtr(N: Byte; A, B, C: Char);
Begin
  If N>0 then
  Begin
    ToronyAtr(N-1, A, C, B);
    KorongAtr(N, A, B);
    ToronyAtr(N-1, C, B, A);
    If KeyPressed Then Halt;
  End;
End;

Procedure GrInit;
Var GdGm: integer;
Begin
  DetectGraph(GdGm); 

  InitGraph(GdGm, 'C:\TP\BGI');
  Mx:= GetMaxXMy:= GetMaxY;
End;

Procedure Start;
Var I: Byte; X, Y, D, V, T: Integer; ChChar;
Begin
  SetColor(14);
  SetTextStyle(0,0,3);
  OutTextXY(150,10, 'Hanoi tornyai');
  Bar(0,Round(0.9*My),Mx,Round(0.91*My));
  Bar(Round(0.15*Mx),Round(0.4*My),

      Round(0.16*Mx),Round(0.9*My));
  Bar(Round(0.49*Mx),Round(0.4*My),

      Round(0.50*Mx),Round(0.9*My));
  Bar(Round(0.83*Mx),Round(0.4*My),

      Round(0.84*Mx),Round(0.9*My));
  SetColor(15);
  SetTextStyle(0,0,2);
  OutTextXY(Round(0.146*Mx),Round(0.93*My), 'a');
  OutTextXY(Round(0.486*Mx),Round(0.93*My), 'b');
  OutTextXY(Round(0.836*Mx),Round(0.93*My), 'c');
  For I:= 1 To Db Do
  Begin
    V:= Round(0.02*My);
    T:= Round(1.5*V);
    D:= Round((0.02+I*0.01)*Mx);
    X:= Round(0.144*Mx);
    Y:= Round(0.87*My-(Db-I)*T);
    KorT[I].Init(X, Y, D, V, I);
    KorT[I].Show;
  End;
  Darab['a']:= Db;
  For Ch:= 'b' To 'c' Do Darab[Ch]:= 0;
End;

Begin
  GrInit;
  Start;
  Lsz:= 0;
  ToronyAtr(Db, 'a','b','c');
  SetTextStyle(0,0,3);
  OuttextXY(150,120,'Kész');
  Readkey;
  CloseGraph;
End.