'=========================================================================== ' Subject: WATOR SIMULATION Date: Unknown Date (00:00) ' Author: Victor Yiu Code: QB, QBasic, PDS ' Keys: WATOR,SIMULATION Packet: AI.ABC '=========================================================================== DECLARE SUB Center (Lin%, Text$) DECLARE SUB ClearBot () DECLARE SUB Display () DECLARE SUB OkFishMoves (OkX%(), OkY%(), Fish%(), Shark%(), PossiblePositions%) DECLARE SUB OkSharkMoves (OkX%(), OkY%(), Fish%(), Shark%(), PP%) DEFINT A-Z ' integers when possible: less space/increased speed DIM SHARED X, Y, XDim, YDim CONST False = 0, True = NOT False SCREEN 0, 0, 0 COLOR 15, 1 CLS COLOR 15, 5 PRINT "Wa-Tor: "; COLOR 14 PRINT "Sharks and fish wage an ecological war on the toroidal planet Wa - Tor." ClearBot LOCATE 3, 1 COLOR 7, 1 DO: INPUT "X Size of Wa-Tor [40]? ", X$ X = VAL(X$) IF X = 0 THEN XDim = 40 ELSE XDim = X LOOP UNTIL (XDim <= 40) AND (XDim > 1) DO: INPUT "Y Size of Wa-Tor [23]? ", Y$ Y = VAL(Y$) IF Y = 0 THEN YDim = 23 ELSE YDim = Y LOOP UNTIL (YDim <= 23) AND (YDim > 1) TotalSpots = XDim * YDim * 9 \ 10' total # of positions NFish = TotalSpots \ 2 ' # of sharks in the beginning NSharks = TotalSpots \ 20 ' # of fish in the beginning DO: INPUT "Chronons required for fish to breed [8]? ", X$ X = VAL(X$) IF X = 0 THEN FBreed = 8 ELSE FBreed = X LOOP UNTIL FBreed >= 1 DO: INPUT "Chronons required for sharks to breed [10]? ", X$ X = VAL(X$) IF X = 0 THEN SBreed = 10 ELSE SBreed = X LOOP UNTIL SBreed >= 1 DO: INPUT "How long can a shark live without fish [3]? ", X$ X = VAL(X$) IF X = 0 THEN Starve = 3 ELSE Starve = X LOOP UNTIL Starve >= 1 PRINT INPUT "Chronons per second (0 = not timed) [0]? ", X$ PerSecond = VAL(X$) IF PerSecond THEN Interval! = 1 / PerSecond COLOR 14, 5 Center 25, "Initializing..." DIM Fish(1 TO XDim, 1 TO YDim) ' presence or absense of a fish at point DIM Shark(1 TO XDim, 1 TO YDim) ' presence or absense of a shark at point DIM FishMove(1 TO XDim, 1 TO YDim) ' record of whether a fish has been moved ' there during the current computational ' cycle DIM SharkMove(1 TO XDim, 1 TO YDim) ' ditto DIM Starve(1 TO XDim, 1 TO YDim) ' registers the last time the sharks ate FOR Dummy = 1 TO XDim FOR Dummy2 = 1 TO YDim Fish(Dummy, Dummy2) = -1 ' none here for the moment Shark(Dummy, Dummy2) = -1 NEXT NEXT FOR Fill = 1 TO NFish ' fill Wa-Tor with fish RANDOMIZE TIMER DO ' make sure it's not occupied by another fish already LocX = INT(RND * XDim + 1) ' positions LocY = INT(RND * YDim + 1) LOOP UNTIL (Fish(LocX, LocY) = -1) Fish(LocX, LocY) = INT(RND * FBreed) ' say fish is here; stage of life NEXT FOR Fill = 1 TO NSharks RANDOMIZE TIMER DO ' make sure it's not occupied by another fish or shark already LocX = INT(RND * XDim + 1) ' positions LocY = INT(RND * YDim + 1) LOOP UNTIL (Fish(LocX, LocY) = -1) AND (Shark(LocX, LocY) = -1) Shark(LocX, LocY) = INT(RND * SBreed) ' say shark is here!; stage of life Starve(LocX, LocY) = INT(RND * Starve) ' last time ate? NEXT ClearBot VIEW PRINT 2 TO 24 LOCATE 24, 1 COLOR 7, 1 FOR Dummy = 1 TO 24: PRINT : NEXT VIEW PRINT Display DO IF PerSecond THEN T! = TIMER REDIM OkX(1 TO 4), OkY(1 TO 4) FOR X = 1 TO XDim ' moving fish FOR Y = 1 TO YDim IF Fish(X, Y) > -1 THEN ' there's a fish here IF FishMove(X, Y) = 0 THEN ' and hasn't been moved yet OkFishMoves OkX(), OkY(), Fish(), Shark(), NumPos ' find the ok positions to move to IF NumPos > 0 THEN ' a place to move to! RANDOMIZE TIMER Choice = INT(NumPos * RND) + 1 NewX = OkX(Choice) ' new pos. NewY = OkY(Choice) IF Fish(X, Y) >= FBreed THEN ' breeding time? Fish(NewX, NewY) = 0 ' reset life Fish(X, Y) = 0 NFish = NFish + 1 FishMove(X, Y) = 1 ' say we have changed FishMove(NewX, NewY) = 1 ' already ELSE Fish(NewX, NewY) = Fish(X, Y) + 1 Fish(X, Y) = -1 FishMove(NewX, NewY) = 1 END IF END IF ' none possible END IF ' moved already END IF ' no fish there NEXT NEXT 'shark time -- complications... FOR X = 1 TO XDim FOR Y = 1 TO YDim IF Shark(X, Y) > -1 THEN ' there's a shark here IF SharkMove(X, Y) = 0 THEN ' it hasn't been moved yet NewX = 0 NewY = 0 OkSharkMoves OkX(), OkY(), Fish(), Shark(), NumPos RANDOMIZE TIMER IF NumPos > 0 THEN ' places with fish to move to Choice = INT(NumPos * RND) + 1 NewX = OkX(Choice) NewY = OkY(Choice) IF Shark(X, Y) = SBreed THEN ' breeding time? Shark(NewX, NewY) = 0 Shark(X, Y) = 0 Starve(NewX, NewY) = 0 Starve(X, Y) = 0 Fish(NewX, NewY) = -1 NSharks = NSharks + 1 NFish = NFish - 1 SharkMove(NewX, NewY) = 1 SharkMove(X, Y) = 1 ELSE Shark(NewX, NewY) = Shark(X, Y) + 1 Shark(X, Y) = -1 Starve(NewX, NewY) = 0 Starve(X, Y) = -1 Fish(NewX, NewY) = -1 NFish = NFish - 1 SharkMove(NewX, NewY) = 1 END IF ELSEIF NumPos < 0 THEN ' no fish positions, but just move Choice = INT(ABS(NumPos) * RND) + 1 NewX = OkX(Choice) NewY = OkY(Choice) IF Shark(X, Y) = SBreed THEN ' breeding time? Shark(NewX, NewY) = 0 Shark(X, Y) = 0 Starve(NewX, NewY) = Starve(X, Y) + 1 ' *********** Should the baby be full when born? Or should it new food? Starve(X, Y) = Starve - 2 NSharks = NSharks + 1 SharkMove(NewX, NewY) = 1 SharkMove(X, Y) = 1 ELSE Shark(NewX, NewY) = Shark(X, Y) + 1 Shark(X, Y) = -1 Starve(NewX, NewY) = Starve(X, Y) + 1 Starve(X, Y) = -1 SharkMove(NewX, NewY) = 1 END IF ELSE ' can't move at all! Shark(X, Y) = Shark(X, Y) + 1 Starve(X, Y) = Starve(X, Y) + 1 'SharkMove(X,Y)=1 END IF IF Starve(X, Y) >= Starve THEN Shark(X, Y) = -1 ' died NSharks = NSharks - 1 END IF IF NewX > 0 THEN IF Starve(NewX, NewY) >= Starve THEN Shark(NewX, NewY) = -1 ' died NSharks = NSharks - 1 END IF END IF END IF ' moved already END IF ' no shark here NEXT NEXT Chronons = Chronons + 1 ' next year REDIM FishMove(1 TO XDim, 1 TO YDim) ' clear moved flags REDIM SharkMove(1 TO XDim, 1 TO YDim) Display ' display progress (YESSS!!!) IF SingleStep = 1 THEN DO: I$ = INKEY$: LOOP UNTIL LEN(I$) IF UCASE$(I$) = "P" THEN SingleStep = 0 IF UCASE$(I$) = "E" THEN EXIT DO ELSE I$ = UCASE$(INKEY$) IF I$ = "P" THEN DO: I$ = INKEY$: LOOP UNTIL LEN(I$) IF UCASE$(I$) <> "P" THEN SingleStep = 1 ELSEIF I$ = "E" THEN EXIT DO END IF END IF IF PerSecond AND (SingleStep = 0) THEN E! = TIMER IF (E! - T!) < Interval! THEN DO: LOOP UNTIL ((TIMER - T!) >= Interval!) OR (TIMER < T!) END IF END IF LOOP UNTIL (NSharks = 0) OR (NFish = 0) COLOR 14, 5 LOCATE 1, 12 PRINT "Press any key to exit..."; SPACE$(81 - POS(0)); DO: LOOP UNTIL LEN(INKEY$) END SUB Center (Lin, Text$) LOCATE Lin, (81 - LEN(Text$)) \ 2 PRINT Text$; END SUB SUB ClearBot COLOR 15, 3 LOCATE 25, 1 PRINT STRING$(80, 0); END SUB SUB Display SHARED Fish(), Shark(), XDim, YDim, Chronons, NFish, NSharks Temp$ = SPACE$(XDim + XDim) COLOR 7, 1 FOR Y = 1 TO YDim Counter = 1 FOR X = 2 TO XDim + XDim STEP 2 IF Fish(Counter, Y) > -1 THEN ' fish? MID$(Temp$, X) = "o" ELSEIF Shark(Counter, Y) > -1 THEN ' shark? MID$(Temp$, X) = CHR$(254) ELSE ' nope, it's just blank MID$(Temp$, X) = CHR$(250) END IF Counter = Counter + 1 NEXT LOCATE Y + 1, 1 PRINT Temp$; NEXT LOCATE 25, 1 IF SCREEN(25, 1) <> 179 THEN COLOR 15, 3 ' 22v 37v 42v PRINT "³Status³ Chronons: Fish pop (o): Shark pop(þ): ³"; PRINT " P E"; COLOR 14 LOCATE , 70 PRINT "ause/"; LOCATE , POS(0) + 1 PRINT "xit"; END IF LOCATE , 20, 0 COLOR 14, 3 PRINT Chronons; LOCATE , 39 PRINT NFish; LOCATE , 58 PRINT NSharks; END SUB SUB OkFishMoves (OkX(), OkY(), Fish(), Shark(), PP) ' PP=Possible Positions PP = 0 ' left IF X = 1 THEN tempX = XDim ELSE tempX = X - 1 tempY = Y GOSUB CheckF ' right IF X = XDim THEN tempX = 1 ELSE tempX = X + 1 GOSUB CheckF ' up IF Y = 1 THEN tempY = YDim ELSE tempY = Y - 1 tempX = X GOSUB CheckF ' down IF Y = YDim THEN tempY = 1 ELSE tempY = Y + 1 GOSUB CheckF EXIT SUB CheckF: IF (Fish(tempX, tempY) = -1) AND (Shark(tempX, tempY) = -1) THEN PP = PP + 1 OkX(PP) = tempX OkY(PP) = tempY END IF RETURN END SUB SUB OkSharkMoves (OkX(), OkY(), Fish(), Shark(), PP) STATIC ' PP=Possible Positions ' if will be returned negated if only no-fish places are found... IF NOT Inited THEN DIM NoFishX(1 TO XDim), NoFishY(1 TO YDim) ' we will store values Inited = True ' when the END IF ' shark moves and doensn't find a fish at position. ' We will store the positions where sharks are found in the "Ok" array. PP = 0 PPnF = 0 ' positions w/o fish ' left IF X = 1 THEN tempX = XDim ELSE tempX = X - 1 tempY = Y GOSUB CheckS ' right IF X = XDim THEN tempX = 1 ELSE tempX = X + 1 GOSUB CheckS ' up IF Y = 1 THEN tempY = YDim ELSE tempY = Y - 1 tempX = X GOSUB CheckS ' down IF Y = YDim THEN tempY = 1 ELSE tempY = Y + 1 GOSUB CheckS IF PP = 0 THEN ' since there is no fish around me, just move on IF PPnF > 0 THEN ' other places not occupied PP = -PPnF FOR Copy = 1 TO PPnF OkX(Copy) = NoFishX(Copy) OkY(Copy) = NoFishY(Copy) NEXT END IF ' no place to go!! END IF EXIT SUB CheckS: IF Shark(tempX, tempY) = -1 THEN ' make sure there's no shark IF Fish(tempX, tempY) > -1 THEN 'fish found in this place PP = PP + 1 OkX(PP) = tempX OkY(PP) = tempY ELSE ' ohh, no fish. Anybody for tuna I bought at the grocers? PPnF = PPnF + 1 NoFishX(PPnF) = tempX NoFishY(PPnF) = tempY END IF END IF RETURN END SUB