home *** CD-ROM | disk | FTP | other *** search
- PROGRAM RotBarcb;
- {NOTES:}
- {*A bar is a ring on a peg}
- {*All bars use the same bitmap to restore what it has erased}
- {*A move is when a bar goes from one peg to anther}
- CONST
- kAngle = 9; {angle between each turn of the bar}
- kNumTurn = 5; {90 div 9}
- kBase = 10; {numturn * 2}
- kBarWid = 4; {width of bar div 2}
- kNumFrame = 40; {numturn * 8 }
- kPi = 3.141592654;
- kAlt = 67; {Height when bar should switch directions}
- kPeg1 = 80; {Pos of peg A}
- kPeg2 = 256; {Pos of peg B}
- kPeg3 = 432; {Pos of peg C}
- kVel = 4; {Velocity at which pegs travel}
- kMaxBar = 6; {Maximun number of bars}
- kMaxMove = 2; {Maximun number of bars moving at one time}
- kMaxQue = 100; {maximun number of elements in que}
- kDLOG = 129; {Dialog ID}
-
- TYPE
- tPeg = (A, B, C);
- tBar = 0..kMaxBar;
- tMove = 0..kMaxMove;
- tQueNum = 1..kMaxQue;
- tFrame = 0..kNumFrame;
-
- tElement = RECORD {Each element in the queue holds a move}
- fFrom : tPeg;
- fTo : tPeg;
- END;
-
- {A stack holds the bars on each peg}
- tStack = RECORD
- fElements : ARRAY[tBar] OF tBar;
- fTos : tBar;
- END;
-
- {The Que holds the moves waiting to be preformed}
- tQueue = RECORD
- fElements : ARRAY[tQueNum] OF tElement;
- fFront, fRear : tQueNum;
- END;
-
- {Hold the information for each frame of a bar}
- tBarData = RECORD
- fRgn : RgnHandle;
- fOrg : point;
- END;
-
- {Hold the information for the bar}
- {NOTES:}
- {*Memory is radically sacrificed for speed}
- {*fAlmost is used to tell MoveBars that the bar has reached its loc but}
- { it still needs to spin}
- {*When a bar is at some peg and the bar above spins it will}
- { erase the bars underneath it because they are not part of gSavePort}
- { To fix this we save the bits underneath the bar at a peg in fSaveBits}
- { and restore them after the peg moves}
- {*As much information to realated to a bar as possible is stored in tBarInfo}
- tBarInfo = RECORD
- fFrame : ARRAY[tFrame] OF tBarData; {Hold the frames of the bar}
- fInd : tFrame; {Hold the current index into fFrame}
- fLastInd : tFrame; {Hold the last index into the fFrame}
- fIndFill : tFrame; {Hold the index to the last horz frame}
- fRad : integer; {Hold the radius of the bar}
- fLoc : point; {Hold the current location of the bar}
- fDestLoc : point; {Hold the destination location}
- fVel : point; {Hold the current velocity of the bar}
- fOldRect : rect; {Hold the previous position of the bar}
- fColor : Pattern; {Hold the color of the bar}
- fAlmost : boolean; {Used to tell some proc that the bar still needs to spin}
- fSaveBits : BitMap; {Used to save the bits of gSavePort}
- fTo : tPeg; {Destination peg}
- END;
-
- {This record stores the stack of bars on it}
- {and if this peg is free to move a bar to}
- tPegInfo = RECORD
- fFree : boolean; {Peg available?}
- fBars : tStack; {Stack of bars}
- END;
-
- tBars = ARRAY[tBar] OF tBarInfo; {Hold all bars}
- tPegs = ARRAY[tPeg] OF tPegInfo; {Hold all Pegs}
- tMoveBars = ARRAY[tMove] OF tBar; {Hold moving bars}
- tPegPositions = ARRAY[tPeg] OF integer; {Hold positions of Pegs}
- tBarPositions = ARRAY[tBar] OF integer; {Hold positions of bars}
-
- VAR
- gSavePort : GrafPtr; {Hold the port which saves the image}
- gDrawPort : GrafPtr; {Hold the port to draw in}
- gNumBars : tBar; {Hold the number of bars}
- gBar : tBars; {Hold the bars}
- gPeg : tPegs; {Hold the pegs}
- gMoveQue : tQueue; {Hold the move queue}
- gMoveBar : tMoveBars; {Hold the moving bars}
- gPegPos : tPegPositions; {Hold the peg positions}
- gBarPos : tBarPositions; {Hold the bar positions}
- gEraseRgn : RgnHandle; {Hold the erase region in PlotBar to save time}
-
- {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
- {Stack routines}
- {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
-
- {*****************************************************************************}
- {Init the stack pPeg}
- {*****************************************************************************}
- PROCEDURE InitStack (pPeg : tPeg);
- BEGIN
- gPeg[pPeg].fBars.fTos := 0;
- END;
-
- {*****************************************************************************}
- {Push pBar onto the stack of pPeg}
- {*****************************************************************************}
- PROCEDURE Push (pBar : tBar;
- pPeg : tPeg);
- VAR
- lTemp : rect;
- BEGIN
- WITH gPeg[pPeg].fBars DO
- BEGIN
- fTos := fTos + 1;
- fElements[fTos] := pBar;
- END;
- WITH gBar[pBar] DO {We must Draw the bar in gSavePort}
- BEGIN
- {Calculate its rectangle on the screen}
- SetRect(lTemp, fLoc.h - fRad, fLoc.v - 4, fLoc.h + fRad, fLoc.v + 4);
- SetPort(gSavePort);
- {Save gSavePort's bits}
- CopyBits(gSavePort^.portBits, fSaveBits, lTemp, fSaveBits.bounds, srccopy, NIL);
- FillRgn(fFrame[fIndFill].fRgn, fColor); {Draw it in gSavePort}
- SetPort(gDrawPort);
- END;
- END;
-
- {*****************************************************************************}
- {Get vBar out of the stack of pPeg}
- {*****************************************************************************}
- PROCEDURE Pop (VAR vBar : tBar;
- pPeg : tPeg);
- VAR
- lTemp : rect;
- BEGIN
- WITH gPeg[pPeg].fBars DO
- BEGIN
- vBar := fElements[fTos];
- fTos := fTos - 1;
- END;
- WITH gBar[vBar] DO {Restore the saved bits}
- BEGIN
- SetRect(lTemp, fLoc.h - fRad, fLoc.v - 4, fLoc.h + fRad, fLoc.v + 4);
- CopyBits(fSaveBits, gSavePort^.portBits, fSaveBits.bounds, lTemp, srccopy, NIL);
- END;
- END;
-
- {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
- {Queue routines}
- {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
-
- {*****************************************************************************}
- {Init the Queue}
- {*****************************************************************************}
- PROCEDURE InitQue;
- BEGIN
- gMoveQue.fFront := 1;
- gMoveQue.fRear := 1;
- END;
-
- {*****************************************************************************}
- {Get the next index into the queue}
- {*****************************************************************************}
- PROCEDURE NextInd (VAR vInd : tQueNum);
- BEGIN
- IF vInd = kMaxQue THEN
- vInd := 1
- ELSE
- vInd := vInd + 1;
- END;
-
- {*****************************************************************************}
- {Enq this move}
- {*****************************************************************************}
- PROCEDURE Enq (pFrom, pTo : tPeg);
- BEGIN
- WITH gMoveQue DO
- BEGIN
- fElements[fRear].fFrom := pFrom;
- fElements[fRear].fTo := pTo;
- NextInd(fRear);
- END;
- END;
-
- {*****************************************************************************}
- {Deq the next move and put it into vElem}
- {*****************************************************************************}
- PROCEDURE Deq (VAR vElem : tElement);
- BEGIN
- WITH gMoveQue DO
- BEGIN
- vElem := fElements[fFront];
- NextInd(fFront);
- END;
- END;
-
- {*****************************************************************************}
- {Get the move to be returned at the next Deq}
- {*****************************************************************************}
- PROCEDURE TopElem (VAR vElem : tElement);
- BEGIN
- WITH gMoveQue DO
- vElem := fElements[fFront];
- END;
-
- {*****************************************************************************}
- {Return true if the que is empty}
- {*****************************************************************************}
- FUNCTION EmptyQue : boolean;
- BEGIN
- EmptyQue := gMoveQue.fFront = gMoveQue.fRear;
- END;
-
- {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
- {Drawing routines}
- {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
-
- {*****************************************************************************}
- {Plot pBar using all the info in its record}
- {*****************************************************************************}
- PROCEDURE PlotBar (pBar : tBar);
-
- { ***************************************************************************}
- { Move the regions center to the absolute location (pLoch,pLocv)}
- { ***************************************************************************}
- PROCEDURE MoveRgn (pBarData : tBarData;
- pLoch, pLocv : integer);
- VAR
- dh, dv : integer;
- BEGIN
- WITH pBarData.fRgn^^.rgnBBox, pBarData DO
- BEGIN
- OffsetRgn(pBarData.fRgn, fOrg.h - left, fOrg.v - top);
- OffsetRgn(pBarData.fRgn, pLoch, pLocv);
- END;
- END;
-
- BEGIN
- WITH gBar[pBar] DO
- BEGIN
- fInd := fInd + 1; {Inc the index}
- MoveRgn(fFrame[fInd], fLoc.h, fLoc.v); {Move the regionto the new loc}
- DiffRgn(fFrame[fLastInd].fRgn, fFrame[fInd].fRgn, gEraseRgn); {Calc the erase rgn}
- FillRgn(fFrame[fInd].fRgn, fColor); {Draw the bar}
- {Restore the Bits}
- CopyBits(gSavePort^.portBits, gDrawPort^.portBits, fOldRect, fOldRect, srccopy, gEraseRgn);
- fLastInd := fInd;
- SetRect(fOldRect, fLoc.h - fRad, fLoc.v - fRad, fLoc.h + fRad, fLoc.v + fRad);
- IF fInd = kNumFrame THEN
- fInd := 0;
- END;
- END;
-
- {*****************************************************************************}
- {Start the move in pElem}
- {*****************************************************************************}
- PROCEDURE StartMove (pElem : tElement);
- VAR
- lBar : tBar;
- lMove : tMove;
- BEGIN
- gPeg[pElem.fTo].fFree := false; {Mark the dest peg as used}
- pop(lBar, pElem.fFrom); {Get the bar to move}
- WITH gBar[lBar] DO {Init the bar to move}
- BEGIN
- fAlmost := false;
- SetPt(fVel, 0, -kVel);
- SetPt(fDestLoc, gPegPos[pElem.fTo], gBarPos[gPeg[pElem.fTo].fBars.fTos + 1]);
- fTo := pElem.fTo;
- END;
- {Put the bar into the next available slot in gMoveBar}
- lMove := 0;
- REPEAT
- lMove := lMove + 1;
- IF gMoveBar[lMove] = 0 THEN
- BEGIN
- gMoveBar[lMove] := lBar;
- lMove := kMaxMove;
- END;
- UNTIL lMove = kMaxMove;
- END;
-
- {*****************************************************************************}
- {Move the bars in gMoveBar}
- {*****************************************************************************}
- PROCEDURE MoveBars;
- VAR
- x : tMove;
-
- { ***************************************************************************}
- { Adjust the fLoc field of bar pBar and change direction if neccessary}
- { Return true if bar has arrived at destination}
- { ***************************************************************************}
- FUNCTION MoveTheBar (pBar : tBar) : boolean;
- BEGIN
- MoveTheBar := false;
- WITH gBar[pBar] DO {Adjust the velocity of the bar}
- BEGIN
- IF fVel.v = -kVel THEN
- IF fLoc.v <= kAlt THEN
- BEGIN
- fVel.v := 0;
- IF fLoc.h > fDestLoc.h THEN
- fVel.h := -kVel
- ELSE
- fVel.h := kVel;
- END;
- IF fVel.v = 0 THEN
- BEGIN
- IF fVel.h = kVel THEN
- IF fLoc.h >= fDestLoc.h THEN
- BEGIN
- fVel.h := 0;
- fVel.v := kVel;
- END;
- IF fVel.h = -kVel THEN
- IF fLoc.h <= fDestLoc.h THEN
- BEGIN
- fVel.h := 0;
- fVel.v := kVel;
- END;
- END;
- IF fVel.v = kVel THEN
- IF fLoc.v >= fDestLoc.v THEN
- fAlmost := true;
- IF fAlmost THEN {do not adjust fLoc}
- BEGIN
- IF (fInd = 10) OR (fInd = 30) THEN
- BEGIN
- fIndFill := fInd + 1;
- MoveTheBar := true;
- END;
- END
- ELSE {Adjust it}
- AddPt(fVel, fLoc);
- PlotBar(pBar); {Plot the bar}
- END;
- END;
-
- BEGIN
- {Update every bar in gMoveBar}
- FOR x := 1 TO kMaxMove DO
- IF gMoveBar[x] > 0 THEN
- IF MoveTheBar(gMoveBar[x]) THEN {We arrived}
- BEGIN
- Push(gMoveBar[x], gBar[gMoveBar[x]].fTo);
- gPeg[gBar[gMoveBar[x]].fTo].fFree := true;
- gMoveBar[x] := 0;
- END;
- END;
-
- {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
- {Processing routines}
- {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
-
- {*****************************************************************************}
- {*****************************************************************************}
- {Decide if we can move a bar and return true if nothing left to do}
- {NOTE: This is the heart of the whole program}
- {*****************************************************************************}
- {*****************************************************************************}
- FUNCTION SystemTime : boolean;
- VAR
- lMove : tMove;
- lTempB : boolean;
- lElem : tElement;
- BEGIN
- IF button THEN {We are tired of watching these bars go in circles}
- ExitToShell;
- lTempB := true;
- {Is there room to in gMoveBar}
- FOR lMove := 1 TO kMaxMove DO
- lTempB := lTempB AND (gMoveBar[lMove] <> 0);
- IF NOT EmptyQue AND NOT lTempB THEN {A move is possible}
- BEGIN
- TopElem(lElem);
- IF gPeg[lElem.fTo].fFree AND gPeg[lElem.fFrom].fFree THEN {Ok to move}
- BEGIN
- Deq(lElem);
- StartMove(lElem);
- END;
- END;
- {Check to see if anything left do}
- lTempB := true;
- FOR lMove := 1 TO kMaxMove DO
- lTempB := lTempB AND (gMoveBar[lMove] = 0);
- SystemTime := EmptyQue AND lTempB;
- MoveBars;
- END;
-
- {*****************************************************************************}
- {Calculate the moves to preform}
- {*****************************************************************************}
- PROCEDURE Hanoi (pNumRings : tBar;
- pFrom, pTo, pUsing : tPeg);
- BEGIN
- IF SystemTime THEN
- ;
- IF pNumRings = 1 THEN
- Enq(pFrom, pTo)
- ELSE
- BEGIN
- hanoi(pNumRings - 1, pFrom, pUsing, pTo);
- Enq(pFrom, pTo);
- hanoi(pNumRings - 1, pUsing, pTo, pFrom);
- END;
- END;
-
- {*****************************************************************************}
- {Init the program}
- {*****************************************************************************}
- PROCEDURE Init;
-
- { ***************************************************************************}
- { Get the number of bars to move}
- { ***************************************************************************}
- PROCEDURE GetNumBars;
- VAR
- lDlog : DialogPtr;
- lItem : integer;
- lType : integer;
- lItemHand : Handle;
- lBox : Rect;
- lText : str255;
- lRslt : longint;
- BEGIN
- lDlog := GetNewDialog(kDLOG, NIL, pointer(-1));
- REPEAT
- ModalDialog(NIL, lItem);
- GetDItem(lDlog, 2, ltype, lItemHand, lBox);
- GetIText(lItemHand, lText);
- StringToNum(lText, lRslt);
- gNumBars := integer(lRslt);
- UNTIL (gNumBars <= 6) AND (gNumBars >= 3);
- DisposDialog(lDlog);
- END;
-
- { ***************************************************************************}
- { Draw the Pegs}
- { ***************************************************************************}
- PROCEDURE DrawScreen;
- VAR
- lTemp : Rect;
- BEGIN
- SetPort(gDrawPort);
- SetRect(lTemp, 8, 235, 152, 243);
- FillRect(lTemp, Black);
- SetRect(lTemp, 184, 235, 328, 243);
- FillRect(lTemp, Black);
- SetRect(lTemp, 360, 235, 504, 243);
- FillRect(lTemp, Black);
- SetRect(lTemp, 76, 99, 84, 235);
- FillRect(lTemp, Black);
- SetRect(lTemp, 252, 99, 260, 235);
- FillRect(lTemp, Black);
- SetRect(lTemp, 428, 99, 436, 235);
- FillRect(lTemp, Black);
- END;
-
- { ***************************************************************************}
- { Calculate the data for the frames of the bars}
- { ***************************************************************************}
- PROCEDURE SetupData;
- VAR
- lBar : tBar;
- lFrame : integer;
- PtA, PtB : point;
-
- { **************************************************************************}
- { Calculate two point tangent to the line pAngle degrees around the circle}
- { **************************************************************************}
- PROCEDURE Get2Tang (pAngle : real;
- pRad : integer;
- VAR PtA, PtB : point);
- VAR
- temp, temp2, xc, yc, m, perpm : real;
- BEGIN
- yc := pRad * cos(pAngle * pi / 180);
- xc := pRad * sin(pAngle * pi / 180);
- perpm := -xc / yc;
- temp := kBarWid / (perpm * perpm + 1);
- temp2 := temp * perpm;
- PtA.h := round(yc - temp2);
- PtA.v := round(xc - temp);
- PtB.h := round(yc + temp2);
- PtB.v := round(xc + temp);
- END;
-
- { **************************************************************************}
- { Transform PtA and PtB into 8 more points}
- { **************************************************************************}
- PROCEDURE BuildData (pInd : integer;
- pBar : tBar;
- PtA, PtB : point);
-
- { *************************************************************************}
- { Build a region around the given points}
- { *************************************************************************}
- PROCEDURE InsertElem (pIndex, pP1h, pP1v, pP2h, pP2v : integer);
- BEGIN
- WITH gBar[pBar] DO
- BEGIN
- fFrame[pIndex].fRgn := NewRgn;
- OpenRgn;
- MoveTo(pP1h, pP1v);
- LineTo(pP2h, pP2v);
- LineTo(-pP1h, -pP1v);
- LineTo(-pP2h, -pP2v);
- LineTo(pP1h, pP1v);
- CloseRgn(fFrame[pIndex].fRgn);
- fFrame[pIndex].fOrg := fFrame[pIndex].fRgn^^.rgnBBox.topleft;
- OffsetRgn(fFrame[pIndex].fRgn, fLoc.h, fLoc.v);
- END;
- END;
-
- BEGIN
- InsertElem(pInd, -PtA.v, PtA.h, -PtB.v, PtB.h);
- IF pInd <> 6 THEN
- InsertElem(kBase - pInd + 2, PtA.h, -PtA.v, PtB.h, -PtB.v);
- InsertElem(kBase + pInd, -PtA.h, -PtA.v, -PtB.h, -PtB.v);
- IF pInd <> 6 THEN
- InsertElem(kBase * 2 - pInd + 2, -PtA.v, -PtA.h, -PtB.v, -PtB.h);
- InsertElem(kBase * 2 + pInd, PtA.v, -PtA.h, PtB.v, -PtB.h);
- IF pInd <> 6 THEN
- InsertElem(kBase * 3 - pInd + 2, -PtA.h, PtA.v, -PtB.h, PtB.v);
- InsertElem(kBase * 3 + pInd, PtA.h, PtA.v, PtB.h, PtB.v);
- IF pInd <> 1 THEN
- InsertElem(kBase * 4 - pInd + 2, PtA.v, PtA.h, PtB.v, PtB.h);
- END;
-
- BEGIN
- FOR lBar := 1 TO gNumBars DO
- WITH gBar[lBar] DO {init the bar}
- BEGIN
- fRad := 16 + (lBar - 1) * 8;
- fInd := 10;
- fLastInd := 10;
- fIndFill := 11;
- fAlmost := false;
- WITH fSaveBits, bounds DO {Create fSaveBits}
- BEGIN
- SetRect(bounds, 0, 0, fRad * 2, 8);
- rowBytes := (((right - left - 1) DIV 16) + 1) * 2;
- baseAddr := NewPtr(rowBytes * (bottom - top));
- END;
- SetPt(fVel, 0, kVel);
- SetPt(fLoc, kPeg1, kAlt);
- SetPt(fDestLoc, kPeg1, (183 + (kMaxBar - gNumBars) * 8) + (lBar * 8));
- fTo := A;
- SetRect(fOldRect, fLoc.h - fRad, fLoc.v - fRad, fLoc.h + fRad, fLoc.v + fRad);
- GetIndPattern(fColor, sysPatListID, lBar + 1);
- FOR lFrame := 1 TO kNumTurn + 1 DO
- BEGIN
- Get2Tang((lFrame - 1) * kAngle, fRad, PtA, PtB);
- BuildData(lFrame, lBar, PtA, PtB);
- END;
- END;
- END;
-
- { *****************************************************************************}
- { Setup the Toolbox}
- { *****************************************************************************}
- PROCEDURE InitToolbox;
- BEGIN
- InitGraf(@thePort);
- MoreMasters;
- MoreMasters;
- MoreMasters;
- MoreMasters;
- MoreMasters;
- MoreMasters;
- MoreMasters;
- MoreMasters;
- MaxApplZone;
- InitFonts;
- InitWindows;
- InitCursor;
- HideCursor;
- END;
-
- { *****************************************************************************}
- { Setup gSavePort}
- { *****************************************************************************}
- PROCEDURE SetupSavePort;
- BEGIN
- gSavePort := GrafPtr(NewPtr(sizeof(GrafPort)));
- gEraseRgn := NewRgn;
- OpenPort(gSavePort);
- WITH gSavePort^, portBits, bounds DO
- BEGIN
- bounds := gDrawPort^.portBits.Bounds;
- portRect := bounds;
- rowBytes := (((right - left - 1) DIV 16) + 1) * 2;
- baseAddr := NewPtr(rowBytes * (bottom - top));
- cliprect(portRect);
- RectRgn(visrgn, portrect);
- END;
- END;
-
- { *****************************************************************************}
- { Setup the global variables}
- { *****************************************************************************}
- PROCEDURE InitGlobals;
- VAR
- lBar : tBar;
- lMove : tMove;
- lPeg : tPeg;
- BEGIN
- InitQue;
- FOR lPeg := A TO C DO
- BEGIN
- InitStack(lPeg);
- gPeg[lPeg].fFree := true;
- END;
- FOR lMove := 1 TO kMaxMove DO
- gMoveBar[lMove] := 0;
- gPegPos[A] := kPeg1;
- gPegPos[B] := kPeg2;
- gPegPos[C] := kPeg3;
- FOR lBar := gNumBars DOWNTO 1 DO
- BEGIN
- gMoveBar[1] := lBar;
- WHILE NOT SystemTime DO
- ;
- END;
- FOR lBar := 1 TO gNumBars DO
- gBarPos[lBar] := gBar[gNumBars - lBar + 1].fDestLoc.v;
- END;
-
- BEGIN
- InitToolbox;
- GetPort(gDrawPort);
- SetUpSavePort;
- DrawScreen;
- CopyBits(gDrawPort^.portBits, gSavePort^.portBits, gDrawPort^.portRect, gSavePort^.portRect, srcCopy, NIL);
- GetNumBars;
- SetUpData;
- InitGlobals;
- END;
-
- {*******************************************************************************}
- {Make the magic happen by calling Hanoi and then SystemTime until done}
- {*******************************************************************************}
- PROCEDURE DoIt;
- VAR
- x : integer;
- BEGIN
- WHILE true DO
- BEGIN
- Hanoi(gNumBars, A, B, C);
- WHILE NOT SystemTime DO
- ;
- SetPort(gDrawPort);
- FOR x := 1 TO 16 DO
- InvertRect(gDrawPort^.PortRect);
- Hanoi(gNumBars, B, C, A);
- WHILE NOT SystemTime DO
- ;
- SetPort(gDrawPort);
- FOR x := 1 TO 16 DO
- InvertRect(gDrawPort^.PortRect);
- Hanoi(gNumBars, C, A, B);
- WHILE NOT SystemTime DO
- ;
- SetPort(gDrawPort);
- FOR x := 1 TO 16 DO
- InvertRect(gDrawPort^.PortRect);
- END;
- END;
-
- BEGIN
- Init;
- DoIt;
- END.
-