home *** CD-ROM | disk | FTP | other *** search
- (**************************************************************************
- ** **
- ** ##### ## ## ##### ##### written by: **
- ** ## ## ## ## ## ## Robert Brandner **
- ** ##### ## ## ## ### #### Schillerstr. 3 **
- ** ## ## ## ## ## ## ## A-8280 Fürstenfeld **
- ** ##### ##### ##### ##### AUSTRIA/EUROPE **
- ** **
- ** This program is written in Modula-II using the compiler M2Amiga V3.3d **
- ** ** **
- **************************************************************************)
-
- MODULE Bugs;
-
- IMPORT Intuition;
- FROM Graphics IMPORT
- RastPortPtr,SetAPen,RectFill,ReadPixel,VBeamPos;
- FROM SYSTEM IMPORT
- ADDRESS,ADR,INLINE;
- FROM Exec IMPORT
- AllocMem,FreeMem,MemReqs,MemReqSet,CopyMem,Byte,
- SetTaskPri,FindTask,TaskPtr;
- FROM RandomNumber IMPORT
- RND,PutSeed;
- FROM Hardware IMPORT
- ciaa,CiaaPraFlags,CiaaPraFlagSet;
-
-
- CONST STARTBUGS=10; (* Anzahl der Bugs am Anfang *)
- DEATH=-20;
- SATIATED=1000;
- ADULT=800;
- NOMOVE=0;
- VERYOLD=ADULT*3;
- ONEBITE=40;
-
- TPRI=0; (* Taskpriorität *)
-
-
- TYPE
- BugPtr=POINTER TO Bug;
- Bug=RECORD
- x,y,richt,alter,energie : INTEGER;
- gen : ARRAY[0..5] OF INTEGER;
- p : ARRAY[0..5] OF LONGINT;
- next : BugPtr;
- (* folgende Zeile dient dazu, das Programm so richtig gemein zu machen *)
- (* speicherfress:ARRAY[0..GEMEIN] OF CHAR *);
- END;
-
-
- VAR
- IntBase : Intuition.IntuitionBasePtr;
- rp : RastPortPtr;
- buglist,newbug : BugPtr;
- dx,dy : POINTER TO ARRAY[0..5] OF INTEGER;
- i,xmax,ymax : INTEGER;
- thisTask : TaskPtr;
- old : Byte;
-
-
- (* $R- Bereichskontrolle *)
- (* $S- Stacküberlauf *)
- (* $V- Über-/Unterlauf *)
-
-
- PROCEDURE AllocBug():BugPtr; (* Speicher für neuen Bug *)
- BEGIN
- RETURN AllocMem(SIZE(Bug),MemReqSet{public,memClear});
- END AllocBug;
-
-
- PROCEDURE InitBug(b:BugPtr);
- VAR
- i:INTEGER;
- BEGIN
- WITH b^ DO
- x:=1+3*RND(xmax/3);
- y:=1+3*RND(ymax/3);
- richt:=0;
- alter:=0;
- energie:=40;
- FOR i:=0 TO 5 DO gen[i]:=5 END;
- p[0]:=gen[0];
- FOR i:=1 TO 5 DO p[i]:=p[i-1]+gen[i] END;
- next:=NIL;
- END;
- END InitBug;
-
-
- PROCEDURE AppendBug(VAR bl,b:BugPtr); (* Bug an Bug Liste anfügen *)
- VAR
- help:BugPtr;
- BEGIN
- IF bl=NIL THEN
- bl:=b
- ELSE
- help:=bl;
- WHILE help^.next#NIL DO help:=help^.next END;
- help^.next:=b;
- END;
- END AppendBug;
-
-
- PROCEDURE KillBug(VAR prev,bl:BugPtr);
- VAR
- help:BugPtr;
- BEGIN
- help:=bl;
- IF bl=buglist THEN (* Ersten Bug in Liste löschen *)
- buglist:=buglist^.next;
- prev:=buglist;
- bl:=buglist;
- ELSE (* Bugs in Liste löschen *)
- bl:=bl^.next;
- prev^.next:=bl;
- END;
- FreeMem(help,SIZE(Bug)); (* Speicher freigeben. *)
- END KillBug;
-
-
- PROCEDURE SplitBug(VAR bl,b:BugPtr);
- VAR
- new:BugPtr;
- zufall,i:INTEGER;
- BEGIN
- new:=AllocBug();
- IF new=NIL THEN RETURN END; (* kein Speicher mehr *)
- b^.energie:=b^.energie/2; (* Vaterenergie halbieren *)
- b^.alter:=0;
- CopyMem(b,new,SIZE(Bug)); (* Vaterwerte kopieren *)
- WITH new^ DO
- zufall:=RND(6); (* Mutierendes Gen bestimmen *)
- gen[zufall]:=gen[zufall]+1; (* Mutation *)
- p[0]:=gen[0];
- FOR i:=1 TO 5 DO p[i]:=p[i-1]+gen[i] END;
- next:=NIL;
- END;
- AppendBug(bl,new);
- WITH b^ DO
- zufall:=RND(6); (* Mutierendes Gen bestimmen *)
- gen[zufall]:=gen[zufall]-1; (* Mutation *)
- IF gen[zufall]<0 THEN gen[zufall]:=0 END;
- p[0]:=gen[0];
- FOR i:=1 TO 5 DO p[i]:=p[i-1]+gen[i] END;
- END;
- END SplitBug;
-
-
- PROCEDURE DrawBug(x,y,c:INTEGER);
- BEGIN
- IF (x<xmax) AND (y<ymax) THEN
- SetAPen(rp,c);
- RectFill(rp,x-1,y-1,x+1,y+1);
- END
- END DrawBug;
-
-
- PROCEDURE MoveBugs(bl:BugPtr);
- VAR
- nricht,zufall,xo,yo,col:INTEGER;
- ok:BOOLEAN;
- prev:BugPtr;
-
- BEGIN
- prev:=bl;
- WHILE bl#NIL DO
- xo:=bl^.x; yo:=bl^.y;
- IF (bl^.energie<=DEATH) OR (* verhungert ..REQUIESCAT.. *)
- (bl^.alter>VERYOLD) THEN (* zu alt. ...IN.PACE.... *)
- DrawBug(xo,yo,0);
- KillBug(prev,bl);
- ELSE
- DEC(bl^.energie);
- INC(bl^.alter);
- IF bl^.energie>NOMOVE THEN (* genug Energie für Bewegung *)
- WITH bl^ DO
- DEC(energie);
- INC(alter);
- zufall:=RND(p[5]+1);
- nricht:=-1; ok:=FALSE;
- REPEAT
- INC(nricht);
- UNTIL zufall<=p[nricht];
- richt:=(richt+nricht) MOD 6; (* neue Orientierung *)
- xo:=x;yo:=y;
- x:=x+dx^[richt]; (* neue Position *)
- y:=y+dy^[richt]; (* neue Position *)
- IF x<1 THEN x:=1 END;
- IF x>xmax THEN x:=xmax END;
- IF y<1 THEN y:=1 END;
- IF y>ymax THEN y:=ymax END;
- col:=ReadPixel(rp,x,y);
- IF ODD(col) THEN
- INC(energie,ONEBITE);
- END;
- DrawBug(xo,yo,0);
- DrawBug(x,y,2);
- END; (* WITH *)
- IF (bl^.alter>=ADULT) AND (bl^.energie>=SATIATED) THEN
- SplitBug(buglist,bl); (* Fortpflanzung durch Teilung *)
- END;
- END; (* IF energie>NOMOVE *)
- prev:=bl; (* Zeiger auf Vorgänger *)
- bl:=bl^.next; (* in Liste weitergehen *)
- END;
- END;
- END MoveBugs;
-
-
- PROCEDURE RemoveBugs(VAR bl:BugPtr); (* Speicher wieder freigeben *)
- VAR
- help:BugPtr;
- BEGIN
- WHILE bl#NIL DO
- help:=bl^.next;
- FreeMem(bl,SIZE(Bug));
- bl:=help;
- END;
- END RemoveBugs;
-
-
- PROCEDURE dxData; (* $E- *)
- BEGIN
- INLINE(0,2,2,0,-2,-2);
- END dxData;
-
-
- PROCEDURE dyData; (* $E- *)
- BEGIN
- INLINE(2,1,-1,-2,-1,1);
- END dyData;
-
-
- BEGIN (* Bugs *)
- thisTask:=FindTask(NIL);
- old:=SetTaskPri(thisTask,TPRI); (* Taskpriorität niedrig machen *)
- PutSeed(VBeamPos()); (* Zufall vom Videostrahl abhängig *)
- dx:=ADR(dxData);
- dy:=ADR(dyData);
- IntBase:=ADR(Intuition); (* Adresse der IntuitionBase *)
- xmax:=IntBase^.activeScreen^.width-4;
- ymax:=IntBase^.firstScreen^.height-4;
- FOR i:=1 TO STARTBUGS DO (* STARTBUGS Bugs machen *)
- newbug:=AllocBug();
- IF newbug#NIL THEN
- InitBug(newbug);
- AppendBug(buglist,newbug);
- END;
- END;
- LOOP
- rp:=ADR(IntBase^.activeScreen^.rastPort); (* immer im aktiven Screen! *)
- xmax:=IntBase^.activeScreen^.width-2;
- ymax:=IntBase^.firstScreen^.height-2;
- MoveBugs(buglist);
- IF (buglist=NIL) OR NOT (gamePort1 IN ciaa.pra) THEN EXIT END;
- END;
- RemoveBugs(buglist);
- Intuition.DisplayBeep(NIL); (*** Test ***)
- END Bugs.
-