home *** CD-ROM | disk | FTP | other *** search
- MODULE maze2;
-
- FROM SYSTEM IMPORT
- ADDRESS, LONGSET, ADR;
- FROM Arts IMPORT
- Terminate, TermProcedure;
- FROM Exec IMPORT
- MsgPortPtr,WaitPort,ReplyMsg,GetMsg;
- FROM Graphics IMPORT
- SetAPen, Move, Draw, Text, WritePixel;
- FROM Intuition IMPORT
- NewWindow, IDCMPFlags, IDCMPFlagSet, ScreenFlags, ScreenFlagSet,
- WindowPtr, WindowFlags, WindowFlagSet, OpenWindow, CloseWindow,
- gadgHNone, Gadget, GadgetPtr, GadgetFlags, GadgetFlagSet, AddGadget,
- propGadget, PropInfo, PropInfoPtr, PropInfoFlags, PropInfoFlagSet,
- Image, ActivationFlags, ActivationFlagSet, IntuiMessagePtr;
-
- (* $R- $V- $S- $F- *)
-
- CONST
- xArrayMax = 120;
- yArrayMax = 54;
-
- VAR
- myWindow: WindowPtr;
- myMsg: IntuiMessagePtr;
- st : CHAR;
- sv : ARRAY [1..xArrayMax],[1..yArrayMax] OF CARDINAL;
- fx : ARRAY [1..xArrayMax * yArrayMax DIV 2] OF CARDINAL;
- fy : ARRAY [1..xArrayMax * yArrayMax DIV 2] OF CARDINAL;
- w : ARRAY [1..4] OF CARDINAL;
- t : [1..4];
- x, y, xc, yc, rand, flcp, pick, n, back,
- xmax, ymax, ssz, hsz, p1, p2, i, xb, xe :CARDINAL;
- gp : GadgetPtr;
- propInfo: PropInfo;
- gadget: Gadget;
- image: Image;
-
- PROCEDURE CreateGadget(): GadgetPtr;
- BEGIN
- WITH propInfo DO
- flags:=PropInfoFlagSet{autoKnob,freeHoriz};
- horizPot:= 0; vertPot:=0;
- horizBody:=100; vertBody:=10;
- END;
- WITH gadget DO
- (* nextGadget:=NIL; *)
- leftEdge:=95; topEdge:=12; width:=100; height:=10;
- (* flags:=GadgetFlagSet{}; *)
- (* activation:=ActivationFlagSet{}; *)
- gadgetType:=propGadget;
- gadgetRender:=ADR(image);
- (* selectRender:=NIL; gadgetText:=NIL; mutualExclude:=LONGSET{}; *)
- specialInfo:=ADR(propInfo);
- (* gadgetID:=0; userData:=NIL; *)
- END;
- RETURN ADR(gadget)
- END CreateGadget;
-
- PROCEDURE CreateWindow(x,y,w,h: INTEGER; t: ADDRESS; gp:GadgetPtr): WindowPtr;
- VAR
- nw: NewWindow;
- BEGIN
- WITH nw DO
- leftEdge:=x; topEdge:=y; width:=w; height:=h;
- detailPen:=0; blockPen:=1;
- idcmpFlags:=IDCMPFlagSet{closeWindow,newSize};
- flags:=WindowFlagSet{windowClose,simpleRefresh,activate,windowDepth,
- windowSizing,windowDrag};
- firstGadget:=gp; checkMark:=NIL;
- title:=t;
- (* screen:=NIL; bitMap:=NIL; *)
- minWidth:=200; minHeight:=100; maxWidth:=w; maxHeight:=h;
- type:=ScreenFlagSet{wbenchScreen}
- END;
- RETURN OpenWindow(nw)
- END CreateWindow;
-
- PROCEDURE QSquare ( qx, qy : CARDINAL);
- BEGIN
- IF sv[qx,qy] = 0 THEN
- sv[qx,qy] := 128;
- INC(flcp);
- fx[flcp] := qx;
- fy[flcp] := qy;
- END;
- END QSquare;
-
- PROCEDURE Line (x1,y1,x2,y2,c:CARDINAL);
- BEGIN
- SetAPen(myWindow^.rPort,c);
- Move (myWindow^.rPort,(x1-1)*hsz+10,(y1-1)*ssz+24);
- Draw (myWindow^.rPort,(x2-1)*hsz+10,(y2-1)*ssz+24);
- END Line;
-
- PROCEDURE Random ( min,range :CARDINAL ): CARDINAL ;
- CONST
- m=1024; a=57; c=6999;
- BEGIN
- rand:=(CARDINAL(a)* rand +CARDINAL(c)) MOD CARDINAL (m);
- IF range > 1 THEN
- RETURN ((rand DIV 10)MOD range + min);
- ELSE
- RETURN min;
- END;
- END Random;
-
- PROCEDURE ReadMsg();
- BEGIN
- LOOP
- myMsg:=GetMsg(myWindow^.userPort);
- IF myMsg=NIL THEN
- EXIT
- ELSIF closeWindow IN myMsg^.class THEN
- Terminate(0)
- ELSE
- hsz:=propInfo.horizPot DIV 1024 + 5;
- ssz:=(hsz * 3) DIV 5;
- xmax:=CARDINAL(myWindow^.width - 40) DIV hsz;
- ymax:=CARDINAL(myWindow^.height- 36) DIV ssz;
- END;
- ReplyMsg(myMsg);
- END;
- END ReadMsg;
-
- PROCEDURE Cleanup;
- BEGIN
- CloseWindow(myWindow)
- END Cleanup;
-
- BEGIN
- TermProcedure(Cleanup);
- xmax:=120; ymax:=54; ssz:=3; hsz:=5;
- gp:=CreateGadget();
- myWindow:=CreateWindow(0,0,640,200,ADR("Muzz's Maze Maker"),gp);
- rand:=71;
-
- REPEAT
- SetAPen(myWindow^.rPort,1);
- Move(myWindow^.rPort,5,20);
- Text(myWindow^.rPort,ADR("Cell size:"),10);
-
- flcp:=0;
- back:=Random(2,14);
-
- (* choose a starting point randomly *)
- xc := Random (xmax DIV 3 + 1,xmax DIV 3);
- yc := Random (ymax DIV 3 + 1,ymax DIV 3);
- sv[xc,yc] := 64;
-
- REPEAT
- (* add all possible neighbouring squares to queue*)
- IF yc > 1 THEN
- QSquare(xc,yc - 1);
- END;
- IF yc < ymax THEN
- QSquare(xc,yc + 1);
- END;
- IF xc > 1 THEN
- QSquare(xc - 1,yc);
- END;
- IF xc < xmax THEN
- QSquare(xc + 1,yc);
- END;
-
- (* pick one to process from the most recent additions *)
- IF flcp > back THEN
- pick := Random(flcp - back,back);
- ELSE
- pick := Random(1, flcp);
- END;
- xc := fx[pick];
- yc := fy[pick];
-
- n:=WritePixel (myWindow^.rPort,(xc-1)*hsz+10,(yc-1)*ssz+24);
-
- (* delete from queue by copying stack top to entry *)
- fx[pick] := fx[flcp];
- fy[pick] := fy[flcp];
- DEC(flcp);
-
- (* use queue to select random exit from the square *)
- FOR n := 1 TO 4 DO
- w[n] := n
- END;
- n := 4;
- REPEAT
- (* search for active path *)
- x:=xc; y:=yc; p2:=0;
- pick := Random(1,n);
- t := w[pick];
- w[pick] := w[n];
- DEC(n);
- CASE t OF
- (* up *)
- 1 : IF yc > 1 THEN
- x := xc;
- y := yc - 1;
- p2 := 1;
- END |
- (* left *)
- 2 : IF xc > 1 THEN
- x := xc - 1;
- y := yc;
- p2 := 2;
- END |
- (* right *)
- 3 : IF xc < xmax THEN
- x := xc + 1;
- y := yc;
- p2 := 4;
- END |
- (* down *)
- 4 : IF yc < ymax THEN
- x := xc;
- y := yc + 1;
- p2 := 8
- END
- ELSE
- Terminate(0)
- END;
- UNTIL ((sv[x,y] > 0) AND (sv[x,y] < 128));
-
- (* flag the wall that has to be deleted *)
- INC(sv[x,y],8 DIV p2);
- sv[xc,yc] := p2;
- UNTIL flcp <= 0;
-
- (* establish maze exits *)
- xb := Random(1,xmax);
- y := 1;
- INC(sv[xb,y]);
- xe := Random(1,xmax);
-
- (* draw maze *)
- FOR y := 1 TO ymax DO
- FOR x := 1 TO xmax DO
- p1 := sv[x,y]; sv[x,y] := 0;
- p2 := 0;
- IF (p1 MOD 2) = 0 THEN
- p2 := 3
- END;
- Line(x,y,x+1,y,p2);
- p2 := 0;
- IF (p1 MOD 4) < 2 THEN
- p2 := 3
- END;
- Line (x,y,x,y+1,p2);
-
- END;
- END;
- Line(xmax+1,1,xmax+1,ymax+1,3);
- Line(1,ymax+1,xmax+1,ymax+1,0);
- Line(1,ymax+1,xe,ymax+1,3);
- Line(xe+1,ymax+1,xmax+1,ymax+1,3);
-
- WaitPort(myWindow^.userPort);
- ReadMsg();
- UNTIL myMsg^.class = IDCMPFlagSet{closeWindow};
-
- END maze2.
-