+Vorticon Posted March 11, 2013 Author Share Posted March 11, 2013 Matt, I have been using TidBit while working on the gamma iteration of my bugs' evolution, and I found a minor bug: if the following is entered: CALL CHAR .. (91,"0000001818000000", .. 96,"FFFFFFFFFFFFFFFF", .. 104,"007E7E7E7E7E7E00", .. 112,"80433C3C3C7C8204", .. 120,"7CFEF3BF1FBFFE7C") It gets translated into this: 100 CALL CHAR (91,"0000001818000000", ,"FFFFFFFFFFFFFFFF", ,"007E7E7E7E7E7E00", ,"80433C3C3C7C8204", ,"7CFEF3BF1FBFFE7C") where the character numbers in the subsequent definitions get deleted. This is corrected by placing the commas after the .. continuation. Also a couple of suggestions: - A clear window button to clear existing code from the input window without having to select and delete as this gets tedious with long programs - A copy to the clipboard button for the output code for the same reason It's amazing how much clearer the code gets when using structured entry! Really great tool. 1 Quote Link to comment Share on other sites More sharing options...
matthew180 Posted March 11, 2013 Share Posted March 11, 2013 The long CALL CHAR needs to have the commas at the beginning of the line, like this: CALL CHAR (91,"0000001818000000".. ,96,"FFFFFFFFFFFFFFFF".. ,104,"007E7E7E7E7E7E00".. ,112,"80433C3C3C7C8204".. ,120,"7CFEF3BF1FBFFE7C") This is because any line starting with a number forces that line to use that line number. This was to allow you to add structured parts to you code and keep line numbers in places too, if you wanted. Every line is trimmed of white space before being examined. I thought the continuation ".." would over-ride the "starts with a number" test, but apparently not. Also a couple of suggestions: - A clear window button to clear existing code from the input window without having to select and delete as this gets tedious with long programs - A copy to the clipboard button for the output code for the same reason I'll see what I can do. My website uses a CMS and I have never explored what you can get away with in a post. I'm not sure about the second suggestion though, can Javascript put data on the local clipboard? Seems like that would be a security risk and not allowed. It's amazing how much clearer the code gets when using structured entry! Really great tool. If you look at the original BASIC language as it was designed by John Kemeny and Thomas Kurtz, there are not line numbers, they have looping constructs, and you can use indentation, and it was compiled. Only when BASIC was modified to run as as interpreter did it gain the line numbers and lose the formatting and looping constructs. It does make a *huge* difference as far as program structure and readability. I think BASIC would not have such a bad reputation if somehow it had retained the ability to use structure and the program structure constructs were retained. Thanks for the feedback, I'll see what I can do. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted April 4, 2013 Author Share Posted April 4, 2013 (edited) So let's fast-forward a few million years... Here's gamma, where now we have a dynamic environment for the bugs, with food cycles and predators. The bugs have 3 genetically transmittable traits, namely speed (1-3), vigilance (1-5 - i.e ability to spot food, other bugs or predators at a distance), and social tendency to flock to other bugs (1-10), and they asexually reproduce at regular cycles if conditions are favorable. The predators on the other hand have fixed attributes of speed and vigilance, and thus allow for a steady environmental pressure on the bugs. Both bugs and predators can die if they run out of energy, which is replenished by eating food or prey. Food for the bugs regenerates at regular cycles (magenta dots). Neither bugs nor predators can cross obstacles (gray squares). A word about vigilance: both bugs and predators can see with a 100% accuracy anything directly adjoining them. However, the farther out a target or object is, the lower the accuracy because bugs and predators only see along the 8 cardinal direction points. Furthermore, line of sight is implemented, so vision can be further reduced by obstacles or other creatures. The simulation ends when all the bugs die. The simulation revolves around life cycles, where each cycle consists of one pass through each of the bugs and predators. The current cycle is indicated at the bottom left of the simulation area. Asynchronous multitasking is also implemented, and therefore each creature may be in one of 3 possible phases, thus attempting to simulate simultaneous activity. There are 19 simulation variables which allow you to control all aspects of the simulation. There are also 3 commands available to you at any time: S: Stop the program R: Restart a fresh simulation G: Display a graph of the current genetic composition of the bugs, which will give you an idea of the dominant genes at any stage of the simulation. The relative number of bugs for each genetic trait is shown by a star. Press any key to return to the simulation There are really infinite possibilities to play with here, each with an unpredictable outcome. Try the simulation with no predators at all, then add predators to see how this affects the balance and the genetic composition of the bugs. I have not yet been able to find the right combination of factors that yields a stable ecosystem between bugs and predators, and I would be very interested to hear from anybody who does. It is best to run this simulation under Classic 99 in overdrive mode for speed. Below is the formatted source code (which for some mysterious reason has lost all of its indentations...): // GAMMA // INITIALIZATION // -------------- RANDOMIZE DIM .. BUG(50,5), .. BUGX(50), .. BUGY(50), .. PRED(10), .. PREDX(10), .. PREDY(10), .. BPHASE(50), .. PPHASE(10) DIM .. TARGETX(50), .. TARGETY(50), .. FLEE_FLAG(50), .. PTARGETX(10), .. PTARGETY(10), .. SPEED(3), .. VIG(5), .. SOCIAL(10) DIM .. FIELD$(22) CALL CHAR .. (128,"0000001818000000" .. ,96,"FFFFFFFFFFFFFFFF" .. ,104,"007E7E7E7E7E7E00" .. ,112,"80433C3C3C7C8204" .. ,120,"7CFEF3BF1FBFFE7C") CALL COLOR(13,14,1,9,13,1,10,15,1,11,5,1,12,9,1) CALL SCREEN(4) // SET SYSTEM VARIABLES NEXT_ID=20 ! TOTAL NUMBER OF BUGS PRED_NUM=5 ! INITIAL NUMBER OF PREDATORS FOOD_NUM=70 ! INITIAL NUMBER OF FOOD OBSTACLE_NUM=10 ! NUMBER OF OBSTACLES FOOD_REGEN=20 ! NUMBER OF FOOD WIDGETS REGENERATED PER FOOD CYCLE B_MAX_ENERGY=10 ! MAXIMUM ENERGY LEVEL FOR BUGS P_MAX_ENERGY=20 ! MAXIMUM ENERGY LEVEL FOR PREDATORS FOOD_ENERGY=2 ! ENERGY GAIN FROM EATING FOOD FOR BUGS P_FOOD_ENERGY=6 ! ENERGY GAIN FROM EATING PREY FOR PREDATORS B_MOVE_ENERGY=1 ! BUGS ENERGY LOSS FROM MOVEMENT P_MOVE_ENERGY=1 ! PREDATORS ENERGY LOSS FROM MOVEMENT B_IDLE_ENERGY=0.5 ! BUGS ENERGY LOSS FROM INACTIVITY P_IDLE_ENERGY=0.75 ! PREDATORS ENERGY LOSS FROM INACTIVITY HUNT_ENERGY=3 ! ENERGY LOSS FROM HUNTING REP_ENERGY=3 ! ENERGY LOSS FROM REPRODUCTION REST_LEVEL=15 ! ENERGY LEVEL AT OR ABOVE WHICH PREDATORS REST FLEE_MULT=1.5 ! MULTIPLYER FOR FLEE ENERGY LOSS RCYCLE=0 ! REPRODUCTIVE CYCLE COUNTER FCYCLE=0 ! FOOD REGENERATION CYCLE COUNTER REP_CYCLE=5 ! REPRODUCTION OCCURS EVERY REP_CYCLE FOOD_CYCLE=10 ! FOOD_REGEN FOOD WIDGETS REGENERATED EVERY FOOD_CYCLE // USER SIMULATION VARIABLES MODIFICATION SCREEN new_simulation: CALL CLEAR DISPLAY AT(1,1)BEEP:"INITIAL SIMULATION VARIABLES" DISPLAY AT(3,1):"NUMBER OF BUGS:";NEXT_ID DISPLAY AT(4,1):"NUMBER OF PREDATORS:";PRED_NUM DISPLAY AT(5,1):"NUMBER OF FOOD WIDGETS:";FOOD_NUM DISPLAY AT(6,1):"NUMBER OF OBSTACLES:";OBSTACLE_NUM DISPLAY AT(7,1):"FOOD REGENERATION CYCLE:";FOOD_REGEN DISPLAY AT(8,1):"BUGS MAX ENERGY:";B_MAX_ENERGY DISPLAY AT(9,1):"PREDATORS MAX ENERGY:";P_MAX_ENERGY DISPLAY AT(10,1):"FOOD ENERGY GAIN:";FOOD_ENERGY DISPLAY AT(11,1):"PREY ENERGY GAIN:";P_FOOD_ENERGY DISPLAY AT(12,1):"BUGS MOVE COST:";B_MOVE_ENERGY DISPLAY AT(13,1):"PREDATORS MOVE COST:";P_MOVE_ENERGY DISPLAY AT(14,1):"BUGS IDLE COST:";B_IDLE_ENERGY DISPLAY AT(15,1):"PREDATORS IDLE COST:";P_IDLE_ENERGY DISPLAY AT(16,1):"HUNT ENERGY COST:";HUNT_ENERGY DISPLAY AT(17,1):"REPRODUCTIVE COST:";REP_ENERGY DISPLAY AT(18,1):"PREDATORS REST LEVEL:";REST_LEVEL DISPLAY AT(19,1):"FLEEING COST MULTIPLYER:";FLEE_MULT DISPLAY AT(20,1):"REPRODUCTIVE CYCLE:";REP_CYCLE DISPLAY AT(21,1):"FOOD CYCLE:";FOOD_CYCLE bug_number: ACCEPT AT(3,17) SIZE(-2) VALIDATE(DIGIT):NEXT_ID IF NEXT_ID<0 OR NEXT_ID>50 THEN .. bug_number pred_number: ACCEPT AT(4,22) SIZE(-2) VALIDATE(DIGIT):PRED_NUM IF PRED_NUM>10 THEN .. pred_number ACCEPT AT(5,25) SIZE(-3) VALIDATE(DIGIT):FOOD_NUM ACCEPT AT(6,22) SIZE(-3) VALIDATE(DIGIT):OBSTACLE_NUM ACCEPT AT(7,26) SIZE(-2) VALIDATE(DIGIT):FOOD_REGEN ACCEPT AT(8,18) SIZE(-2) VALIDATE(DIGIT):B_MAX_ENERGY ACCEPT AT(9,23) SIZE(-2) VALIDATE(DIGIT)_MAX_ENERGY ACCEPT AT(10,19) SIZE(-2) VALIDATE(DIGIT):FOOD_ENERGY ACCEPT AT(11,19) SIZE(-2) VALIDATE(DIGIT)_FOOD_ENERGY ACCEPT AT(12,17) SIZE(-2) VALIDATE(DIGIT):B_MOVE_ENERGY ACCEPT AT(13,22) SIZE(-2) VALIDATE(DIGIT)_MOVE_ENERGY ACCEPT AT(14,17) SIZE(-4) VALIDATE(NUMERIC):B_IDLE_ENERGY ACCEPT AT(15,22) SIZE(-4) VALIDATE(NUMERIC)_IDLE_ENERGY ACCEPT AT(16,19) SIZE(-2) VALIDATE(DIGIT):HUNT_ENERGY ACCEPT AT(17,20) SIZE(-2) VALIDATE(DIGIT):REP_ENERGY ACCEPT AT(18,23) SIZE(-2) VALIDATE(DIGIT):REST_LEVEL ACCEPT AT(19,26) SIZE(-4) VALIDATE(NUMERIC):FLEE_MULT ACCEPT AT(20,21) SIZE(-2) VALIDATE(DIGIT):REP_CYCLE ACCEPT AT(21,13) SIZE(-2) VALIDATE(DIGIT):FOOD_CYCLE CALL CLEAR // SELECT BUGS GENETIC MAKEUP, ENERGY AND REPRODUCTIVE CYCLE // BUG(ID,0)=SPEED 1-3 // BUG(ID,1)=VIGILANCE 1-5 // BUG(ID,2)=SOCIAL TENDENCY 1-10 // BUG(ID,3)=ENERGY LEVEL 0-B_MAX_ENERGY // BUG(ID,4)=REPRODUCTIVE CYCLE 0-1 // BUG(ID,5)=ALIVE FLAG (0=DEAD, 1=ALIVE) FOR ID=0 TO 50 :: BPHASE(ID)=1 :: FLEE_FLAG(ID)=0 :: FOR G=0 TO 5 :: BUG(ID,G)=0 :: NEXT G :: NEXT ID FOR ID=0 TO NEXT_ID-1 BUG(ID,0)=INT(RND*3)+1 :: BUG(ID,1)=INT(RND*5)+1 :: BUG(ID,2)=INT(RND*10)+1 :: BUG(ID,3)=B_MAX_ENERGY-2 :: BUG(ID,5)=1 :: NEXT ID // SET ENERGY LEVEL OF PREDATORS // ENERGY 0-P_MAX_ENERGY FOR ID=0 TO PRED_NUM-1 :: PRED(ID)=P_MAX_ENERGY-5:: PPHASE(ID)=1 :: NEXT ID // DRAW ENVIRONMENT CALL HCHAR(1,1,96,32) :: CALL VCHAR(2,1,96,23) :: CALL VCHAR(2,32,96,23) :: CALL HCHAR(24,2,96,30) ! DRAW BORDER FOR I=1 TO OBSTACLE_NUM :: CALL PLACE(X,Y) :: CALL HCHAR(Y,X,104):: NEXT I ! PLACE OBSTACLES FOR I=1 TO FOOD_NUM :: CALL PLACE(X,Y) :: CALL HCHAR(Y,X,128) :: NEXT I ! PLACE FOOD WIDGETS // PLACE BUGS AND PREDATORS ON FIELD FOR ID=0 TO NEXT_ID-1 :: CALL PLACE(X,Y) :: BUGX(ID)=X :: BUGY(ID)=Y :: CALL HCHAR(Y,X,112) :: NEXT ID FOR ID=0 TO PRED_NUM-1 :: CALL PLACE(X,Y) :: PREDX(ID)=X :: PREDY(ID)=Y :: CALL HCHAR(Y,X,120) :: NEXT ID // START OF SIMULATION RESTART=0 DEAD_FLAG=0 ! INDICATES DEATH OF BUGS EVERY CYCLE TCYCLE=0 ! TOTAL NUMBER OF ELAPSED CYCLES new_cycle: TCYCLE=TCYCLE+1 :: DISPLAY AT(24,1) SIZE(4):TCYCLE :: BUG_NUMBER=NEXT_ID-1 IF DEAD_FLAG=1 THEN .. GOSUB purge_dead FOR ID=0 TO BUG_NUMBER ON BPHASE(ID) GOSUB .. bug_phase_one, .. bug_phase_two, .. bug_phase_three GOSUB command_check IF RESTART=1 THEN .. new_simulation NEXT ID FOR ID=0 TO PRED_NUM-1 ON PPHASE(ID) GOSUB .. pred_phase_one, .. pred_phase_two, .. pred_phase_three, .. pred_phase_four GOSUB command_check IF RESTART=1 THEN .. new_simulation NEXT ID RCYCLE=RCYCLE+1 :: FCYCLE=FCYCLE+1 IF DEAD_FLAG=0 THEN .. check_reproduction GOSUB purge_dead check_reproduction: IF RCYCLE<REP_CYCLE OR NEXT_ID>=51 THEN .. check_food RCYCLE=0 FOR I=0 TO NEXT_ID-1 IF BUG(I,3)>7 AND FLEE_FLAG(I)=0 THEN .. BUG(I,4)=1 :: BPHASE(I)=3 NEXT I check_food: IF FCYCLE=FOOD_CYCLE THEN .. FCYCLE=0 :: GOSUB food_regen GOTO new_cycle // PHASE 1: BUGS LOOK AROUND AND PREDATORS SEARCH FOR PREY bug_phase_one: CALL LOOK(BUGX(ID),BUGY(ID),PREDATOR,FOOD,FRIEND,PX,PY,FX,FY,FRX,FRY,BUG(ID,1)) IF PREDATOR=1 AND BUG(ID,3)>(BUG(ID,0)*FLEE_MULT) THEN .. BPHASE(ID)=2 :: TARGETX(ID)=PX :: TARGETY(ID)=PY :: FLEE_FLAG(ID)=1 :: RETURN ! PREDATOR DETECTED IF FOOD=1 AND BUG(ID,3)<B_MAX_ENERGY THEN .. BPHASE(ID)=2 :: TARGETX(ID)=FX :: TARGETY(ID)=FY :: RETURN ! FOOD DETECTED IF FRIEND=0 THEN .. random_move IF BUG(ID,2)>7 THEN .. select_target PROB=INT(RND*10)+1 IF BUG(ID,2)>4 AND PROB>3 THEN .. select_target IF BUG(ID,2)<4 AND PROB>7 THEN .. select_target .. ELSE .. random_move select_target: BPHASE(ID)=2 :: TARGETX(ID)=FRX :: TARGETY(ID)=FRY :: BUG(ID,3)=BUG(ID,3)-B_IDLE_ENERGY IF BUG(ID,3)<=0 THEN .. BUG(ID,5)=0 :: DEAD_FLAG=1 :: CALL HCHAR(BUGY(ID),BUGX(ID),32) :: RETURN random_move: FOR I=1 TO BUG(ID,0) TX=BUGX(ID) :: TY=BUGY(ID) CALL HCHAR(TY,TX,32) :: CALL MOVE(BUGX(ID),BUGY(ID),OBJ) IF OBJ=120 THEN .. BUGX(ID)=TX :: BUGY(ID)=TY :: DEAD_FLAG=1 :: BUG(ID,5)=0 :: RETURN IF OBJ=128 THEN .. BUG(ID,3)=BUG(ID,3)+FOOD_ENERGY :: CALL HCHAR(BUGY(ID),BUGX(ID),112):: IF BUG(ID,3)>B_MAX_ENERGY THEN .. BUG(ID,3)=B_MAX_ENERGY :: RETURN IF OBJ=112 THEN .. BUGX(ID)=TX :: BUGY(ID)=TY CALL HCHAR(BUGY(ID),BUGX(ID),112) NEXT I BUG(ID,3)=BUG(ID,3)-B_MOVE_ENERGY IF BUG(ID,3)<=0 THEN .. BUG(ID,5)=0 :: DEAD_FLAG=1 :: CALL HCHAR(BUGY(ID),BUGX(ID),32) RETURN pred_phase_one: IF PRED(ID)>=REST_LEVEL THEN .. PPHASE(ID)=3 :: RETURN CALL SEARCH(PREDX(ID),PREDY(ID),PREY,PRX,PRY) IF PREY=1 THEN .. target_prey FOR I=1 TO 5 TX=PREDX(ID) :: TY=PREDY(ID) CALL HCHAR(PREDY(ID),PREDX(ID),32) :: CALL MOVE(PREDX(ID),PREDY(ID),OBJ) IF OBJ=120 THEN .. PREDX(ID)=TX :: PREDY(ID)=TY IF OBJ=112 THEN .. GOSUB find_bug :: PRED(ID)=PRED(ID)+P_FOOD_ENERGY :: IF PRED(ID)>P_MAX_ENERGY THEN .. PRED(ID)=P_MAX_ENERGY :: CALL HCHAR(PREDY(ID),PREDX(ID),120) :: RETURN CALL HCHAR(PREDY(ID),PREDX(ID),120) NEXT I PRED(ID)=PRED(ID)-P_MOVE_ENERGY IF PRED(ID)<=0 THEN .. CALL HCHAR(PREDY(ID),PREDX(ID),32) :: PPHASE(ID)=4 RETURN target_prey: PTARGETX(ID)=PRX :: PTARGETY(ID)=PRY :: PPHASE(ID)=2 :: PRED(ID)=PRED(ID)-P_IDLE_ENERGY IF PRED(ID)<=0 THEN .. CALL HCHAR(PREDY(ID),PREDX(ID),32) :: PPHASE(ID)=4 RETURN // PHASE 2: BUGS SEEK FOOD/OTHER BUGS OR FLEE PREDATORS. PREDATORS HUNT DOWN BUGS bug_phase_two: BPHASE(ID)=1 IF FLEE_FLAG(ID)=1 THEN .. CALL FLEE(BUGX(ID),BUGY(ID),TARGETX(ID),TARGETY(ID),BUG(ID,0)) .. ELSE continue BUG(ID,3)=BUG(ID,3)-(BUG(ID,0)*FLEE_MULT) :: FLEE_FLAG(ID)=0 :: RETURN continue: FOR I=1 TO BUG(ID,0) CALL HCHAR(BUGY(ID),BUGX(ID),32) :: TX=BUGX(ID) :: TY=BUGY(ID) CALL TARGET_MOVE(BUGX(ID),BUGY(ID),TARGETX(ID),TARGETY(ID),OBJ,DX,DY) IF OBJ=120 THEN .. DEAD_FLAG=1 :: BUG(ID,5)=0 :: CALL HCHAR(BUGY(ID),BUGX(ID),32) :: RETURN IF OBJ=112 THEN .. BUGX(ID)=TX :: BUGY(ID)=TY IF OBJ=128 THEN .. BUGX(ID)=BUGX(ID)+DX :: BUGY(ID)=BUGY(ID)+DY :: BUG(ID,3)=BUG(ID,3)+FOOD_ENERGY :: IF BUG(ID,3)>B_MAX_ENERGY THEN .. BUG(ID,3)=B_MAX_ENERGY :: GOTO continue1 IF OBJ=32 THEN .. BUGX(ID)=BUGX(ID)+DX :: BUGY(ID)=BUGY(ID)+DY CALL HCHAR(BUGY(ID),BUGX(ID),112) NEXT I continue1: CALL HCHAR(BUGY(ID),BUGX(ID),112) BUG(ID,3)=BUG(ID,3)-B_MOVE_ENERGY IF BUG(ID,3)<=0 THEN .. BUG(ID,5)=0 :: DEAD_FLAG=1 :: CALL HCHAR(BUGY(ID),BUGX(ID),32) RETURN pred_phase_two: FOR I=1 TO 5 TX=PREDX(ID) :: TY=PREDY(ID) CALL HCHAR(PREDY(ID),PREDX(ID),32) :: CALL TARGET_MOVE(PREDX(ID),PREDY(ID),PTARGETX(ID),PTARGETY(ID),OBJ,DX,DY) IF OBJ<>112 THEN .. check_obstructions PREDX(ID)=PREDX(ID)+DX :: PREDY(ID)=PREDY(ID)+DY :: GOSUB find_bug :: PRED(ID)=PRED(ID)+P_FOOD_ENERGY :: GOTO continue3 check_obstructions: IF OBJ<>32 AND OBJ<>128 THEN .. continue3 PTARGETX(ID)=PTARGETX(ID)+DX :: PTARGETY(ID)=PTARGETY(ID)+DY :: PREDX(ID)=PREDX(ID)+DX :: PREDY(ID)=PREDY(ID)+DY CALL HCHAR(PREDY(ID),PREDX(ID),120) NEXT I continue3: IF PRED(ID)>P_MAX_ENERGY THEN .. PRED(ID)=P_MAX_ENERGY PRED(ID)=PRED(ID)-HUNT_ENERGY IF PRED(ID)>REST_LEVEL THEN .. PPHASE(ID)=3 IF PRED(ID)<=0 THEN .. CALL HCHAR(PREDY(ID),PREDX(ID),32) :: PPHASE(ID)=4 .. ELSE .. CALL HCHAR(PREDY(ID),PREDX(ID),120) :: PPHASE(ID)=1 RETURN // PHASE 3: BUGS REPRODUCE AND PREDATORS REST bug_phase_three: IF BUG(ID,3)<8 OR NEXT_ID>50 THEN .. BUG(ID,4)=0 :: BPHASE(ID)=1 :: BUG(ID,3)=BUG(ID,3)-B_IDLE_ENERGY :: RETURN CALL REPRODUCE(BUGX(ID),BUGY(ID),NX,NY) :: IF NX=BUGX(ID) AND NY=BUGY(ID) THEN .. BUG(ID,3)=BUG(ID,3)-B_IDLE_ENERGY :: RETURN BUG(ID,4)=0 :: BUG(ID,3)=BUG(ID,3)-REP_ENERGY :: CALL HCHAR(NY,NX,112) :: BPHASE(ID)=1 BUGX(NEXT_ID)=NX :: BUGY(NEXT_ID)=NY :: BUG(NEXT_ID,0)=BUG(ID,0) :: BUG(NEXT_ID,1)=BUG(ID,1) :: BUG(NEXT_ID,2)=BUG(ID,2) BUG(NEXT_ID,3)=8 :: BUG(NEXT_ID,4)=0 :: BUG(NEXT_ID,5)=1 BPHASE(NEXT_ID)=1 :: NEXT_ID=NEXT_ID+1 RETURN pred_phase_three: PRED(ID)=PRED(ID)-P_IDLE_ENERGY IF PRED(ID)<REST_LEVEL THEN .. PPHASE(ID)=1 RETURN // PHASE 4: DEAD PREDATOR. NO ACTION pred_phase_four: RETURN purge_dead: ID=0 :: DEAD_FLAG=0 purge_loop: IF ID=NEXT_ID-1 AND BUG(ID,5)=0 THEN .. NEXT_ID=NEXT_ID-1 :: IF NEXT_ID=0 THEN .. end_simulation .. ELSE .. RETURN IF BUG(ID,5)=1 THEN .. ID=ID+1 :: IF ID=NEXT_ID THEN .. RETURN .. ELSE .. purge_loop FOR I=ID+1 TO NEXT_ID-1 FOR J=0 TO 5 BUG(I-1,J)=BUG(I,J) NEXT J BUGX(I-1)=BUGX(I) :: BUGY(I-1)=BUGY(I) :: TARGETX(I-1)=TARGETX(I) :: TARGETY(I-1)=TARGETY(I) :: FLEE_FLAG(I-1)=FLEE_FLAG(I) :: BPHASE(I-1)=BPHASE(I) NEXT I NEXT_ID=NEXT_ID-1 :: IF NEXT_ID=0 THEN .. end_simulation GOTO purge_loop find_bug: FOR Z=0 TO NEXT_ID-1 IF BUGX(Z)=PREDX(ID) AND BUGY(Z)=PREDY(ID) AND BUG(Z,5)=1 THEN .. DEAD_FLAG=1 :: BUG(Z,5)=0 :: RETURN NEXT Z command_check: CALL KEY(0,K,S) IF K=83 OR K=115 THEN .. STOP IF K=82 OR K=114 THEN .. RESTART=1 :: RETURN IF K<>71 AND K<>103 THEN .. RETURN FOR I=1 TO 22 FIELD$(I)="" NEXT I FOR I=1 TO 3 SPEED(I)=0 NEXT I FOR I=1 TO 5 VIG(I)=0 NEXT I FOR I=1 TO 10 SOCIAL(I)=0 NEXT I FOR Y=2 TO 23 FOR X=2 TO 31 CALL GCHAR(Y,X,OBJ) IF OBJ=128 OR OBJ=104 THEN .. IF X<10 THEN .. FIELD$(Y-1)=FIELD$(Y-1)&"0"&STR$(X)&STR$(OBJ) .. ELSE .. FIELD$(Y-1)=FIELD$(Y-1)&STR$(X)&STR$(OBJ) NEXT X FIELD$(Y-1)=FIELD$(Y-1)&"99" NEXT Y DISPLAY AT(23,2) ERASE ALL:"123 12345 1234567890" DISPLAY AT(24,1):"SPEED VIGILANCE SOCIAL" FOR I=0 TO NEXT_ID-1 SPEED(BUG(I,0))=SPEED(BUG(I,0))+1 VIG(BUG(I,1))=VIG(BUG(I,1))+1 SOCIAL(BUG(I,2))=SOCIAL(BUG(I,2))+1 NEXT I FOR I=1 TO 3 DISPLAY AT(22-INT(SPEED(I)/2),1+I):"*" NEXT I FOR I=1 TO 5 DISPLAY AT(22-INT(VIG(I)/2),9+I):"*" NEXT I FOR I=1 TO 10 DISPLAY AT(22-INT(SOCIAL(I)/2),18+I):"*" NEXT I key_loop: CALL KEY(0,K,S) :: IF S=0 THEN .. key_loop CALL CLEAR :: I=1 CALL HCHAR(1,1,96,32) :: CALL VCHAR(2,1,96,23) :: CALL VCHAR(2,32,96,23) :: CALL HCHAR(24,2,96,30) ! DRAW BORDER FOR Y=2 TO 23 fetch_next_x: X=VAL(SEG$(FIELD$(Y-1),I,2)) IF X=99 THEN .. next_line OBJ=VAL(SEG$(FIELD$(Y-1),I+2,3)) :: CALL HCHAR(Y,X,OBJ) :: I=I+5 :: GOTO fetch_next_x next_line: I=1 NEXT Y FOR I=0 TO NEXT_ID-1 CALL HCHAR(BUGY(I),BUGX(I),112) NEXT I FOR I=0 TO PRED_NUM-1 IF PPHASE(I)<4 THEN .. CALL HCHAR(PREDY(I),PREDX(I),120) NEXT I DISPLAY AT(24,1) SIZE(4):TCYCLE RETURN end_simulation: DISPLAY AT(10,4) BEEP:"THE COLONY HAS DIED!" :: DISPLAY AT(12,4):"RESTART SIMULATION?" check_key_loop: CALL KEY(0,K,S) :: IF S=0 THEN .. check_key_loop IF K=89 OR K=121 THEN .. new_simulation .. ELSE .. STOP // DATA FOR LOOK AND SEARCH ROUTINES look_data: DATA -1,-1,-1,1,0,-1,0,1,1,-1,1,1 DATA -2,-2,-2,2,0,-2,0,2,2,-2,2,2 DATA -3,-3,-3,3,0,-3,0,3,3,-3,3,3 DATA -4,-4,-4,4,0,-4,0,4,4,-4,4,4 DATA -5,-5,-5,5,0,-5,0,5,5,-5,5,5 // FOOD REGENERATION ROUTINE food_regen: FOR I=1 TO FOOD_REGEN :: CALL PLACE(X,Y) :: CALL HCHAR(Y,X,128) :: NEXT I RETURN // RANDOM SCREEN OBJECT PLACEMENT ROUTINE SUB PLACE(X,Y) sub_place_loop: X=INT(RND*30)+2 :: Y=INT(RND*21)+2 CALL GCHAR(Y,X,C) :: IF C<>32 THEN sub_place_loop SUBEND // RANDOM MOVEMENT DIRECTION GENERATION ROUTINE SUB DIR(CX,CY) sub_dir_loop: CX=INT(RND*2) :: DIR=INT(RND*10)+1 :: IF DIR>5 THEN CX=-CX CY=INT(RND*2) :: DIR=INT(RND*10)+1 :: IF DIR>5 THEN CY=-CY IF CX=0 AND CY=0 THEN sub_dir_loop SUBEND // LOOK AROUND ROUTINE SUB LOOK(BUGX,BUGY,PREDATOR,FOOD,FRIEND,PX,PY,FX,FY,FRX,FRY,V) FOR I=1 TO 6 :: BLOCK(I)=0 :: NEXT I PREDATOR,FOOD,FRIEND=0 RESTORE look_data FOR I=1 TO V FOR J=1 TO 6 READ DX,DY IF BLOCK(J)=1 THEN .. look_advance IF BUGX+DX>0 AND BUGX+DX<33 THEN .. X=BUGX+DX IF BUGY+DY>0 AND BUGY+DY<25 THEN .. Y=BUGY+DY :: CALL GCHAR(Y,X,OBJ) IF OBJ=96 OR OBJ=104 THEN .. BLOCK(J)=1 :: GOTO look_advance ! SKIP OBSTRUCTIONS IF OBJ=120 THEN .. PREDATOR=1 :: PX=X :: PY=Y :: SUBEXIT ! LOOK FOR PREDATORS IF OBJ=128 AND FOOD=0 THEN .. FOOD=1 :: FX=X :: FY=Y :: GOTO look_advance! LOOK FOR FOOD IF OBJ=112 AND FRIEND=0 THEN .. FRIEND=1 :: BLOCK(J)=1 :: FRX=X :: FRY=Y ! LOOK FOR OTHER BUGS look_advance: NEXT J NEXT I SUBEND // FLEE ROUTINE SUB FLEE(BUGX,BUGY,PX,PY,S) X=BUGX :: Y=BUGY :: FOR I=1 TO S CALL HCHAR(Y,X,32) pick_new_dir: CALL DIR(CX,CY) NX=X+CX :: NY=Y+CY :: CALL GCHAR(NY,NX,OBJ) IF NX<2 OR NX>31 OR NY<2 OR NY>23 OR OBJ=104 THEN .. GOTO flee_loop ! AVOID ALL OBSTRUCTIONS PDIST=INT(SQR((PX-X)^2+(PY-Y)^2)) :: NDIST=INT(SQR((PX-NX)^2+(PY-NY)^2)) IF NDIST<=PDIST THEN .. GOTO pick_new_dir ! AVOID DIRECTIONS TOWARDS PREDATOR X=NX :: Y=NY flee_loop: CALL HCHAR(Y,X,112) NEXT I BUGX=X :: BUGY=Y SUBEND // TARGETED MOVEMENT ROUTINE SUB TARGET_MOVE(ORGX,ORGY,TX,TY,OBJ,DX,DY) DX=0 :: DY=0 IF TX-ORGX>0 THEN .. DX=1 :: GOTO check_y IF TX-ORGX<0 THEN .. DX=-1 check_y: IF TY-ORGY>0 THEN .. DY=1 :: GOTO update_pos IF TY-ORGY<0 THEN .. DY=-1 update_pos: X=ORGX+DX :: Y=ORGY+DY :: CALL GCHAR(Y,X,OBJ) IF OBJ=104 THEN .. DX=0 :: DY=0 SUBEND // UNTARGETED MOVEMENT ROUTINE SUB MOVE(ORGX,ORGY,OBJ) move_loop: CALL DIR(DX,DY) :: X=ORGX+DX :: Y=ORGY+DY :: CALL GCHAR(Y,X,OBJ) IF X<2 OR X>31 OR Y<2 OR Y>23 OR OBJ=104 THEN .. move_loop ORGX=X :: ORGY=Y SUBEND // PREDATOR SEARCH FOR PREY ROUTINE SUB SEARCH(PREDX,PREDY,PREY,PRX,PRY) FOR I=1 TO 6 :: BLOCK(I)=0 :: NEXT I PREY=0 :: RESTORE look_data FOR I=1 TO 5 FOR J=1 TO 6 READ DX,DY IF BLOCK(J)=1 THEN .. search_advance IF PREDX+DX>0 AND PREDX+DX<33 THEN .. X=PREDX+DX .. ELSE .. search_advance IF PREDY+DY>0 AND PREDY+DY<25 THEN .. Y=PREDY+DY .. ELSE .. search_advance CALL GCHAR(Y,X,OBJ) IF OBJ=96 OR OBJ=104 THEN .. BLOCK(J)=1 :: GOTO search_advance ! SKIP OBSTRUCTIONS IF OBJ=112 THEN .. PREY=1 :: PRX=X :: PRY=Y :: SUBEXIT ! LOOK FOR PREY IF OBJ=120 THEN .. BLOCK(J)=1 search_advance: NEXT J NEXT I SUBEND // BUG REPRODUCTION ROUTINE SUB REPRODUCE(X,Y,NX,NY) NX=0 :: NY=0 FOR I=X-1 TO X+1 FOR J=Y-1 TO Y+1 CALL GCHAR(J,I,OBJ) :: IF OBJ=32 OR OBJ=128 THEN .. NX=I :: NY=J :: SUBEXIT NEXT J NEXT I IF NX=0 AND NY=0 THEN .. NX=X :: NY=Y SUBEND And here's the actual XB code after running the source through Matthew180's TidBit utility. I have to say that I very highly recommend TidBit for any non-trivial XB program because formatting the source code immensely enhances readability and reduces errors. Matt, I was wondering if you would consider creating a stand-alone version of TidBit so we are not dependent on having an internet connection all the time. 100 RANDOMIZE 110 DIM BUG(50,5), BUGX(50), BUGY(50), PRED(10), PREDX(10), PREDY(10), BPHASE(50), PPHASE(10) 120 DIM TARGETX(50), TARGETY(50), FLEE_FLAG(50), PTARGETX(10), PTARGETY(10), SPEED(3), VIG(5), SOCIAL(10) 130 DIM FIELD$(22) 140 CALL CHAR (128,"0000001818000000" ,96,"FFFFFFFFFFFFFFFF" ,104,"007E7E7E7E7E7E00" ,112,"80433C3C3C7C8204" ,120,"7CFEF3BF1FBFFE7C") 150 CALL COLOR(13,14,1,9,13,1,10,15,1,11,5,1,12,9,1) 160 CALL SCREEN(4) 170 NEXT_ID=20 ! TOTAL NUMBER OF BUGS 180 PRED_NUM=5 ! INITIAL NUMBER OF PREDATORS 190 FOOD_NUM=70 ! INITIAL NUMBER OF FOOD 200 OBSTACLE_NUM=10 ! NUMBER OF OBSTACLES 210 FOOD_REGEN=20 ! NUMBER OF FOOD WIDGETS REGENERATED PER FOOD CYCLE 220 B_MAX_ENERGY=10 ! MAXIMUM ENERGY LEVEL FOR BUGS 230 P_MAX_ENERGY=20 ! MAXIMUM ENERGY LEVEL FOR PREDATORS 240 FOOD_ENERGY=2 ! ENERGY GAIN FROM EATING FOOD FOR BUGS 250 P_FOOD_ENERGY=6 ! ENERGY GAIN FROM EATING PREY FOR PREDATORS 260 B_MOVE_ENERGY=1 ! BUGS ENERGY LOSS FROM MOVEMENT 270 P_MOVE_ENERGY=1 ! PREDATORS ENERGY LOSS FROM MOVEMENT 280 B_IDLE_ENERGY=0.5 ! BUGS ENERGY LOSS FROM INACTIVITY 290 P_IDLE_ENERGY=0.75 ! PREDATORS ENERGY LOSS FROM INACTIVITY 300 HUNT_ENERGY=3 ! ENERGY LOSS FROM HUNTING 310 REP_ENERGY=3 ! ENERGY LOSS FROM REPRODUCTION 320 REST_LEVEL=15 ! ENERGY LEVEL AT OR ABOVE WHICH PREDATORS REST 330 FLEE_MULT=1.5 ! MULTIPLYER FOR FLEE ENERGY LOSS 340 RCYCLE=0 ! REPRODUCTIVE CYCLE COUNTER 350 FCYCLE=0 ! FOOD REGENERATION CYCLE COUNTER 360 REP_CYCLE=5 ! REPRODUCTION OCCURS EVERY REP_CYCLE 370 FOOD_CYCLE=10 ! FOOD_REGEN FOOD WIDGETS REGENERATED EVERY FOOD_CYCLE 380 CALL CLEAR 390 DISPLAY AT(1,1)BEEP:"INITIAL SIMULATION VARIABLES" 400 DISPLAY AT(3,1):"NUMBER OF BUGS:";NEXT_ID 410 DISPLAY AT(4,1):"NUMBER OF PREDATORS:";PRED_NUM 420 DISPLAY AT(5,1):"NUMBER OF FOOD WIDGETS:";FOOD_NUM 430 DISPLAY AT(6,1):"NUMBER OF OBSTACLES:";OBSTACLE_NUM 440 DISPLAY AT(7,1):"FOOD REGENERATION CYCLE:";FOOD_REGEN 450 DISPLAY AT(8,1):"BUGS MAX ENERGY:";B_MAX_ENERGY 460 DISPLAY AT(9,1):"PREDATORS MAX ENERGY:";P_MAX_ENERGY 470 DISPLAY AT(10,1):"FOOD ENERGY GAIN:";FOOD_ENERGY 480 DISPLAY AT(11,1):"PREY ENERGY GAIN:";P_FOOD_ENERGY 490 DISPLAY AT(12,1):"BUGS MOVE COST:";B_MOVE_ENERGY 500 DISPLAY AT(13,1):"PREDATORS MOVE COST:";P_MOVE_ENERGY 510 DISPLAY AT(14,1):"BUGS IDLE COST:";B_IDLE_ENERGY 520 DISPLAY AT(15,1):"PREDATORS IDLE COST:";P_IDLE_ENERGY 530 DISPLAY AT(16,1):"HUNT ENERGY COST:";HUNT_ENERGY 540 DISPLAY AT(17,1):"REPRODUCTIVE COST:";REP_ENERGY 550 DISPLAY AT(18,1):"PREDATORS REST LEVEL:";REST_LEVEL 560 DISPLAY AT(19,1):"FLEEING COST MULTIPLYER:";FLEE_MULT 570 DISPLAY AT(20,1):"REPRODUCTIVE CYCLE:";REP_CYCLE 580 DISPLAY AT(21,1):"FOOD CYCLE:";FOOD_CYCLE 590 ACCEPT AT(3,17) SIZE(-2) VALIDATE(DIGIT):NEXT_ID 600 IF NEXT_ID<0 OR NEXT_ID>50 THEN 590 610 ACCEPT AT(4,22) SIZE(-2) VALIDATE(DIGIT):PRED_NUM 620 IF PRED_NUM>10 THEN 610 630 ACCEPT AT(5,25) SIZE(-3) VALIDATE(DIGIT):FOOD_NUM 640 ACCEPT AT(6,22) SIZE(-3) VALIDATE(DIGIT):OBSTACLE_NUM 650 ACCEPT AT(7,26) SIZE(-2) VALIDATE(DIGIT):FOOD_REGEN 660 ACCEPT AT(8,18) SIZE(-2) VALIDATE(DIGIT):B_MAX_ENERGY 670 ACCEPT AT(9,23) SIZE(-2) VALIDATE(DIGIT) _MAX_ENERGY 680 ACCEPT AT(10,19) SIZE(-2) VALIDATE(DIGIT):FOOD_ENERGY 690 ACCEPT AT(11,19) SIZE(-2) VALIDATE(DIGIT) _FOOD_ENERGY 700 ACCEPT AT(12,17) SIZE(-2) VALIDATE(DIGIT):B_MOVE_ENERGY 710 ACCEPT AT(13,22) SIZE(-2) VALIDATE(DIGIT) _MOVE_ENERGY 720 ACCEPT AT(14,17) SIZE(-4) VALIDATE(NUMERIC):B_IDLE_ENERGY 730 ACCEPT AT(15,22) SIZE(-4) VALIDATE(NUMERIC) _IDLE_ENERGY 740 ACCEPT AT(16,19) SIZE(-2) VALIDATE(DIGIT):HUNT_ENERGY 750 ACCEPT AT(17,20) SIZE(-2) VALIDATE(DIGIT):REP_ENERGY 760 ACCEPT AT(18,23) SIZE(-2) VALIDATE(DIGIT):REST_LEVEL 770 ACCEPT AT(19,26) SIZE(-4) VALIDATE(NUMERIC):FLEE_MULT 780 ACCEPT AT(20,21) SIZE(-2) VALIDATE(DIGIT):REP_CYCLE 790 ACCEPT AT(21,13) SIZE(-2) VALIDATE(DIGIT):FOOD_CYCLE 800 CALL CLEAR 810 FOR ID=0 TO 50 :: BPHASE(ID)=1 :: FLEE_FLAG(ID)=0 :: FOR G=0 TO 5 :: BUG(ID,G)=0 :: NEXT G :: NEXT ID 820 FOR ID=0 TO NEXT_ID-1 830 BUG(ID,0)=INT(RND*3)+1 :: BUG(ID,1)=INT(RND*5)+1 :: BUG(ID,2)=INT(RND*10)+1 :: BUG(ID,3)=B_MAX_ENERGY-2 :: BUG(ID,5)=1 :: NEXT ID 840 FOR ID=0 TO PRED_NUM-1 :: PRED(ID)=P_MAX_ENERGY-5:: PPHASE(ID)=1 :: NEXT ID 850 CALL HCHAR(1,1,96,32) :: CALL VCHAR(2,1,96,23) :: CALL VCHAR(2,32,96,23) :: CALL HCHAR(24,2,96,30) ! DRAW BORDER 860 FOR I=1 TO OBSTACLE_NUM :: CALL PLACE(X,Y) :: CALL HCHAR(Y,X,104):: NEXT I ! PLACE OBSTACLES 870 FOR I=1 TO FOOD_NUM :: CALL PLACE(X,Y) :: CALL HCHAR(Y,X,128) :: NEXT I ! PLACE FOOD WIDGETS 880 FOR ID=0 TO NEXT_ID-1 :: CALL PLACE(X,Y) :: BUGX(ID)=X :: BUGY(ID)=Y :: CALL HCHAR(Y,X,112) :: NEXT ID 890 FOR ID=0 TO PRED_NUM-1 :: CALL PLACE(X,Y) :: PREDX(ID)=X :: PREDY(ID)=Y :: CALL HCHAR(Y,X,120) :: NEXT ID 900 RESTART=0 910 DEAD_FLAG=0 ! INDICATES DEATH OF BUGS EVERY CYCLE 920 TCYCLE=0 ! TOTAL NUMBER OF ELAPSED CYCLES 930 TCYCLE=TCYCLE+1 :: DISPLAY AT(24,1) SIZE(4):TCYCLE :: BUG_NUMBER=NEXT_ID-1 940 IF DEAD_FLAG=1 THEN GOSUB 1930 950 FOR ID=0 TO BUG_NUMBER 960 ON BPHASE(ID) GOSUB 1150,1520,1820 970 GOSUB 2070 980 IF RESTART=1 THEN 380 990 NEXT ID 1000 FOR ID=0 TO PRED_NUM-1 1010 ON PPHASE(ID) GOSUB 1360,1680,1890,1920 1020 GOSUB 2070 1030 IF RESTART=1 THEN 380 1040 NEXT ID 1050 RCYCLE=RCYCLE+1 :: FCYCLE=FCYCLE+1 1060 IF DEAD_FLAG=0 THEN 1080 1070 GOSUB 1930 1080 IF RCYCLE=51 THEN 1130 1090 RCYCLE=0 1100 FOR I=0 TO NEXT_ID-1 1110 IF BUG(I,3)>7 AND FLEE_FLAG(I)=0 THEN BUG(I,4)=1 :: BPHASE(I)=3 1120 NEXT I 1130 IF FCYCLE=FOOD_CYCLE THEN FCYCLE=0 :: GOSUB 2710 1140 GOTO 930 1150 CALL LOOK(BUGX(ID),BUGY(ID),PREDATOR,FOOD,FRIEND,PX,PY,FX,FY,FRX,FRY,BUG(ID,1)) 1160 IF PREDATOR=1 AND BUG(ID,3)>(BUG(ID,0)*FLEE_MULT) THEN BPHASE(ID)=2 :: TARGETX(ID)=PX :: TARGETY(ID)=PY :: FLEE_FLAG(ID)=1 :: RETURN ! PREDATOR DETECTED 1170 IF FOOD=1 AND BUG(ID,3)1180 IF FRIEND=0 THEN 1250 1190 IF BUG(ID,2)>7 THEN 1230 1200 PROB=INT(RND*10)+1 1210 IF BUG(ID,2)>4 AND PROB>3 THEN 1230 1220 IF BUG(ID,2)<4 AND PROB>7 THEN 1230 ELSE 1250 1230 BPHASE(ID)=2 :: TARGETX(ID)=FRX :: TARGETY(ID)=FRY :: BUG(ID,3)=BUG(ID,3)-B_IDLE_ENERGY 1240 IF BUG(ID,3)<=0 THEN BUG(ID,5)=0 :: DEAD_FLAG=1 :: CALL HCHAR(BUGY(ID),BUGX(ID),32) :: RETURN 1250 FOR I=1 TO BUG(ID,0) 1260 TX=BUGX(ID) :: TY=BUGY(ID) 1270 CALL HCHAR(TY,TX,32) :: CALL MOVE(BUGX(ID),BUGY(ID),OBJ) 1280 IF OBJ=120 THEN BUGX(ID)=TX :: BUGY(ID)=TY :: DEAD_FLAG=1 :: BUG(ID,5)=0 :: RETURN 1290 IF OBJ=128 THEN BUG(ID,3)=BUG(ID,3)+FOOD_ENERGY :: CALL HCHAR(BUGY(ID),BUGX(ID),112):: IF BUG(ID,3)>B_MAX_ENERGY THEN BUG(ID,3)=B_MAX_ENERGY :: RETURN 1300 IF OBJ=112 THEN BUGX(ID)=TX :: BUGY(ID)=TY 1310 CALL HCHAR(BUGY(ID),BUGX(ID),112) 1320 NEXT I 1330 BUG(ID,3)=BUG(ID,3)-B_MOVE_ENERGY 1340 IF BUG(ID,3)<=0 THEN BUG(ID,5)=0 :: DEAD_FLAG=1 :: CALL HCHAR(BUGY(ID),BUGX(ID),32) 1350 RETURN 1360 IF PRED(ID)>=REST_LEVEL THEN PPHASE(ID)=3 :: RETURN 1370 CALL SEARCH(PREDX(ID),PREDY(ID),PREY,PRX,PRY) 1380 IF PREY=1 THEN 1490 1390 FOR I=1 TO 5 1400 TX=PREDX(ID) :: TY=PREDY(ID) 1410 CALL HCHAR(PREDY(ID),PREDX(ID),32) :: CALL MOVE(PREDX(ID),PREDY(ID),OBJ) 1420 IF OBJ=120 THEN PREDX(ID)=TX :: PREDY(ID)=TY 1430 IF OBJ=112 THEN GOSUB 2040 :: PRED(ID)=PRED(ID)+P_FOOD_ENERGY :: IF PRED(ID)>P_MAX_ENERGY THEN PRED(ID)=P_MAX_ENERGY :: CALL HCHAR(PREDY(ID),PREDX(ID),120) :: RETURN 1440 CALL HCHAR(PREDY(ID),PREDX(ID),120) 1450 NEXT I 1460 PRED(ID)=PRED(ID)-P_MOVE_ENERGY 1470 IF PRED(ID)<=0 THEN CALL HCHAR(PREDY(ID),PREDX(ID),32) :: PPHASE(ID)=4 1480 RETURN 1490 PTARGETX(ID)=PRX :: PTARGETY(ID)=PRY :: PPHASE(ID)=2 :: PRED(ID)=PRED(ID)-P_IDLE_ENERGY 1500 IF PRED(ID)<=0 THEN CALL HCHAR(PREDY(ID),PREDX(ID),32) :: PPHASE(ID)=4 1510 RETURN 1520 BPHASE(ID)=1 1530 IF FLEE_FLAG(ID)=1 THEN CALL FLEE(BUGX(ID),BUGY(ID),TARGETX(ID),TARGETY(ID),BUG(ID,0)) ELSE 1550 1540 BUG(ID,3)=BUG(ID,3)-(BUG(ID,0)*FLEE_MULT) :: FLEE_FLAG(ID)=0 :: RETURN 1550 FOR I=1 TO BUG(ID,0) 1560 CALL HCHAR(BUGY(ID),BUGX(ID),32) :: TX=BUGX(ID) :: TY=BUGY(ID) 1570 CALL TARGET_MOVE(BUGX(ID),BUGY(ID),TARGETX(ID),TARGETY(ID),OBJ,DX,DY) 1580 IF OBJ=120 THEN DEAD_FLAG=1 :: BUG(ID,5)=0 :: CALL HCHAR(BUGY(ID),BUGX(ID),32) :: RETURN 1590 IF OBJ=112 THEN BUGX(ID)=TX :: BUGY(ID)=TY 1600 IF OBJ=128 THEN BUGX(ID)=BUGX(ID)+DX :: BUGY(ID)=BUGY(ID)+DY :: BUG(ID,3)=BUG(ID,3)+FOOD_ENERGY :: IF BUG(ID,3)>B_MAX_ENERGY THEN BUG(ID,3)=B_MAX_ENERGY :: GOTO 1640 1610 IF OBJ=32 THEN BUGX(ID)=BUGX(ID)+DX :: BUGY(ID)=BUGY(ID)+DY 1620 CALL HCHAR(BUGY(ID),BUGX(ID),112) 1630 NEXT I 1640 CALL HCHAR(BUGY(ID),BUGX(ID),112) 1650 BUG(ID,3)=BUG(ID,3)-B_MOVE_ENERGY 1660 IF BUG(ID,3)<=0 THEN BUG(ID,5)=0 :: DEAD_FLAG=1 :: CALL HCHAR(BUGY(ID),BUGX(ID),32) 1670 RETURN 1680 FOR I=1 TO 5 1690 TX=PREDX(ID) :: TY=PREDY(ID) 1700 CALL HCHAR(PREDY(ID),PREDX(ID),32) :: CALL TARGET_MOVE(PREDX(ID),PREDY(ID),PTARGETX(ID),PTARGETY(ID),OBJ,DX,DY) 1710 IF OBJ<>112 THEN 1730 1720 PREDX(ID)=PREDX(ID)+DX :: PREDY(ID)=PREDY(ID)+DY :: GOSUB 2040 :: PRED(ID)=PRED(ID)+P_FOOD_ENERGY :: GOTO 1770 1730 IF OBJ<>32 AND OBJ<>128 THEN 1770 1740 PTARGETX(ID)=PTARGETX(ID)+DX :: PTARGETY(ID)=PTARGETY(ID)+DY :: PREDX(ID)=PREDX(ID)+DX :: PREDY(ID)=PREDY(ID)+DY 1750 CALL HCHAR(PREDY(ID),PREDX(ID),120) 1760 NEXT I 1770 IF PRED(ID)>P_MAX_ENERGY THEN PRED(ID)=P_MAX_ENERGY 1780 PRED(ID)=PRED(ID)-HUNT_ENERGY 1790 IF PRED(ID)>REST_LEVEL THEN PPHASE(ID)=3 1800 IF PRED(ID)<=0 THEN CALL HCHAR(PREDY(ID),PREDX(ID),32) :: PPHASE(ID)=4 ELSE CALL HCHAR(PREDY(ID),PREDX(ID),120) :: PPHASE(ID)=1 1810 RETURN 1820 IF BUG(ID,3)<8 OR NEXT_ID>50 THEN BUG(ID,4)=0 :: BPHASE(ID)=1 :: BUG(ID,3)=BUG(ID,3)-B_IDLE_ENERGY :: RETURN 1830 CALL REPRODUCE(BUGX(ID),BUGY(ID),NX,NY) :: IF NX=BUGX(ID) AND NY=BUGY(ID) THEN BUG(ID,3)=BUG(ID,3)-B_IDLE_ENERGY :: RETURN 1840 BUG(ID,4)=0 :: BUG(ID,3)=BUG(ID,3)-REP_ENERGY :: CALL HCHAR(NY,NX,112) :: BPHASE(ID)=1 1850 BUGX(NEXT_ID)=NX :: BUGY(NEXT_ID)=NY :: BUG(NEXT_ID,0)=BUG(ID,0) :: BUG(NEXT_ID,1)=BUG(ID,1) :: BUG(NEXT_ID,2)=BUG(ID,2) 1860 BUG(NEXT_ID,3)=8 :: BUG(NEXT_ID,4)=0 :: BUG(NEXT_ID,5)=1 1870 BPHASE(NEXT_ID)=1 :: NEXT_ID=NEXT_ID+1 1880 RETURN 1890 PRED(ID)=PRED(ID)-P_IDLE_ENERGY 1900 IF PRED(ID)1910 RETURN 1920 RETURN 1930 ID=0 :: DEAD_FLAG=0 1940 IF ID=NEXT_ID-1 AND BUG(ID,5)=0 THEN NEXT_ID=NEXT_ID-1 :: IF NEXT_ID=0 THEN 2630 ELSE RETURN 1950 IF BUG(ID,5)=1 THEN ID=ID+1 :: IF ID=NEXT_ID THEN RETURN ELSE 1940 1960 FOR I=ID+1 TO NEXT_ID-1 1970 FOR J=0 TO 5 1980 BUG(I-1,J)=BUG(I,J) 1990 NEXT J 2000 BUGX(I-1)=BUGX(I) :: BUGY(I-1)=BUGY(I) :: TARGETX(I-1)=TARGETX(I) :: TARGETY(I-1)=TARGETY(I) :: FLEE_FLAG(I-1)=FLEE_FLAG(I) :: BPHASE(I-1)=BPHASE(I) 2010 NEXT I 2020 NEXT_ID=NEXT_ID-1 :: IF NEXT_ID=0 THEN 2630 2030 GOTO 1940 2040 FOR Z=0 TO NEXT_ID-1 2050 IF BUGX(Z)=PREDX(ID) AND BUGY(Z)=PREDY(ID) AND BUG(Z,5)=1 THEN DEAD_FLAG=1 :: BUG(Z,5)=0 :: RETURN 2060 NEXT Z 2070 CALL KEY(0,K,S) 2080 IF K=83 OR K=115 THEN STOP 2090 IF K=82 OR K=114 THEN RESTART=1 :: RETURN 2100 IF K<>71 AND K<>103 THEN RETURN 2110 FOR I=1 TO 22 2120 FIELD$(I)="" 2130 NEXT I 2140 FOR I=1 TO 3 2150 SPEED(I)=0 2160 NEXT I 2170 FOR I=1 TO 5 2180 VIG(I)=0 2190 NEXT I 2200 FOR I=1 TO 10 2210 SOCIAL(I)=0 2220 NEXT I 2230 FOR Y=2 TO 23 2240 FOR X=2 TO 31 2250 CALL GCHAR(Y,X,OBJ) 2260 IF OBJ=128 OR OBJ=104 THEN IF X<10 THEN FIELD$(Y-1)=FIELD$(Y-1)&"0"&STR$(X)&STR$(OBJ) ELSE FIELD$(Y-1)=FIELD$(Y-1)&STR$(X)&STR$(OBJ) 2270 NEXT X 2280 FIELD$(Y-1)=FIELD$(Y-1)&"99" 2290 NEXT Y 2300 DISPLAY AT(23,2) ERASE ALL:"123 12345 1234567890" 2310 DISPLAY AT(24,1):"SPEED VIGILANCE SOCIAL" 2320 FOR I=0 TO NEXT_ID-1 2330 SPEED(BUG(I,0))=SPEED(BUG(I,0))+1 2340 VIG(BUG(I,1))=VIG(BUG(I,1))+1 2350 SOCIAL(BUG(I,2))=SOCIAL(BUG(I,2))+1 2360 NEXT I 2370 FOR I=1 TO 3 2380 DISPLAY AT(22-INT(SPEED(I)/2),1+I):"*" 2390 NEXT I 2400 FOR I=1 TO 5 2410 DISPLAY AT(22-INT(VIG(I)/2),9+I):"*" 2420 NEXT I 2430 FOR I=1 TO 10 2440 DISPLAY AT(22-INT(SOCIAL(I)/2),18+I):"*" 2450 NEXT I 2460 CALL KEY(0,K,S) :: IF S=0 THEN 2460 2470 CALL CLEAR :: I=1 2480 CALL HCHAR(1,1,96,32) :: CALL VCHAR(2,1,96,23) :: CALL VCHAR(2,32,96,23) :: CALL HCHAR(24,2,96,30) ! DRAW BORDER 2490 FOR Y=2 TO 23 2500 X=VAL(SEG$(FIELD$(Y-1),I,2)) 2510 IF X=99 THEN 2530 2520 OBJ=VAL(SEG$(FIELD$(Y-1),I+2,3)) :: CALL HCHAR(Y,X,OBJ) :: I=I+5 :: GOTO 2500 2530 I=1 2540 NEXT Y 2550 FOR I=0 TO NEXT_ID-1 2560 CALL HCHAR(BUGY(I),BUGX(I),112) 2570 NEXT I 2580 FOR I=0 TO PRED_NUM-1 2590 IF PPHASE(I)<4 THEN CALL HCHAR(PREDY(I),PREDX(I),120) 2600 NEXT I 2610 DISPLAY AT(24,1) SIZE(4):TCYCLE 2620 RETURN 2630 DISPLAY AT(10,4) BEEP:"THE COLONY HAS DIED!" :: DISPLAY AT(12,4):"RESTART SIMULATION?" 2640 CALL KEY(0,K,S) :: IF S=0 THEN 2640 2650 IF K=89 OR K=121 THEN 380 ELSE STOP 2660 DATA -1,-1,-1,1,0,-1,0,1,1,-1,1,1 2670 DATA -2,-2,-2,2,0,-2,0,2,2,-2,2,2 2680 DATA -3,-3,-3,3,0,-3,0,3,3,-3,3,3 2690 DATA -4,-4,-4,4,0,-4,0,4,4,-4,4,4 2700 DATA -5,-5,-5,5,0,-5,0,5,5,-5,5,5 2710 FOR I=1 TO FOOD_REGEN :: CALL PLACE(X,Y) :: CALL HCHAR(Y,X,128) :: NEXT I 2720 RETURN 2730 SUB PLACE(X,Y) 2740 X=INT(RND*30)+2 :: Y=INT(RND*21)+2 2750 CALL GCHAR(Y,X,C) :: IF C<>32 THEN 2740 2760 SUBEND 2770 SUB DIR(CX,CY) 2780 CX=INT(RND*2) :: DIR=INT(RND*10)+1 :: IF DIR>5 THEN CX=-CX 2790 CY=INT(RND*2) :: DIR=INT(RND*10)+1 :: IF DIR>5 THEN CY=-CY 2800 IF CX=0 AND CY=0 THEN 2780 2810 SUBEND 2820 SUB LOOK(BUGX,BUGY,PREDATOR,FOOD,FRIEND,PX,PY,FX,FY,FRX,FRY,V) 2830 FOR I=1 TO 6 :: BLOCK(I)=0 :: NEXT I 2840 PREDATOR,FOOD,FRIEND=0 2850 RESTORE 2660 2860 FOR I=1 TO V 2870 FOR J=1 TO 6 2880 READ DX,DY 2890 IF BLOCK(J)=1 THEN 2960 2900 IF BUGX+DX>0 AND BUGX+DX<33 THEN X=BUGX+DX 2910 IF BUGY+DY>0 AND BUGY+DY<25 THEN Y=BUGY+DY :: CALL GCHAR(Y,X,OBJ) 2920 IF OBJ=96 OR OBJ=104 THEN BLOCK(J)=1 :: GOTO 2960 ! SKIP OBSTRUCTIONS 2930 IF OBJ=120 THEN PREDATOR=1 :: PX=X :: PY=Y :: SUBEXIT ! LOOK FOR PREDATORS 2940 IF OBJ=128 AND FOOD=0 THEN FOOD=1 :: FX=X :: FY=Y :: GOTO 2960! LOOK FOR FOOD 2950 IF OBJ=112 AND FRIEND=0 THEN FRIEND=1 :: BLOCK(J)=1 :: FRX=X :: FRY=Y ! LOOK FOR OTHER BUGS 2960 NEXT J 2970 NEXT I 2980 SUBEND 2990 SUB FLEE(BUGX,BUGY,PX,PY,S) 3000 X=BUGX :: Y=BUGY :: FOR I=1 TO S 3010 CALL HCHAR(Y,X,32) 3020 CALL DIR(CX,CY) 3030 NX=X+CX :: NY=Y+CY :: CALL GCHAR(NY,NX,OBJ) 3040 IF NX<2 OR NX>31 OR NY<2 OR NY>23 OR OBJ=104 THEN GOTO 3080 ! AVOID ALL OBSTRUCTIONS 3050 PDIST=INT(SQR((PX-X)^2+(PY-Y)^2)) :: NDIST=INT(SQR((PX-NX)^2+(PY-NY)^2)) 3060 IF NDIST<=PDIST THEN GOTO 3020 ! AVOID DIRECTIONS TOWARDS PREDATOR 3070 X=NX :: Y=NY 3080 CALL HCHAR(Y,X,112) 3090 NEXT I 3100 BUGX=X :: BUGY=Y 3110 SUBEND 3120 SUB TARGET_MOVE(ORGX,ORGY,TX,TY,OBJ,DX,DY) 3130 DX=0 :: DY=0 3140 IF TX-ORGX>0 THEN DX=1 :: GOTO 3160 3150 IF TX-ORGX<0 THEN DX=-1 3160 IF TY-ORGY>0 THEN DY=1 :: GOTO 3180 3170 IF TY-ORGY<0 THEN DY=-1 3180 X=ORGX+DX :: Y=ORGY+DY :: CALL GCHAR(Y,X,OBJ) 3190 IF OBJ=104 THEN DX=0 :: DY=0 3200 SUBEND 3210 SUB MOVE(ORGX,ORGY,OBJ) 3220 CALL DIR(DX,DY) :: X=ORGX+DX :: Y=ORGY+DY :: CALL GCHAR(Y,X,OBJ) 3230 IF X<2 OR X>31 OR Y<2 OR Y>23 OR OBJ=104 THEN 3220 3240 ORGX=X :: ORGY=Y 3250 SUBEND 3260 SUB SEARCH(PREDX,PREDY,PREY,PRX,PRY) 3270 FOR I=1 TO 6 :: BLOCK(I)=0 :: NEXT I 3280 PREY=0 :: RESTORE 2660 3290 FOR I=1 TO 5 3300 FOR J=1 TO 6 3310 READ DX,DY 3320 IF BLOCK(J)=1 THEN 3390 3330 IF PREDX+DX>0 AND PREDX+DX<33 THEN X=PREDX+DX ELSE 3390 3340 IF PREDY+DY>0 AND PREDY+DY<25 THEN Y=PREDY+DY ELSE 3390 3350 CALL GCHAR(Y,X,OBJ) 3360 IF OBJ=96 OR OBJ=104 THEN BLOCK(J)=1 :: GOTO 3390 ! SKIP OBSTRUCTIONS 3370 IF OBJ=112 THEN PREY=1 :: PRX=X :: PRY=Y :: SUBEXIT ! LOOK FOR PREY 3380 IF OBJ=120 THEN BLOCK(J)=1 3390 NEXT J 3400 NEXT I 3410 SUBEND 3420 SUB REPRODUCE(X,Y,NX,NY) 3430 NX=0 :: NY=0 3440 FOR I=X-1 TO X+1 3450 FOR J=Y-1 TO Y+1 3460 CALL GCHAR(J,I,OBJ) :: IF OBJ=32 OR OBJ=128 THEN NX=I :: NY=J :: SUBEXIT 3470 NEXT J 3480 NEXT I 3490 IF NX=0 AND NY=0 THEN NX=X :: NY=Y 3500 SUBEND[/code] Clearly, we are well beyond the contents of the original book which inspired all of this, and yet there are still many possibilities out there. Any further work on this simulation line however will need likely be done in another language such as TurboForth or Pascal for speed. GAMMA.ZIP Edited April 5, 2013 by Vorticon 2 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 4, 2013 Share Posted April 4, 2013 What a cool concept!!! This is some in-depth stuff here, man! I'm going to run the sim a few times and I'll post some results when I can. ***Side note*** I also HIGHLY recommend TidBit to anyone working on in-depth logic or complex menu features... The last thing TI-related I did before I moved to Tennessee was build a fairly awesome menu engine for the Beryl project... None of which I could have done very well without it. I, too, would love to have TidBit in a standalone format... Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 4, 2013 Share Posted April 4, 2013 Vorticon, how would you define "stable".... So far the counter is at 15 and the sim seems to be at a relative stability... I have lost one predator, but the bugs and food seem to be rejuvenating fairly steadily. Another thing... I did not write down what my settings were I started with. If I start a new sim, will my old settings be the starting point for my new sim? Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 4, 2013 Share Posted April 4, 2013 Fascinating!!! At cycle 40, I was out of predators... The bug population dwindled down to two at about cycle 60, and now they have reproduced to 16 and are multiplying and thriving... cycle 90 now, and looking good for the bugs. =) Quote Link to comment Share on other sites More sharing options...
Opry99er Posted April 4, 2013 Share Posted April 4, 2013 Okay, this is very cool. I have some pictures of the first simulation I ran. At cycle 95, the graph showed some interesting stuff... very different from the initial graph early on... It seems the bugs specialized pretty quickly in an attempt to adapt. Here they are, thriving, having outlasted the predators... Plenty of food, plenty of bugs. Looks pretty good. Here at cycle 107, however, the food supply is running short and the bugs start to die off little by little... They still maintain for quite a while, but it's evident that the growing population doesn't have the food supply regeneration frequency they need to maintain the population. Alas, after the population dwindled down to just a few bugs, the replenished food supply did not come in time. The colony died. **I'm very intrigued by this simulation... **SETTINGS** 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted April 4, 2013 Author Share Posted April 4, 2013 Vorticon, how would you define "stable".... So far the counter is at 15 and the sim seems to be at a relative stability... I have lost one predator, but the bugs and food seem to be rejuvenating fairly steadily. Another thing... I did not write down what my settings were I started with. If I start a new sim, will my old settings be the starting point for my new sim? A stable ecosystem is when the bugs and predators do not completely die off over an extended period of time (500 cycles?). Now you could also just have bugs with no predators that can perpetuate their existence in perfect balance with the food supply, and in that situation the farthest I ever got was 256 cycles. With predators around, the latter die off usually within 25-30 cycles, and I have yet to find the correct ratio of bugs to predators, along with the various energy gains/losses settings. It certainly gives us a glimpse of why it is so easy for humans to disrupt current ecosystems which are likely very delicately balanced... Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted April 4, 2013 Author Share Posted April 4, 2013 Your simulation run clearly shows that speed and vigilance were determined to be crucial factors in survival. However, I am a little surprised that social interaction was so low as to be practically irrelevant. In real life, prey tend to huddle in herds for protection, which does not seem to be the case under these specific circumstances... I'm going to replicate your settings and see if I can re-create that finding Quote Link to comment Share on other sites More sharing options...
matthew180 Posted April 4, 2013 Share Posted April 4, 2013 Below is the formatted source code (which for some mysterious reason has lost all of its indentations...): You forgot to use "code" tags inside the "spoiler" tags: [ spoiler ] [ code ] your code goes here [ /code ] [ /spoiler ] Remove the spaces of course. Also note that after an update to the forum some time ago, any group of four spaces are converted to tabs, even in code tags, so it will blow the formatting anyway, as well as any kind of ASCII formatting you try to do. Matt, I was wondering if you would consider creating a stand-alone version of TidBit so we are not dependent on having an internet connection all the time. http://atariage.com/forums/topic/172765-basic-xb-translator/ It is on page 14 of the forum, but I'll bump it so you can find it easier. The first post in the thread has the .zip. It is written in PHP so you can run it on pretty much any OS you want to use. Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted October 4, 2016 Author Share Posted October 4, 2016 A couple of days ago I was looking for a programming project to run on my recently completed PDP-8 replica computer, and I remembered a chapter on neural nets in the book titled The Tinkertoy Computer and Other Machinations from the pages of Scientific American by A.K. Dewdney. A fascinating book by the way with lots of super interesting computational projects and you can find the PDF copy here: https://archive.org/details/tinkertoycomputer00dewd So based on the text and the algorithmic outline, I programmed a neural net which is capable of converting from polar to cartesian coordinates on a purely empirical basis with just a set of interconnected "neurons". There are 3 neurons for input (2 for the polar coordinates and one as a fixed offset number), 2 output neurons for the resulting X/Y coordinates, and 20 intermediate neurons connected to each of the input and output neurons. Each connection is initially given a random weight. What the program does is get a random set of polar coordinates (radius and angle) and feed them to the input neurons. Then the output neurons result is compared to the expected X/Y coordinates from the standard sine/cosine conversions and the error is fed retrogradely to the intermediate neurons, with the weights of the connections between both the input and output sides adjusted accordingly. When this is repeated several thousand times, the net will usually converge to the correct result within 6 decimal places consistently, at least on the PDP-8, all without having any knowledge of trigonometry or any concept of coordinates! Here's the program for the TI. It required some tweaking because the PDP-8 has a number representation limit of 10-626 whereas the TI goes to only 10-99 and so I was running into overflow issues. It also runs VERY slowly, doing about 200 iterations per hour. Given that we need at least 10000 iterations to start seeing a convergence, that adds up to about 50 hrs of computing time at a minimum 1 REM POLARNET2 REM NEURAL NET FOR POLAR TO CARTESIAN COORDINATES CONVERSION5 REM INITIALIZATION7 RANDOMIZE10 DIM S1(3,20),S2(20,3)20 DIM INP(3),O(2),T(2),E(2)21 DIM M1(20),M0(20)22 DIM G(20),G1(20)25 INP(3)=100040 FOR I=1 TO 2050 FOR J=1 TO 360 S1(J,I)=0.1*RND70 NEXT J80 NEXT I90 FOR I=1 TO 2100 FOR J=1 TO 20110 S2(J,I)=0.1*RND120 NEXT J130 NEXT I140 REM FORWARD COORDINATE CONVERSION150 INP(1)=RND170 INP(2)=RND*2*3.14159265359180 FOR I=1 TO 20190 M1(I)=0200 FOR J=1 TO 3210 M1(I)=0.1*(M1(I)+S1(J,I)*INP(J))215 IF ABS(M1(I))>220 THEN 150220 M0(I)=0.1*(1/(1-EXP(-M1(I))))225 NEXT J226 NEXT I227 T(1)=INP(1)*COS(INP(2))228 T(2)=INP(1)*SIN(INP(2))230 FOR I=1 TO 2240 O(I)=0250 FOR J=1 TO 20260 O(I)=O(I)+S2(J,I)*M0(J)270 E(I)=T(I)-O(I)280 NEXT J290 NEXT I295 REM BACK PROPAGATION300 FOR I=1 TO 2310 FOR J=1 TO 20320 S2(J,I)=S2(J,I)+0.1*M0(J)*E(I)330 NEXT J340 NEXT I350 FOR I=1 TO 20360 G(I)=0370 FOR J=1 TO 2380 G(I)=G(I)+E(J)*S2(I,J)390 G1(I)=M1(I)*(1-M1(I))400 NEXT J410 NEXT I420 FOR I=1 TO 2430 FOR J=1 TO 20440 D=0.1*G1(J)*G(J)*INP(I)450 S1(I,J)=S1(I,J)+D460 NEXT J470 NEXT I475 REM DISPLAY RESULTS480 N=N+1485 PRINT486 PRINT "TRIAL #";N490 PRINT "RADIUS=";INP(1),"ANGLE=";INP(2)500 PRINT "CALCULATED X=";O(1),"CALCULATED Y=";O(2)510 PRINT "TARGET X=";T(1),"TARGET Y=";T(2)550 PRINT "TOTAL ERROR=";SQR(E(1)^2+E(2)^2)560 GOTO 150570 END Fascinating stuff... Going further, one can experiment with the number of intermediate neurons or with different types of calculations and see what happens. Trust me, read the book. Highly recommended. 3 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted October 4, 2016 Share Posted October 4, 2016 Though it is not close to the capacity of the PDP-8, the TI via TI Basic actually can go down to 10-128—the console display routine just doesn't display it properly. You can prove this by assigning a number between 10-99 and 10-128 to a variable and displaying the product of that variable and a number that will bring it back into printing range (2-digit exponent): 10 A = 1E-120 20 B = 1E21 30 PRINT A;B;A*B RUN 1.E-** 1.E+21 1.E-99 fbForth 2.0 and TurboForth 1.2 will handle it because I rewrote part of the floating point package I ported from the MDOS floating point library (with permission, of course) to include a formatted print option for 3-digit E notation. ...lee Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted October 4, 2016 Author Share Posted October 4, 2016 Though it is not close to the capacity of the PDP-8, the TI via TI Basic actually can go down to 10-128—the console display routine just doesn't display it properly. You can prove this by assigning a number between 10-99 and 10-128 to a variable and displaying the product of that variable and a number that will bring it back into printing range (2-digit exponent): 10 A = 1E-120 20 B = 1E21 30 PRINT A;B;A*B RUN 1.E-** 1.E+21 1.E-99 fbForth 2.0 and TurboForth 1.2 will handle it because I rewrote part of the floating point package I ported from the MDOS floating point library (with permission, of course) to include a formatted print option for 3-digit E notation. ...lee Ah... I was just going by the User Manual content. Good to know! Quote Link to comment Share on other sites More sharing options...
matthew180 Posted October 4, 2016 Share Posted October 4, 2016 That is really cool! I'm definitely going to have to read that book. How do you know how many neurons you need for a given task? Also, once you "teach" the network, can you then feed in other polar coordinates and get results faster? Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted October 4, 2016 Author Share Posted October 4, 2016 That is really cool! I'm definitely going to have to read that book. How do you know how many neurons you need for a given task? Also, once you "teach" the network, can you then feed in other polar coordinates and get results faster? Apparently significantly increasing the number of intermediate neurons beyond 20-30 does not necessarily enhance performance, and may actually give you a worse result... At least according to the book Maybe something to experiment with... And yes, once the network reaches a stable output level, you can just preserve the weights of all the connections and just feed it polar coordinates. One way to do it is say once the program reaches 20000 iterations, you can have it ask you for input, then have it only run the forward coordinate conversion section and not go through the back propagation section so that no changes to the connection weights are made. Even better yet, using the Missing Link bitmap extensions, at the end of 20000 iterations, I could have the network go through 360 degrees sequentially 1 degree at a time with a standard radius of 1 and have it draw the resulting pixels at the calculated x/y coordinates on the screen. Next to it go through the same procedure but using the standard sine/cosine conversion and match the network circle to the calculated one. They should pretty much match. If the network circle is distorted, then it's not quite stable yet. The problem is that it's really slow on the TI, and as a matter of fact my program has been running for nearly 28hrs now and it still has ways to go... The PDP-8 is much faster. Quote Link to comment Share on other sites More sharing options...
matthew180 Posted October 4, 2016 Share Posted October 4, 2016 I'm repeating myself, but that is really cool. And, where is a link to the PDP-8 project??? Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted October 4, 2016 Author Share Posted October 4, 2016 Here you go: http://obsolescence.wixsite.com/obsolescence/pidp-8 Below is my replica: 1 Quote Link to comment Share on other sites More sharing options...
matthew180 Posted October 5, 2016 Share Posted October 5, 2016 Wow, that is bad ass! Now I'm really jealous! Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted October 29, 2016 Author Share Posted October 29, 2016 So in a bout of insomnia, I was watching an episode of the British TV show from the 80's titled The Computer Programme, and they were showing a program on the BBC micro learning how to play Tic-Tac-Toe without knowing the rules. It seemed like the perfect game to try something like that on given that it is super simple to play, so I decided to try and create something similar for the TI 99/4A. The program is written in XB over the course of the past few hours. Basically when you start it up it will go into learning mode and play itself for the number of trials you input. Needless to say that a large number of trials will be needed in order for it to improve its play. What it does is randomly place pieces on the board and compile statistics on the likelihood that any particular move at any particular time will have a good chance of leading to a win. Once it's done with the trials, it will have in memory a list of "best moves" which it will try to use against the human player. Then you will get a chance to test its mettle in real games. The video below is just a quick demo with only 10 trials, so needless to say that it plays horrifically bad. I'm currently having it run a 500 trial run (it's slow...) and I'll see how its play improves. It may need far more than that though... * Note: Somehow I managed to append the video to some test footage of my Phoenix chess game under development. No sure how this happened... https://youtu.be/M-T47lRBqWE Here's the code. It's rough but I wrote it pretty quickly as an experiment The squares are represented as a grid of numbers 1-9 as below which you will use to input the player moves: 1 2 3 4 5 6 7 8 9 EDIT: I caught a couple of bugs with further testing. With 1000 trials, it was now able to consistently recognize where to place a marker to complete a row, column or diagonal and thus win. It's still pretty dumb otherwise I'm going to have it run for a few thousand trials overnight and see what kind of improvements I get. 10 RANDOMIZE11 CALL CLEAR12 DIM WD1(9,9),WD2(8,9),L1(9,9),L2(8,9),M1(9,9),M2(8,9)20 DISPLAY AT(1,1)BEEP:"READY TO LEARN!" :: DISPLAY AT(2,1):"PRESS ANY KEY TO START..."30 CALL KEY(0,K,S) :: IF S=0 THEN 3031 CALL CLEAR32 MODE=135 FOR I=1 TO 9 :: B$(I)="" :: NEXT I36 DISPLAY AT(1,1)BEEP:"ENTER # OF TRIALS: " :: ACCEPT AT(1,20):MT50 GOSUB 1000051 DISPLAY AT(22,1):"TRIAL #";155 GOSUB 10060 :: DISPLAY AT(24,1):""60 SIDE=180 LOC=INT(RND*(9-TURN))+190 N=0 :: P=1100 IF B$(P)="" THEN N=N+1 :: IF N=LOC AND SIDE=1 THEN B$(P)="X" :: GOSUB 10060 :: GOTO 111 ELSE IF N=LOC THEN B$(P)="O" :: GOSUB 10060 :: GOTO 111110 P=P+1 :: GOTO 100111 GOSUB 10120112 IF SIDE=1 THEN S1(TURN+1)=P ELSE S2(TURN+1)=P113 IF RESULT<>0 THEN 140120 TURN=TURN+1 :: IF TURN>8 THEN GOTO 140130 IF SIDE=1 THEN SIDE=2 ELSE SIDE=1135 GOTO 80140 IF RESULT=1 THEN DISPLAY AT(24,1)BEEP:"X WINS!" :: WX=WX+1 :: DISPLAY AT(5,15):"X WIN #: ";WX150 IF RESULT=2 THEN DISPLAY AT(24,1)BEEP:"O WINS!" :: WO=WO+1 :: DISPLAY AT(6,15):"O WIN #: ";WO151 IF RESULT=0 THEN DISPLAY AT(24,1)BEEP:"DRAW!" :: D=D+1 :: DISPLAY AT(7,15):"DRAW #: ";D152 GOSUB 10250160 TRIAL=TRIAL+1 :: IF TRIAL>MT-1 THEN 190 ELSE DISPLAY AT(22,1):"TRIAL #";TRIAL+1170 FOR I=1 TO 9 :: B$(I)="" :: NEXT I :: TURN=0175 FOR I=1 TO 9 STEP 2 :: S1(I)=0 :: NEXT I176 FOR I=2 TO 8 STEP 2 :: S2(I)=0 :: NEXT I180 GOTO 55190 DISPLAY AT(20,1)BEEP:"LEARNING COMPLETE!" :: DISPLAY AT(21,1):"PRESS ANY KEY"200 CALL KEY(0,K,S) :: IF S=0 THEN 200205 CALL CLEAR206 MODE=2210 FOR I=1 TO 9 STEP 2220 FOR J=1 TO 9230 IF L1(I,J)=0 THEN M1(I,J)=WD1(I,J)ELSE M1(I,J)=WD1(I,J)/L1(I,J)240 NEXT J250 NEXT I260 FOR I=2 TO 8 STEP 2270 FOR J=1 TO 9280 IF L2(I,J)=0 THEN M2(I,J)=WD2(I,J)ELSE M2(I,J)=WD2(I,J)/L2(I,J)290 NEXT J300 NEXT I310 DISPLAY AT(1,1)BEEP:"READY TO PLAY!" :: DISPLAY AT(2,1):"PRESS ANY KEY TO START..."320 CALL KEY(0,K,S) :: IF S=0 THEN 320330 FOR I=1 TO 9 :: B$(I)="" :: NEXT I331 SIDE=1 :: TURN=1332 DISPLAY AT(5,1)BEEP:"PLAY FIRST? (Y/N)"333 CALL KEY(0,K,S) :: IF S=0 THEN 333334 IF CHR$(K)="Y" THEN 450335 CALL CLEAR340 GOSUB 10000350 DISPLAY AT(22,1)BEEP:"MY TURN..." :: DISPLAY AT(24,1):""355 BEST=0360 IF SIDE=2 THEN 410370 FOR I=1 TO 9380 IF MAX(M1(TURN,I),BEST)>BEST AND B$(I)="" THEN BPOS=I :: BEST=M1(TURN,I) :: GOTO 390381 IF MAX(M1(TURN,I),BEST)382 IF INT(RND*10)+1<=5 AND B$(I)="" THEN BEST=M1(TURN,I) :: BPOS=I390 NEXT I400 B$(BPOS)="X" :: GOSUB 10060 :: TURN=TURN+1 :: SIDE=2401 GOSUB 10120 :: IF RESULT=0 THEN 460402 DISPLAY AT(23,1)BEEP:"I WIN!!!" :: DISPLAY AT(24,1):"PLAY AGAIN? (Y/N)"403 CALL KEY(0,K,S) :: IF S=0 THEN 403404 IF CHR$(K)="N" THEN STOP405 CALL CLEAR :: GOTO 310410 FOR I=1 TO 9420 IF MAX(M2(TURN,I),BEST)>BEST AND B$(I)="" THEN BPOS=I :: GOTO 430421 IF MAX(M2(TURN,I),BEST)422 IF INT(RND*10)+1<=5 AND B$(I)="" THEN BEST=M2(TURN,I) :: BPOS=I430 NEXT I440 B$(BPOS)="O" :: GOSUB 10060 :: TURN=TURN+1 :: SIDE=1 :: GOSUB 10120 :: GOTO 401450 CALL CLEAR :: GOSUB 10000460 IF TURN>9 THEN DISPLAY AT(23,1)BEEP:"DRAW!!!" :: DISPLAY AT(24,1)BEEP:"PLAY AGAIN? (Y/N)" :: GOTO 403465 DISPLAY AT(22,1)BEEP:"YOUR TURN..."470 DISPLAY AT(24,1)BEEP:"ENTER MOVE..."480 CALL KEY(0,K,S) :: IF S=0 THEN 480490 IF K<49 OR K>57 THEN 480500 IF B$(K-48)<>"" THEN 480510 IF SIDE=1 THEN B$(K-48)="X" ELSE B$(K-48)="O"520 GOSUB 10060 :: GOSUB 10120530 IF RESULT<>0 THEN 570540 TURN=TURN+1 :: IF TURN>9 THEN 460550 IF SIDE=1 THEN SIDE=2 ELSE SIDE=1560 GOTO 350570 DISPLAY AT(23,1)BEEP:"YOU WIN!!!" :: DISPLAY AT(24,1)BEEP:"PLAY AGAIN? (Y/N)" :: GOTO 40310000 REM DISPLAY BOARD ROUTINE10010 CALL CLEAR10020 IF MODE=2 THEN DISPLAY AT(1,1):"PLAYING MODE" ELSE DISPLAY AT(1,1):"LEARNING MODE"10030 FOR I=1 TO 11 :: DISPLAY AT(I+4,4):"* *" :: NEXT I10040 DISPLAY AT(8,1):"***********" :: DISPLAY AT(12,1):"***********"10050 RETURN10060 REM DISPLAY GAME MARKERS ROUTINE10065 X=2 :: Y=610070 FOR I=1 TO 910080 DISPLAY AT(Y,X)SIZE(1):B$(I)10090 X=X+4 :: IF X>10 THEN X=2 :: Y=Y+410100 NEXT I10110 RETURN10120 REM CHECK FOR WIN10130 OFST=010140 FOR I=1 TO 310150 IF(B$(I+OFST)=B$(I+1+OFST))AND(B$(I+1+OFST)=B$(I+2+OFST))AND(B$(I+OFST)<>"")THEN 1024010160 OFST=OFST+2 :: NEXT I10180 FOR I=1 TO 310190 IF(B$(I)=B$(I+3))AND(B$(I+3)=B$(I+6))AND(B$(I)<>"")THEN 1024010200 NEXT I10210 IF(B$(1)=B$(5))AND(B$(5)=B$(9))AND(B$(1)<>"")THEN 1024010220 IF(B$(3)=B$(5))AND(B$(5)=B$(7))AND(B$(3)<>"")THEN 1024010230 RESULT=0 :: RETURN10240 RESULT=SIDE :: RETURN10250 REM TABULATE RESULTS10260 IF SIDE=2 THEN 1042010270 IF RESULT=2 THEN 1035010280 FOR I=1 TO 9 STEP 210290 WD1(I,S1(I))=WD1(I,S1(I))+110300 NEXT I10310 FOR I=2 TO 8 STEP 210320 L2(I,S2(I))=L2(I,S2(I))+110330 NEXT I10340 RETURN10350 FOR I=1 TO 9 STEP 210360 L1(I,S1(I))=L1(I,S1(I))+110370 NEXT I10380 FOR I=2 TO 8 STEP 210390 WD2(I,S2(I))=WD2(I,S2(I))+110400 NEXT I10410 RETURN10420 IF RESULT=1 THEN 1050010430 FOR I=1 TO 9 STEP 210440 L1(I,S1(I))=L1(I,S1(I))+110450 NEXT I10460 FOR I=2 TO 8 STEP 210470 WD2(I,S2(I))=WD2(I,S2(I))+110480 NEXT I10490 RETURN10500 FOR I=1 TO 9 STEP 210510 WD1(I,S1(I))=WD1(I,S1(I))+110520 NEXT I10530 FOR I=2 TO 8 STEP 210540 L2(I,S2(I))=L2(I,S2(I))+110550 NEXT I10560 RETURN 4 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted October 30, 2016 Author Share Posted October 30, 2016 A few observations after 5000 trials (thank heavens for overdrive mode in Classic99!): - There seems to be a 50% higher chance to win for the player who starts first. This seems to be corroborated by Dr. Google. - The computer seems to consistently favor the right lower corner of the board. Odd... - It still has not discovered the importance of the center square - It still plays like shit... I'm going to try and tweak things a bit. I'm afraid it will need larger trial sizes still, and that is where it becomes really painful on the TI... Perhaps my next project should be networking several TI's for parallel processing! 2 Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted October 30, 2016 Share Posted October 30, 2016 Somebody actually did that, Vorticon. They built a TMS9900 multiprocessor board called the FEM to work on some engineering algorithms. Here's a description of the system software for it too. Here's another article on it (Wikipedia). Here's another one built with 19 TMS9995 processor boards connected to a NeXT computer. . . 2 Quote Link to comment Share on other sites More sharing options...
Morsa Posted September 26, 2022 Share Posted September 26, 2022 Hi, Vorticon, I know this is an old discusión. Is there a chance to see the videos you made from the Heiserman's book? Quote Link to comment Share on other sites More sharing options...
jgerrie Posted October 21, 2023 Share Posted October 21, 2023 On 10/30/2016 at 1:34 AM, Vorticon said: I'm going to try and tweak things a bit. I'm afraid it will need larger trial sizes still, and that is where it becomes really painful on the TI... Perhaps my next project should be networking several TI's for parallel processing! Hey Vorticon, Very neat TI program. Thanks for starting this interesting discussion of early BASIC AI programming. I've been trying to compile a list (and working examples) of such programs, including some from Heiserman's book. Type-in-Mania-AI-Programs Thought you and others here might be interested. 1 Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted October 21, 2023 Author Share Posted October 21, 2023 46 minutes ago, jgerrie said: Hey Vorticon, Very neat TI program. Thanks for starting this interesting discussion of early BASIC AI programming. I've been trying to compile a list (and working examples) of such programs, including some from Heiserman's book. Type-in-Mania-AI-Programs Thought you and others here might be interested. Very cool project! I'm definitely going to take a close look at some of these tonight Quote Link to comment Share on other sites More sharing options...
+Vorticon Posted September 29 Author Share Posted September 29 Here's an interesting program that allows the computer to heuristically learn to play the game of NIM and eventually become unbeatable. It's taken from the book "Data and File Management for the TI-99/4A" by JP Grillo et al. In brief you have 13 stones and each player takes turn at picking 1-3 stones, and the one who ends up with 1 stone left on his turn loses. It will take maybe 9 or 10 tries before the computer starts playing perfectly and becomes very snarky! Interesting process with broader applications in the field of machine learning. 10 REM filename: "G1A" 20 REM purpose: to play the game of "NIM" heuristically 30 REM author: jpg & jdr 9/82 40 REM ________________________________________________ 50 RANDOMIZE :: CALL CLEAR 60 DIM CUP(4,3),CY(13),CX(13) 70 DIM PERM(6,3)!6 permutations of 3 digits 80 ! His win or our win messages 90 DIM H1$(6),H2$(6),O1$(13),O2$(13),O3$(13) 100 ! Flash the title screen 110 DISPLAY AT(5,1):RPT$("=",28) 120 DISPLAY AT(7,5):"N I M W I T H G 1 A" 130 DISPLAY AT(9,1):RPT$("=",28) 140 ! Fill each set of 3 cups with digits 1,2,3 150 FOR I=1 TO 4 160 FOR J=1 TO 3 :: CUP(I,J)=J :: NEXT J 170 NEXT I 180 !Fill the PERM array with all permutaitions of 1,2,3 190 FOR I=1 TO 6 200 FOR J=1 TO 3 :: READ PERM(I,J) :: NEXT J 210 NEXT I 220 !Fill his win message with gracious pap 230 FOR I=1 TO 6 :: READ H1$(I),H2$(I) :: NEXT I 240 !Fill our win message with scathing scorn 250 FOR I=1 TO 13 :: READ O1$(I),O2$(I),O3$(I) :: NEXT I 260 DISPLAY AT(12,1):RPT$("-",16) :: WHO$="" 270 !Set up the player's name 280 DISPLAY AT(12,3)BEEP :"Enter your initials "; 282 CALL KEY(0,T,S) :: IF S=0 THEN 282 284 T$=CHR$(T) 290 IF T=13 THEN 320 300 WHO$=WHO$&T$ :: DISPLAY AT(12,23):WHO$ 310 IF LEN(WHO$)<3 THEN 270 320 GOSUB 5000 :: CALL CLEAR 330 DISPLAY AT(7,4):"G1A";!The conputer's name is G1A 340 DISPLAY AT(9,4):WHO$;!print the player's name 350 DISPLAY AT(8,4):WIN;!print the number of player losses 360 DISPLAY AT(10,4):LOSE;!print the number of player wins 370 GOSUB 1000!blank out previous chips and position the chips 400 DISPLAY AT(7,2):" "; 410 DISPLAY AT(9,2):"->"; 420 !Get the player's response 430 DISPLAY AT(15,5)BEEP :"Take 1 to 3 chips" 432 CALL KEY(0,T,S) 434 IF S=0 THEN 432 435 IF(T<48)OR(T>57)THEN 430 436 T$=CHR$(T) 440 TAKE=VAL(T$) :: DISPLAY AT(15,25):"/";T$ :: GOSUB 5000 450 IF TAKE<1 OR TAKE>3 OR TAKE>CHIPS THEN GOSUB 6000 :: DISPLAY AT(15,5):"improper move"; :: GOSUB 5000 :: GOTO 420 460 GOSUB 2000 470 IF CHIPS=0 THEN GOSUB 4000 :: GOTO 330 480 !G1A's move 490 GOSUB 6000 :: DISPLAY AT(9,2):" "; 500 DISPLAY AT(7,2):"->"; 510 !A is the random permutation selector 520 GOSUB 5000 :: A=INT(RND*6+1) 530 FOR I=1 TO 3 550 !B is the remainder: Chips modulo 4 560 K=PERM(A,I) :: B=CHIPS-4*INT(CHIPS/4) 570 IF B=0 THEN B=4 600 IF CUP(B,K)>0 THEN 610 605 NEXT I :: CUP(BCUP,KCARD)=-1 :: HOW=1 :: GOSUB 3000 :: GOTO 330 610 TAKE=CUP(B,K) 630 IF TAKE>=CHIPS THEN CUP(B,K)=-1 :: HOW=2 :: GOSUB 3000 :: GOTO 330 640 !Note proper grammatical display. 'chip' or 'chips' 650 DISPLAY AT(15,5):"G1A takes";TAKE;SEG$("chips",1,4+INT(TAKE/2)) 660 GOSUB 5000 :: GOSUB 5000 670 BCUP=B :: KCARD=K 680 GOSUB 2000 :: GOTO 400 1000 !****** Subroutine to set up chips. ****** 1005 CHIPS=13 :: DISPLAY AT(7,14):"chips"; :: DISPLAY AT(8,15):"left" 1010 N=0 1020 FOR I=-1 TO 1 1030 L=ABS(I) :: M=18+L 1040 FOR J=1 TO 5-L 1050 N=N+1 :: CX(N)=M+J+J :: CY(N)=I+I+8 1060 DISPLAY AT(CY(N),CX(N)):CHR$(30) 1070 NEXT J 1080 NEXT I 1100 DISPLAY AT(9,15)SIZE(3):CHIPS; :: R=INT(RND*13+1) :: P=1+INT(RND*11+1) 1110 RETURN 2000 !****** Subroutine to remove 1 to 3 chips ****** 2010 FOR I=1 TO TAKE 2020 R=R+P 2030 IF R>13 THEN R=R-13 2040 DISPLAY AT(CY(R),CX(R))SIZE(1):" "; 2050 NEXT I 2060 CHIPS=CHIPS-TAKE :: DISPLAY AT(9,15):CHIPS 2070 RETURN 3000 !****** Subroutine to print loss message ****** 3010 GOSUB 5000 :: GOSUB 5000 :: CALL CLEAR 3020 A=INR(RND*6+1) :: DISPLAY AT(7,1):RPT$("~",28) 3030 IF HOW=2 THEN DISPLAY AT(9,1):"G1A ";H2$(A);" acknowledges defeat"; 3040 IF HOW=1 THEN DISPLAY AT(9,5):"G1A ";H1$(A);" concedes the game" 3050 DISPLAY AT(12,1):RPT$("~",28) :: LOSE=LOSE+1 3060 GOSUB 5000 :: GOSUB 5000 :: GOSUB 5000 :: CALL CLEAR 3070 RETURN 4000 !******Subroutine to print win by G1A ****** 4010 CALL CLEAR :: A=INT(RND*13+1) :: B=INT(RND*13+1) :: C=INT(RND*13+1) 4020 DISPLAY AT(7,1):RPT$("#",28) 4030 DISPLAY AT(9,1):"THE ";O1$(A);" G1A HAS ";O2$(B);" THE ";O3$(C);" ";WHO$ 4040 DISPLAY AT(12,1):RPT$("#",28) 4050 WIN=WIN+1 4060 GOSUB 5000 :: GOSUB 5000 :: GOSUB 5000 :: CALL CLEAR 4070 RETURN 5000 !****** Subroutine to mark time ****** 5010 FOR I=1 TO 500 :: NEXT I 5020 RETURN 6000 !****** Subroutine for blanking out ****** 6010 DISPLAY AT(15,1):RPT$(" ",28) 6020 RETURN 7000 !****** D a t a S t a t e m e n t s ****** 7030 DATA 1,2,3,1,3,2,2,1,3,2,3,1,3,1,2,3,2,1 7040 !Data for G1A losses 7050 DATA cordially,respectfully,graciously,politely 7060 DATA affably,humbly,cogenially,modestly 7070 DATA meekly,amicably,courteously,agreeably 7080 !Data for G1A wins 7090 DATA AWESOME,ANNIHILATED,PROSAIC,DREDED 7100 DATA EXTERMINATED,VAPID,PUISSANT,OBLITERATED,SLUGGISH 7110 DATA EMINENT,DEMOLISHED,DOLTISH,EXALTED,CONQUERED,OBTUSE 7120 DATA INTREPID,VANQUISHED,INFERIOR,SPLENDID,DEVASTATED 7130 DATA INSIPID,SAPIENT,EXTIRPATED,HAWKISH,ERUDITE,SUBJUGATED 7140 DATA BUNGLING,FORMIDABLE,CRUSHED,FLACCID,REDOUBTABLE 7150 DATA FLATTENED,INEPT,BRILLIANT,STOMPED,IGNORANT 7160 DATA MAGNIFICENT,DESTROYED,STUPID 9999 END 5 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.