Thread View: comp.sources.mac
1 messages
1 total messages
Started by Jeffrey Shulman
Thu, 05 May 1988 04:36
Towers of Hanoi
Author: Jeffrey Shulman
Date: Thu, 05 May 1988 04:36
Date: Thu, 05 May 1988 04:36
725 lines
24573 bytes
24573 bytes
[Towers of Hanoi - Uploaded from Delphi by Jeff Shulman]
Name: TOWERS OF HANOI
Date: 3-APR-1988 17:09 by SOCCERKING
This is the same old towers of hanoi problem but with a few new twists.
If you are interested you can check out the source code. This program
is simply for your enjoyment and curiosity. I hope you enjoy it. Does
not run under MultiFinder.
[Moderator's Note: The application and a PackIt archive of the source
and Lightspeed Pascal project have been posted in comp.binaries.mac.]
---
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# Towers.lp
# This archive created: Wed May 4 08:16:04 1988
# By: Roger L. Long (macintosh@dhw68k.cts.com)
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Towers.lp'" '(21552 characters)'
if test -f 'Towers.lp'
then
echo shar: will not over-write existing file "'Towers.lp'"
else
sed 's/^X//' << \SHAR_EOF > 'Towers.lp'
XPROGRAM RotBarcb;
X{NOTES:}
X{*A bar is a ring on a peg}
X{*All bars use the same bitmap to restore what it has erased}
X{*A move is when a bar goes from one peg to anther}
X CONST
X kAngle = 9; {angle between each turn of the bar}
X kNumTurn = 5; {90 div 9}
X kBase = 10; {numturn * 2}
X kBarWid = 4; {width of bar div 2}
X kNumFrame = 40; {numturn * 8 }
X kPi = 3.141592654;
X kAlt = 67; {Height when bar should switch directions}
X kPeg1 = 80; {Pos of peg A}
X kPeg2 = 256; {Pos of peg B}
X kPeg3 = 432; {Pos of peg C}
X kVel = 4; {Velocity at which pegs travel}
X kMaxBar = 6; {Maximun number of bars}
X kMaxMove = 2; {Maximun number of bars moving at one time}
X kMaxQue = 100; {maximun number of elements in que}
X kDLOG = 129; {Dialog ID}
X
X TYPE
X tPeg = (A, B, C);
X tBar = 0..kMaxBar;
X tMove = 0..kMaxMove;
X tQueNum = 1..kMaxQue;
X tFrame = 0..kNumFrame;
X
X tElement = RECORD {Each element in the queue holds a move}
X fFrom : tPeg;
X fTo : tPeg;
X END;
X
X{A stack holds the bars on each peg}
X tStack = RECORD
X fElements : ARRAY[tBar] OF tBar;
X fTos : tBar;
X END;
X
X{The Que holds the moves waiting to be preformed}
X tQueue = RECORD
X fElements : ARRAY[tQueNum] OF tElement;
X fFront, fRear : tQueNum;
X END;
X
X{Hold the information for each frame of a bar}
X tBarData = RECORD
X fRgn : RgnHandle;
X fOrg : point;
X END;
X
X{Hold the information for the bar}
X{NOTES:}
X{*Memory is radically sacrificed for speed}
X{*fAlmost is used to tell MoveBars that the bar has reached its loc but}
X{ it still needs to spin}
X{*When a bar is at some peg and the bar above spins it will}
X{ erase the bars underneath it because they are not part of gSavePort}
X{ To fix this we save the bits underneath the bar at a peg in fSaveBits}
X{ and restore them after the peg moves}
X{*As much information to realated to a bar as possible is stored in tBarInfo}
X tBarInfo = RECORD
X fFrame : ARRAY[tFrame] OF tBarData; {Hold the frames of the bar}
X fInd : tFrame; {Hold the current index into fFrame}
X fLastInd : tFrame; {Hold the last index into the fFrame}
X fIndFill : tFrame; {Hold the index to the last horz frame}
X fRad : integer; {Hold the radius of the bar}
X fLoc : point; {Hold the current location of the bar}
X fDestLoc : point; {Hold the destination location}
X fVel : point; {Hold the current velocity of the bar}
X fOldRect : rect; {Hold the previous position of the bar}
X fColor : Pattern; {Hold the color of the bar}
X fAlmost : boolean; {Used to tell some proc that the bar still needs to spin}
X fSaveBits : BitMap; {Used to save the bits of gSavePort}
X fTo : tPeg; {Destination peg}
X END;
X
X{This record stores the stack of bars on it}
X{and if this peg is free to move a bar to}
X tPegInfo = RECORD
X fFree : boolean; {Peg available?}
X fBars : tStack; {Stack of bars}
X END;
X
X tBars = ARRAY[tBar] OF tBarInfo; {Hold all bars}
X tPegs = ARRAY[tPeg] OF tPegInfo; {Hold all Pegs}
X tMoveBars = ARRAY[tMove] OF tBar; {Hold moving bars}
X tPegPositions = ARRAY[tPeg] OF integer; {Hold positions of Pegs}
X tBarPositions = ARRAY[tBar] OF integer; {Hold positions of bars}
X
X VAR
X gSavePort : GrafPtr; {Hold the port which saves the image}
X gDrawPort : GrafPtr; {Hold the port to draw in}
X gNumBars : tBar; {Hold the number of bars}
X gBar : tBars; {Hold the bars}
X gPeg : tPegs; {Hold the pegs}
X gMoveQue : tQueue; {Hold the move queue}
X gMoveBar : tMoveBars; {Hold the moving bars}
X gPegPos : tPegPositions; {Hold the peg positions}
X gBarPos : tBarPositions; {Hold the bar positions}
X gEraseRgn : RgnHandle; {Hold the erase region in PlotBar to save time}
X
X{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
X{Stack routines}
X{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
X
X{*****************************************************************************}
X{Init the stack pPeg}
X{*****************************************************************************}
X PROCEDURE InitStack (pPeg : tPeg);
X BEGIN
X gPeg[pPeg].fBars.fTos := 0;
X END;
X
X{*****************************************************************************}
X{Push pBar onto the stack of pPeg}
X{*****************************************************************************}
X PROCEDURE Push (pBar : tBar;
X pPeg : tPeg);
X VAR
X lTemp : rect;
X BEGIN
X WITH gPeg[pPeg].fBars DO
X BEGIN
X fTos := fTos + 1;
X fElements[fTos] := pBar;
X END;
X WITH gBar[pBar] DO {We must Draw the bar in gSavePort}
X BEGIN
X{Calculate its rectangle on the screen}
X SetRect(lTemp, fLoc.h - fRad, fLoc.v - 4, fLoc.h + fRad, fLoc.v + 4);
X SetPort(gSavePort);
X{Save gSavePort's bits}
X CopyBits(gSavePort^.portBits, fSaveBits, lTemp, fSaveBits.bounds, srccopy, NIL);
X FillRgn(fFrame[fIndFill].fRgn, fColor); {Draw it in gSavePort}
X SetPort(gDrawPort);
X END;
X END;
X
X{*****************************************************************************}
X{Get vBar out of the stack of pPeg}
X{*****************************************************************************}
X PROCEDURE Pop (VAR vBar : tBar;
X pPeg : tPeg);
X VAR
X lTemp : rect;
X BEGIN
X WITH gPeg[pPeg].fBars DO
X BEGIN
X vBar := fElements[fTos];
X fTos := fTos - 1;
X END;
X WITH gBar[vBar] DO {Restore the saved bits}
X BEGIN
X SetRect(lTemp, fLoc.h - fRad, fLoc.v - 4, fLoc.h + fRad, fLoc.v + 4);
X CopyBits(fSaveBits, gSavePort^.portBits, fSaveBits.bounds, lTemp, srccopy, NIL);
X END;
X END;
X
X{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
X{Queue routines}
X{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
X
X{*****************************************************************************}
X{Init the Queue}
X{*****************************************************************************}
X PROCEDURE InitQue;
X BEGIN
X gMoveQue.fFront := 1;
X gMoveQue.fRear := 1;
X END;
X
X{*****************************************************************************}
X{Get the next index into the queue}
X{*****************************************************************************}
X PROCEDURE NextInd (VAR vInd : tQueNum);
X BEGIN
X IF vInd = kMaxQue THEN
X vInd := 1
X ELSE
X vInd := vInd + 1;
X END;
X
X{*****************************************************************************}
X{Enq this move}
X{*****************************************************************************}
X PROCEDURE Enq (pFrom, pTo : tPeg);
X BEGIN
X WITH gMoveQue DO
X BEGIN
X fElements[fRear].fFrom := pFrom;
X fElements[fRear].fTo := pTo;
X NextInd(fRear);
X END;
X END;
X
X{*****************************************************************************}
X{Deq the next move and put it into vElem}
X{*****************************************************************************}
X PROCEDURE Deq (VAR vElem : tElement);
X BEGIN
X WITH gMoveQue DO
X BEGIN
X vElem := fElements[fFront];
X NextInd(fFront);
X END;
X END;
X
X{*****************************************************************************}
X{Get the move to be returned at the next Deq}
X{*****************************************************************************}
X PROCEDURE TopElem (VAR vElem : tElement);
X BEGIN
X WITH gMoveQue DO
X vElem := fElements[fFront];
X END;
X
X{*****************************************************************************}
X{Return true if the que is empty}
X{*****************************************************************************}
X FUNCTION EmptyQue : boolean;
X BEGIN
X EmptyQue := gMoveQue.fFront = gMoveQue.fRear;
X END;
X
X{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
X{Drawing routines}
X{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
X
X{*****************************************************************************}
X{Plot pBar using all the info in its record}
X{*****************************************************************************}
X PROCEDURE PlotBar (pBar : tBar);
X
X{ ***************************************************************************}
X{ Move the regions center to the absolute location (pLoch,pLocv)}
X{ ***************************************************************************}
X PROCEDURE MoveRgn (pBarData : tBarData;
X pLoch, pLocv : integer);
X VAR
X dh, dv : integer;
X BEGIN
X WITH pBarData.fRgn^^.rgnBBox, pBarData DO
X BEGIN
X OffsetRgn(pBarData.fRgn, fOrg.h - left, fOrg.v - top);
X OffsetRgn(pBarData.fRgn, pLoch, pLocv);
X END;
X END;
X
X BEGIN
X WITH gBar[pBar] DO
X BEGIN
X fInd := fInd + 1; {Inc the index}
X MoveRgn(fFrame[fInd], fLoc.h, fLoc.v); {Move the regionto the new loc}
X DiffRgn(fFrame[fLastInd].fRgn, fFrame[fInd].fRgn, gEraseRgn); {Calc the erase rgn}
X FillRgn(fFrame[fInd].fRgn, fColor); {Draw the bar}
X{Restore the Bits}
X CopyBits(gSavePort^.portBits, gDrawPort^.portBits, fOldRect, fOldRect, srccopy, gEraseRgn);
X fLastInd := fInd;
X SetRect(fOldRect, fLoc.h - fRad, fLoc.v - fRad, fLoc.h + fRad, fLoc.v + fRad);
X IF fInd = kNumFrame THEN
X fInd := 0;
X END;
X END;
X
X{*****************************************************************************}
X{Start the move in pElem}
X{*****************************************************************************}
X PROCEDURE StartMove (pElem : tElement);
X VAR
X lBar : tBar;
X lMove : tMove;
X BEGIN
X gPeg[pElem.fTo].fFree := false; {Mark the dest peg as used}
X pop(lBar, pElem.fFrom); {Get the bar to move}
X WITH gBar[lBar] DO {Init the bar to move}
X BEGIN
X fAlmost := false;
X SetPt(fVel, 0, -kVel);
X SetPt(fDestLoc, gPegPos[pElem.fTo], gBarPos[gPeg[pElem.fTo].fBars.fTos + 1]);
X fTo := pElem.fTo;
X END;
X{Put the bar into the next available slot in gMoveBar}
X lMove := 0;
X REPEAT
X lMove := lMove + 1;
X IF gMoveBar[lMove] = 0 THEN
X BEGIN
X gMoveBar[lMove] := lBar;
X lMove := kMaxMove;
X END;
X UNTIL lMove = kMaxMove;
X END;
X
X{*****************************************************************************}
X{Move the bars in gMoveBar}
X{*****************************************************************************}
X PROCEDURE MoveBars;
X VAR
X x : tMove;
X
X{ ***************************************************************************}
X{ Adjust the fLoc field of bar pBar and change direction if neccessary}
X{ Return true if bar has arrived at destination}
X{ ***************************************************************************}
X FUNCTION MoveTheBar (pBar : tBar) : boolean;
X BEGIN
X MoveTheBar := false;
X WITH gBar[pBar] DO {Adjust the velocity of the bar}
X BEGIN
X IF fVel.v = -kVel THEN
X IF fLoc.v <= kAlt THEN
X BEGIN
X fVel.v := 0;
X IF fLoc.h > fDestLoc.h THEN
X fVel.h := -kVel
X ELSE
X fVel.h := kVel;
X END;
X IF fVel.v = 0 THEN
X BEGIN
X IF fVel.h = kVel THEN
X IF fLoc.h >= fDestLoc.h THEN
X BEGIN
X fVel.h := 0;
X fVel.v := kVel;
X END;
X IF fVel.h = -kVel THEN
X IF fLoc.h <= fDestLoc.h THEN
X BEGIN
X fVel.h := 0;
X fVel.v := kVel;
X END;
X END;
X IF fVel.v = kVel THEN
X IF fLoc.v >= fDestLoc.v THEN
X fAlmost := true;
X IF fAlmost THEN {do not adjust fLoc}
X BEGIN
X IF (fInd = 10) OR (fInd = 30) THEN
X BEGIN
X fIndFill := fInd + 1;
X MoveTheBar := true;
X END;
X END
X ELSE {Adjust it}
X AddPt(fVel, fLoc);
X PlotBar(pBar); {Plot the bar}
X END;
X END;
X
X BEGIN
X{Update every bar in gMoveBar}
X FOR x := 1 TO kMaxMove DO
X IF gMoveBar[x] > 0 THEN
X IF MoveTheBar(gMoveBar[x]) THEN {We arrived}
X BEGIN
X Push(gMoveBar[x], gBar[gMoveBar[x]].fTo);
X gPeg[gBar[gMoveBar[x]].fTo].fFree := true;
X gMoveBar[x] := 0;
X END;
X END;
X
X{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
X{Processing routines}
X{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
X
X{*****************************************************************************}
X{*****************************************************************************}
X{Decide if we can move a bar and return true if nothing left to do}
X{NOTE: This is the heart of the whole program}
X{*****************************************************************************}
X{*****************************************************************************}
X FUNCTION SystemTime : boolean;
X VAR
X lMove : tMove;
X lTempB : boolean;
X lElem : tElement;
X BEGIN
X IF button THEN {We are tired of watching these bars go in circles}
X ExitToShell;
X lTempB := true;
X{Is there room to in gMoveBar}
X FOR lMove := 1 TO kMaxMove DO
X lTempB := lTempB AND (gMoveBar[lMove] <> 0);
X IF NOT EmptyQue AND NOT lTempB THEN {A move is possible}
X BEGIN
X TopElem(lElem);
X IF gPeg[lElem.fTo].fFree AND gPeg[lElem.fFrom].fFree THEN {Ok to move}
X BEGIN
X Deq(lElem);
X StartMove(lElem);
X END;
X END;
X{Check to see if anything left do}
X lTempB := true;
X FOR lMove := 1 TO kMaxMove DO
X lTempB := lTempB AND (gMoveBar[lMove] = 0);
X SystemTime := EmptyQue AND lTempB;
X MoveBars;
X END;
X
X{*****************************************************************************}
X{Calculate the moves to preform}
X{*****************************************************************************}
X PROCEDURE Hanoi (pNumRings : tBar;
X pFrom, pTo, pUsing : tPeg);
X BEGIN
X IF SystemTime THEN
X ;
X IF pNumRings = 1 THEN
X Enq(pFrom, pTo)
X ELSE
X BEGIN
X hanoi(pNumRings - 1, pFrom, pUsing, pTo);
X Enq(pFrom, pTo);
X hanoi(pNumRings - 1, pUsing, pTo, pFrom);
X END;
X END;
X
X{*****************************************************************************}
X{Init the program}
X{*****************************************************************************}
X PROCEDURE Init;
X
X{ ***************************************************************************}
X{ Get the number of bars to move}
X{ ***************************************************************************}
X PROCEDURE GetNumBars;
X VAR
X lDlog : DialogPtr;
X lItem : integer;
X lType : integer;
X lItemHand : Handle;
X lBox : Rect;
X lText : str255;
X lRslt : longint;
X BEGIN
X lDlog := GetNewDialog(kDLOG, NIL, pointer(-1));
X REPEAT
X ModalDialog(NIL, lItem);
X GetDItem(lDlog, 2, ltype, lItemHand, lBox);
X GetIText(lItemHand, lText);
X StringToNum(lText, lRslt);
X gNumBars := integer(lRslt);
X UNTIL (gNumBars <= 6) AND (gNumBars >= 3);
X DisposDialog(lDlog);
X END;
X
X{ ***************************************************************************}
X{ Draw the Pegs}
X{ ***************************************************************************}
X PROCEDURE DrawScreen;
X VAR
X lTemp : Rect;
X BEGIN
X SetPort(gDrawPort);
X SetRect(lTemp, 8, 235, 152, 243);
X FillRect(lTemp, Black);
X SetRect(lTemp, 184, 235, 328, 243);
X FillRect(lTemp, Black);
X SetRect(lTemp, 360, 235, 504, 243);
X FillRect(lTemp, Black);
X SetRect(lTemp, 76, 99, 84, 235);
X FillRect(lTemp, Black);
X SetRect(lTemp, 252, 99, 260, 235);
X FillRect(lTemp, Black);
X SetRect(lTemp, 428, 99, 436, 235);
X FillRect(lTemp, Black);
X END;
X
X{ ***************************************************************************}
X{ Calculate the data for the frames of the bars}
X{ ***************************************************************************}
X PROCEDURE SetupData;
X VAR
X lBar : tBar;
X lFrame : integer;
X PtA, PtB : point;
X
X{ **************************************************************************}
X{ Calculate two point tangent to the line pAngle degrees around the circle}
X{ **************************************************************************}
X PROCEDURE Get2Tang (pAngle : real;
X pRad : integer;
X VAR PtA, PtB : point);
X VAR
X temp, temp2, xc, yc, m, perpm : real;
X BEGIN
X yc := pRad * cos(pAngle * pi / 180);
X xc := pRad * sin(pAngle * pi / 180);
X perpm := -xc / yc;
X temp := kBarWid / (perpm * perpm + 1);
X temp2 := temp * perpm;
X PtA.h := round(yc - temp2);
X PtA.v := round(xc - temp);
X PtB.h := round(yc + temp2);
X PtB.v := round(xc + temp);
X END;
X
X{ **************************************************************************}
X{ Transform PtA and PtB into 8 more points}
X{ **************************************************************************}
X PROCEDURE BuildData (pInd : integer;
X pBar : tBar;
X PtA, PtB : point);
X
X{ *************************************************************************}
X{ Build a region around the given points}
X{ *************************************************************************}
X PROCEDURE InsertElem (pIndex, pP1h, pP1v, pP2h, pP2v : integer);
X BEGIN
X WITH gBar[pBar] DO
X BEGIN
X fFrame[pIndex].fRgn := NewRgn;
X OpenRgn;
X MoveTo(pP1h, pP1v);
X LineTo(pP2h, pP2v);
X LineTo(-pP1h, -pP1v);
X LineTo(-pP2h, -pP2v);
X LineTo(pP1h, pP1v);
X CloseRgn(fFrame[pIndex].fRgn);
X fFrame[pIndex].fOrg := fFrame[pIndex].fRgn^^.rgnBBox.topleft;
X OffsetRgn(fFrame[pIndex].fRgn, fLoc.h, fLoc.v);
X END;
X END;
X
X BEGIN
X InsertElem(pInd, -PtA.v, PtA.h, -PtB.v, PtB.h);
X IF pInd <> 6 THEN
X InsertElem(kBase - pInd + 2, PtA.h, -PtA.v, PtB.h, -PtB.v);
X InsertElem(kBase + pInd, -PtA.h, -PtA.v, -PtB.h, -PtB.v);
X IF pInd <> 6 THEN
X InsertElem(kBase * 2 - pInd + 2, -PtA.v, -PtA.h, -PtB.v, -PtB.h);
X InsertElem(kBase * 2 + pInd, PtA.v, -PtA.h, PtB.v, -PtB.h);
X IF pInd <> 6 THEN
X InsertElem(kBase * 3 - pInd + 2, -PtA.h, PtA.v, -PtB.h, PtB.v);
X InsertElem(kBase * 3 + pInd, PtA.h, PtA.v, PtB.h, PtB.v);
X IF pInd <> 1 THEN
X InsertElem(kBase * 4 - pInd + 2, PtA.v, PtA.h, PtB.v, PtB.h);
X END;
X
X BEGIN
X FOR lBar := 1 TO gNumBars DO
X WITH gBar[lBar] DO {init the bar}
X BEGIN
X fRad := 16 + (lBar - 1) * 8;
X fInd := 10;
X fLastInd := 10;
X fIndFill := 11;
X fAlmost := false;
X WITH fSaveBits, bounds DO {Create fSaveBits}
X BEGIN
X SetRect(bounds, 0, 0, fRad * 2, 8);
X rowBytes := (((right - left - 1) DIV 16) + 1) * 2;
X baseAddr := NewPtr(rowBytes * (bottom - top));
X END;
X SetPt(fVel, 0, kVel);
X SetPt(fLoc, kPeg1, kAlt);
X SetPt(fDestLoc, kPeg1, (183 + (kMaxBar - gNumBars) * 8) + (lBar * 8));
X fTo := A;
X SetRect(fOldRect, fLoc.h - fRad, fLoc.v - fRad, fLoc.h + fRad, fLoc.v + fRad);
X GetIndPattern(fColor, sysPatListID, lBar + 1);
X FOR lFrame := 1 TO kNumTurn + 1 DO
X BEGIN
X Get2Tang((lFrame - 1) * kAngle, fRad, PtA, PtB);
X BuildData(lFrame, lBar, PtA, PtB);
X END;
X END;
X END;
X
X{ *****************************************************************************}
X{ Setup the Toolbox}
X{ *****************************************************************************}
X PROCEDURE InitToolbox;
X BEGIN
X InitGraf(@thePort);
X MoreMasters;
X MoreMasters;
X MoreMasters;
X MoreMasters;
X MoreMasters;
X MoreMasters;
X MoreMasters;
X MoreMasters;
X MaxApplZone;
X InitFonts;
X InitWindows;
X InitCursor;
X HideCursor;
X END;
X
X{ *****************************************************************************}
X{ Setup gSavePort}
X{ *****************************************************************************}
X PROCEDURE SetupSavePort;
X BEGIN
X gSavePort := GrafPtr(NewPtr(sizeof(GrafPort)));
X gEraseRgn := NewRgn;
X OpenPort(gSavePort);
X WITH gSavePort^, portBits, bounds DO
X BEGIN
X bounds := gDrawPort^.portBits.Bounds;
X portRect := bounds;
X rowBytes := (((right - left - 1) DIV 16) + 1) * 2;
X baseAddr := NewPtr(rowBytes * (bottom - top));
X cliprect(portRect);
X RectRgn(visrgn, portrect);
X END;
X END;
X
X{ *****************************************************************************}
X{ Setup the global variables}
X{ *****************************************************************************}
X PROCEDURE InitGlobals;
X VAR
X lBar : tBar;
X lMove : tMove;
X lPeg : tPeg;
X BEGIN
X InitQue;
X FOR lPeg := A TO C DO
X BEGIN
X InitStack(lPeg);
X gPeg[lPeg].fFree := true;
X END;
X FOR lMove := 1 TO kMaxMove DO
X gMoveBar[lMove] := 0;
X gPegPos[A] := kPeg1;
X gPegPos[B] := kPeg2;
X gPegPos[C] := kPeg3;
X FOR lBar := gNumBars DOWNTO 1 DO
X BEGIN
X gMoveBar[1] := lBar;
X WHILE NOT SystemTime DO
X ;
X END;
X FOR lBar := 1 TO gNumBars DO
X gBarPos[lBar] := gBar[gNumBars - lBar + 1].fDestLoc.v;
X END;
X
X BEGIN
X InitToolbox;
X GetPort(gDrawPort);
X SetUpSavePort;
X DrawScreen;
X CopyBits(gDrawPort^.portBits, gSavePort^.portBits, gDrawPort^.portRect, gSavePort^.portRect, srcCopy, NIL);
X GetNumBars;
X SetUpData;
X InitGlobals;
X END;
X
X{*******************************************************************************}
X{Make the magic happen by calling Hanoi and then SystemTime until done}
X{*******************************************************************************}
X PROCEDURE DoIt;
X VAR
X x : integer;
X BEGIN
X WHILE true DO
X BEGIN
X Hanoi(gNumBars, A, B, C);
X WHILE NOT SystemTime DO
X ;
X SetPort(gDrawPort);
X FOR x := 1 TO 16 DO
X InvertRect(gDrawPort^.PortRect);
X Hanoi(gNumBars, B, C, A);
X WHILE NOT SystemTime DO
X ;
X SetPort(gDrawPort);
X FOR x := 1 TO 16 DO
X InvertRect(gDrawPort^.PortRect);
X Hanoi(gNumBars, C, A, B);
X WHILE NOT SystemTime DO
X ;
X SetPort(gDrawPort);
X FOR x := 1 TO 16 DO
X InvertRect(gDrawPort^.PortRect);
X END;
X END;
X
XBEGIN
X Init;
X DoIt;
XEND.
SHAR_EOF
if test 21552 -ne "`wc -c < 'Towers.lp'`"
then
echo shar: error transmitting "'Towers.lp'" '(should have been 21552 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
---
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads