Í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 NewDelay, Crt, Graph;
Const Db=12;
Var Mx, My, Gd, Gm: Integer;
Lsz: Integer;
Type TKor= Object
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 Ws: String;
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, Mx, My, ClipOff);
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 KorT: Array[1..Db] Of TKor;
Darab: Array['a'..'c'] Of Byte;
Procedure KorongAtr(N: Byte; F, G: Char);
Var E: Byte;
Ws: String;
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, Mx, My, ClipOff);
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-
KorongAtr(N, A, B);
ToronyAtr(N-
If KeyPressed Then Halt;
End;
End;
Procedure GrInit;
Var Gd, Gm: integer;
Begin
DetectGraph(Gd, Gm);
InitGraph(Gd, Gm, 'C:\TP\BGI');
Mx:= GetMaxX; My:= GetMaxY;
End;
Procedure Start;
Var I: Byte; X, Y, D, V, T: Integer; Ch: Char;
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.