"Loading MAZE..." $PRINT CRLF ; ; MAZE - created 10/24/02, last modified 11/29/02 (code 11/7/02) ; In this game you wander around an 8 by 8 maze of randomly ; connected rooms, finding food to stay alive and battling ; monsters which also wander around the maze. If your strength ; falls to 0 the game is over. Protection packages are scattered ; around the maze to reduce the effect of the monsters. Food and ; protection packages are removed when consumed, and are randomly ; replenished as you move about. Transporters take you to a ; randomly selected room when used. Full connectivity is not ; guaranteed so be careful using transporters, you might find ; yourself trapped. If you're inclined a map function shows ; (roughly) the layout of the maze and where the stuff is. ; OCTAL DEFINE MAZE DEC END ;dummy, will be extended ; "Defining RND" $PRINT CRLF DEFINE RND ;make RND a bit more random.. RND 473 GET XOR ;473=timer low when TBG driver running END "Declaring Variables" $PRINT CRLF VARIABLE FOOD_WORTH ;how much strength gain per take VARIABLE PROTECTION_WORTH ;how much protection gain per take VARIABLE REP_RATE ;replenish rate - rnd AND mask VARIABLE RESS_RATE ;monster resurrection rate - rnd AND mask VARIABLE P_HIT ;player's hit = p.strength / (n + rnd(0-7)) ; nominal 3, more is weaker player VARIABLE M_HIT ;monster's hit = m.strength / (5 + protection / n) ; nominal 16, more is stronger monster VARIABLE C_ERROR ;connection error ;65-word arrays, location 0 not used, 1-64 correspond to room# VARIABLE NPASS 101 ;north south east west passages arrays VARIABLE SPASS 101 ;contain 0 for no passage, or room number VARIABLE EPASS 101 VARIABLE WPASS 101 VARIABLE ROOM ;current room# VARIABLE STRENGTH ;current strenth ; effect you have on opponent VARIABLE PROTECTION ;current protection ; reduces effect opponent has on you ; contents for each room... 65 locations, 1-64 corr.to room# VARIABLE CONTENTS 101 ;location 0 set to 123456 after initializing ;bit 0 - food ;bit 1 - protection ;bit 2 - magic transporter VARIABLE MOVES ;starts at 0, increments each move VARIABLE SCORE ;1 point for each threat "overcome" ;8 "monsters" VARIABLE MONSTER_ROOM 7 ;room each is located in VARIABLE MONSTER_STRENGTH 7 ;strength of each monster "Defining XY_TO_ROOM" $PRINT CRLF DEFINE XY_TO_ROOM ; X 1 to 8, Y 1 to 8, return room number ;room number = (X-1) + (Y-1)*8 + 1 ; if error return 0 #0 S>Z ;error flag on Z stack ;check X and Y OVER OVER CASE < 1 Z>S INC S>Z ;if Y<1 inc Z > 10 Z>S INC S>Z ;if Y>8 inc Z ENDCASE CASE < 1 Z>S INC S>Z ;if X<1 inc Z > 10 Z>S INC S>Z ;if X>8 inc Z ENDCASE Z>S IFZ ;if valid then... SWAP DEC SWAP DEC ;decrement X and Y 10 MUL ADD INC ;multiply Y by 8 and add to X, inc results ELSE ;if not valid then... DROP DROP #0 ;drop X,Y and return 0 ENDIF END "Defining CONNECT_ROOM" $PRINT CRLF DEFINE CONNECT_ROOM ; X,Y source X,Y dest on stack, remove only X,Y dest XY_TO_ROOM ;convert X/Y dest into actual room# DUP IFZ ;if error then DROP ;do nothing except C_ERROR #1 PUT ;raise the error flag ELSE ;else room# on stack, connect it... S>Z ;save destination room number to Z stack OVER OVER XY_TO_ROOM ;determine source room number S>Y ;save source room number to Y stack ;determine "to" direction... subtract source from dest Z>S DUP S>Z Y>S DUP S>Y SUB CASE = 1 ;Go East Y>S DUP S>Y EPASS ADD Z>S DUP S>Z PUT ;set EPASS(srcroom)=destroom Z>S DUP S>Z WPASS ADD Y>S DUP S>Y PUT ;set WPASS(destroom)=srcroom = -1 ;Go West Y>S DUP S>Y WPASS ADD Z>S DUP S>Z PUT Z>S DUP S>Z EPASS ADD Y>S DUP S>Y PUT = 10 ;Go South Y>S DUP S>Y SPASS ADD Z>S DUP S>Z PUT Z>S DUP S>Z NPASS ADD Y>S DUP S>Y PUT = -10 ;Go North Y>S DUP S>Y NPASS ADD Z>S DUP S>Z PUT Z>S DUP S>Z SPASS ADD Y>S DUP S>Y PUT ENDCASE Y>S DROP Z>S DROP ENDIF END "Defining RANDOMIZE_ROOMS" $PRINT CRLF DEFINE RANDOMIZE_ROOMS ;zero arrays #0 100 +DO INDEX DUP NPASS ADD #0 PUT DUP SPASS ADD #0 PUT DUP EPASS ADD #0 PUT DUP WPASS ADD #0 PUT CONTENTS ADD #0 PUT +LOOP ;randomize rnd using tmrlo #0 473 GET +DO RND DROP +LOOP ;randomly connect the rooms #1 10 +DO INDEX ;for X = 1 to 8 #1 10 +DO INDEX ;for Y = 1 to 8 ;X,Y on the stack, try 4 directions.. RND 77 AND 32 SUB IF<0 OVER OVER DEC CONNECT_ROOM ENDIF RND 77 AND 32 SUB IF<0 OVER OVER INC CONNECT_ROOM ENDIF RND 77 AND 32 SUB IF<0 OVER DEC OVER CONNECT_ROOM ENDIF RND 77 AND 32 SUB IF<0 OVER INC OVER CONNECT_ROOM ENDIF ;distribute random contents OVER OVER XY_TO_ROOM CONTENTS ADD ;push array address #0 ;start empty RND 7 AND IFZ 1 OR ENDIF ;1-8 chance of food RND 17 AND IFZ 2 OR ENDIF ;1-16 chance of protection RND 17 AND IFZ 4 OR ENDIF ;1-16 chance of transporter PUT ;write CONTENTS entry DROP +LOOP ;next Y DROP +LOOP ;next X ;look for unconnected rooms and connect them... #1 10 +DO INDEX #1 10 +DO INDEX OVER OVER XY_TO_ROOM #0 ;number of connections OVER NPASS ADD GET IFNZ INC ENDIF OVER SPASS ADD GET IFNZ INC ENDIF OVER EPASS ADD GET IFNZ INC ENDIF OVER WPASS ADD GET IFNZ INC ENDIF SWAP DROP ;room number IFZ ;if no connections... DO ;loop until connection is made C_ERROR #0 PUT ;clear error flag RND 3 AND CASE ;rnd 0-3 = 0 OVER OVER DEC CONNECT_ROOM = 1 OVER OVER INC CONNECT_ROOM = 2 OVER DEC OVER CONNECT_ROOM = 3 OVER INC OVER CONNECT_ROOM ENDCASE C_ERROR GET WHILE ;try again if error ENDIF DROP +LOOP DROP +LOOP ;ensure room 1 connects to something... #1 #1 #1 2 CONNECT_ROOM 2 #1 CONNECT_ROOM DROP DROP ;always put a transporter in room 1... CONTENTS INC DUP GET 4 OR PUT END "Defining ROOM_TO_XY" $PRINT CRLF DEFINE ROOM_TO_XY DEC ;true dimension.. bits 0-2 X 0-7 3-5 Y 0-7 DUP 7 AND INC S>Z ;push X 1-8 to Z 70 AND ASR ASR ASR INC ;push Y 1-8 dropping original Z>S SWAP ;return X and Y (1st pop will be Y) END "Defining GO_IF_VALID" $PRINT CRLF DEFINE GO_IF_VALID ADD GET DUP IFZ CRLF "Can't go that way" $PRINT DROP ELSE ROOM SWAP PUT Z>S INC S>Z ;command performed ENDIF END "Defining M_RADAR" $PRINT CRLF DEFINE M_RADAR ;room # and xpass var address on stack, both removed ;if direction possible, checks for monster in that room ADD GET DUP IFZ DROP ELSE #0 7 +DO INDEX MONSTER_ROOM ADD GET OVER SUB IFZ CRLF "Monster " $PRINT INDEX 101 ADD PCHR " is nearby" $PRINT ENDIF +LOOP DROP ENDIF END "Defining TAKE_HITS" $PRINT CRLF DEFINE TAKE_HITS ;look for monsters in the same room... ROOM GET ;push current room #0 7 +DO INDEX MONSTER_ROOM ADD GET OVER SUB IFZ CRLF "Monster " $PRINT INDEX 101 ADD PCHR " is here" $PRINT ;take away strength points based on monster's strength ;and player's level of protection... ;hit = monster_strength/(5 + protection/m_hit) INDEX MONSTER_STRENGTH ADD GET ;push monster strength PROTECTION GET M_HIT GET DIV 5 ADD ;push 5 + protection/m_hit DIV ;divide strength by above DUP IFZ DROP CRLF "It has no effect" $PRINT ELSE CRLF "It drains your strength by " $PRINT DUP PNUM STRENGTH GET SWAP SUB STRENGTH SWAP PUT STRENGTH GET IF<0 STRENGTH #0 PUT ENDIF ;no lower than 0 ENDIF ENDIF +LOOP DROP END "Defining MOVE_MONSTER" $PRINT CRLF DEFINE MOVE_MONSTER ;monster room address on Z ;room number and address of room array on stack ADD GET DUP IFZ DROP Z>S DROP ELSE Z>S SWAP PUT ENDIF END "Defining LOOK_AROUND" $PRINT CRLF DEFINE LOOK_AROUND ROOM GET ROOM_TO_XY CRLF "You are at X: " $PRINT SWAP PNUM "Y: " $PRINT PNUM CRLF "Passages lead: " $PRINT ROOM GET NPASS ADD GET IFNZ "North " $PRINT ENDIF ROOM GET SPASS ADD GET IFNZ "South " $PRINT ENDIF ROOM GET EPASS ADD GET IFNZ "East " $PRINT ENDIF ROOM GET WPASS ADD GET IFNZ "West" $PRINT ENDIF CRLF "Strength: " $PRINT STRENGTH GET PNUM " Protection: " $PRINT PROTECTION GET PNUM ROOM GET CONTENTS ADD GET DUP 1 AND IFNZ CRLF "There is food here" $PRINT ENDIF DUP 2 AND IFNZ CRLF "There is protection here" $PRINT ENDIF 4 AND IFNZ CRLF "There is a transporter here" $PRINT ENDIF ENDIF END "Defining INIT_MAZE" $PRINT CRLF DEFINE INIT_MAZE RESS_RATE 77 PUT ;1 in 64 chance per move of dead monsters coming back CRLF "*** MAZE *** 11/07/02" $PRINT CRLF "Select 1)Easy 2)Medium 3)Difficult: " $PRINT DO CHRIN CASE = 61 #1 ;1 FOOD_WORTH 50 PUT PROTECTION_WORTH 36 PUT P_HIT 3 PUT M_HIT 20 PUT REP_RATE 7 PUT = 62 #1 ;2 FOOD_WORTH 36 PUT PROTECTION_WORTH 24 PUT P_HIT 4 PUT M_HIT 24 PUT REP_RATE 7 PUT = 63 #1 ;3 FOOD_WORTH 36 PUT PROTECTION_WORTH 24 PUT P_HIT 5 PUT M_HIT 30 PUT REP_RATE 17 PUT DEFAULT #0 10 PCHR 40 PCHR 10 PCHR ENDCASE UNTIL CRLF "Creating World..." $PRINT RANDOMIZE_ROOMS ;set up maze ROOM #1 PUT ;start in room 1 SCORE #0 PUT ;zero score MOVES #0 PUT ;zero move counter STRENGTH 62 PUT ;set strength to 50 PROTECTION #0 PUT ;set protection to 0 #0 7 +DO INDEX DUP MONSTER_ROOM ADD RND 77 AND INC PUT ;random room 1-64 MONSTER_STRENGTH ADD RND 77 AND 45 ADD PUT ;random strength 37-100 +LOOP CONTENTS 123456 PUT ;set 0 array index to specific value END "Defining MAZE_HELP" $PRINT CRLF DEFINE MAZE_HELP CRLF "N S E W move north, south, east or west" $PRINT CRLF "F P T take food or protection, use transport" $PRINT CRLF "L B Q M R ? look, battle, quit, map, reset, help" $PRINT END "Defining MAZE_BODY" $PRINT CRLF DEFINE MAZE_BODY RADIX DECIMAL ;push current radix, use decimal CONTENTS GET 123456 SUB ;push <>0 if not initialized STRENGTH GET #1 SUB IF<0 #1 ELSE #0 ENDIF ;push 1 if dead OR IFNZ ;if not initialized or dead then initialize... INIT_MAZE ENDIF CRLF "Welcome to the maze. Commands..." $PRINT MAZE_HELP DO ;loop while not playing again DO #0 ;loop until DROP 1 STRENGTH GET #1 SUB IF<0 ;terminate if dead... DROP #1 CRLF "You are dead." $PRINT ENDIF DUP IFZ ;if still alive... LOOK_AROUND TAKE_HITS STRENGTH GET IFZ DROP #1 ;drop room and terminate ELSE ;if still alive look for nearby monsters... ROOM GET DUP NPASS M_RADAR DUP SPASS M_RADAR DUP EPASS M_RADAR WPASS M_RADAR DO ;until valid command #0 S>Z ;no command CRLF "Command: " $PRINT CHRIN "" $APPEND ;get command, convert to 1-char string "N" $EQUAL IFNZ ROOM GET NPASS GO_IF_VALID ENDIF "S" $EQUAL IFNZ ROOM GET SPASS GO_IF_VALID ENDIF "E" $EQUAL IFNZ ROOM GET EPASS GO_IF_VALID ENDIF "W" $EQUAL IFNZ ROOM GET WPASS GO_IF_VALID ENDIF "M" $EQUAL IFNZ #1 10 +DO CRLF INDEX #1 10 +DO INDEX OVER OVER SWAP XY_TO_ROOM ;push room#, leave XY alone #0 ;bits 3-0 will be wesn bits OVER NPASS ADD GET IFNZ 1 OR ENDIF OVER SPASS ADD GET IFNZ 2 OR ENDIF OVER EPASS ADD GET IFNZ 4 OR ENDIF OVER WPASS ADD GET IFNZ 10 OR ENDIF CASE ;on wesn bits = 0 " " ;nc = 1 " ' " ;n = 2 " . " ;s = 3 " : " ;ns = 4 " -" ;e = 5 " `-" ;ne = 6 " .-" ;se = 7 " :-" ;nse = 10 "- " ;w = 11 "-' " ;nw = 12 "-. " ;sw = 13 "-: " ;nsw = 14 "---" ;ew = 15 "-'-" ;new = 16 "-.-" ;sew = 17 "-:-" ;nsew ENDCASE ; room# on stack, room string on X ; replace middle char with T for transport, P for protection, ; F for food, M for monster or * for player DUP CONTENTS ADD GET ;get room contents DUP 4 AND IFNZ ;if transporter #1 124 $PUT ENDIF ;replace middle w/ T DUP 2 AND IFNZ ;if protection #1 120 $PUT ENDIF ;replace middle w/ P #1 AND IFNZ ;drop contents, if food #1 106 $PUT ENDIF ;replace middle w/ F #0 7 +DO INDEX MONSTER_ROOM ADD GET OVER SUB IFZ ;if monster in the room #1 115 $PUT ENDIF ;replace middle w/ M +LOOP ROOM GET SUB IFZ ;drop room number, if=player #1 52 $PUT ENDIF ;replace middle w/ * $PRINT DROP +LOOP DROP +LOOP ENDIF "?" $EQUAL IFNZ MAZE_HELP ENDIF "F" $EQUAL IFNZ ;food... CONTENTS ROOM GET ADD GET #1 AND IFNZ ;if food.. CRLF "Food taken" $PRINT STRENGTH DUP GET FOOD_WORTH GET ADD PUT ;add food_worth to strength CONTENTS ROOM GET ADD DUP GET 177776 AND PUT ;remove food 144 STRENGTH GET SUB IF<0 STRENGTH 144 PUT ENDIF ;max 100 ENDIF ENDIF "P" $EQUAL IFNZ ;protection... CONTENTS ROOM GET ADD GET 2 AND IFNZ ;if protection.. CRLF "Protection taken" $PRINT PROTECTION DUP GET PROTECTION_WORTH GET ADD PUT ;add p.worth to protection CONTENTS ROOM GET ADD DUP GET 177775 AND PUT ;remove protection 144 PROTECTION GET SUB IF<0 PROTECTION 144 PUT ENDIF ;max 100 ENDIF ENDIF "T" $EQUAL IFNZ ;transport... CONTENTS ROOM GET ADD GET 4 AND IFNZ ;if transporter.. CRLF "Wheee...." $PRINT ROOM RND 77 AND INC PUT ;random room Z>S INC S>Z ;moved ENDIF ENDIF "B" $EQUAL IFNZ ;battle... #0 7 +DO MONSTER_ROOM INDEX ADD GET ;push monster's room # ROOM GET SUB IFZ ;if equal to player's room then... ;calculate hit = strength / (p_hit + rnd(0 to 7) STRENGTH GET RND 7 AND P_HIT GET ADD DIV CRLF "You hit monster " $PRINT INDEX 101 ADD PCHR " by " $PRINT DUP PNUM MONSTER_STRENGTH INDEX ADD ;push m.strength adr DUP S>Z ;copy to Z GET SWAP SUB ;get strength, subtract hit from it DUP IF<0 DROP #0 ENDIF ;stop at 0 DUP ;results for testing Z>S SWAP PUT ;write back to strength IFZ ;if monster was defeated... INDEX MONSTER_ROOM ADD #0 PUT ;zero his room# "and defeat it" $PRINT SCORE DUP GET INC PUT ;increase score by 1 ENDIF ENDIF +LOOP TAKE_HITS ;the monsters fight back STRENGTH GET IFZ CRLF "You have been defeated" $PRINT DROP #1 Z>S INC S>Z ENDIF ENDIF "L" $EQUAL IFNZ LOOK_AROUND ENDIF "Q" $EQUAL IFNZ DROP #1 Z>S INC S>Z ;terminate, flag moved STRENGTH DUP GET INC PUT ;put back strength and PROTECTION DUP GET INC PUT ;protection that MOVES DUP GET DEC PUT ;moving takes away ENDIF "R" $EQUAL IFNZ CRLF "Reset game.. Are You Sure? " $PRINT CHRIN 131 SUB IFZ ;if Y is pressed... INIT_MAZE LOOK_AROUND TAKE_HITS ENDIF ENDIF $DROP ;drop the command string Z>S ;get refresh-location flag DUP IFNZ ;if moved... MOVES DUP GET INC PUT ;increment moves STRENGTH DUP GET DEC PUT ;decrement strength STRENGTH GET IF<0 STRENGTH #0 PUT ENDIF ;down to 0 PROTECTION DUP GET DEC PUT ;decrement protection PROTECTION GET IF<0 PROTECTION #0 PUT ENDIF ;down to 0 ;1 in rep_rate chance of distributing food somewhere... RND REP_RATE GET AND IFZ RND 77 AND INC CONTENTS ADD ;calculate location DUP GET #1 OR PUT ;set bit 0 ENDIF ;1 in rep_rate chance of distributing protection somewhere... RND REP_RATE GET AND IFZ RND 77 AND INC CONTENTS ADD ;calculate location DUP GET 2 OR PUT ;set bit 1 ENDIF ;move monsters... #0 7 +DO INDEX MONSTER_ROOM ADD DUP S>Z GET DUP IFZ DROP Z>S DROP ELSE ;room on stack, room address on Z RND 3 AND CASE = 0 DUP NPASS MOVE_MONSTER = 1 DUP SPASS MOVE_MONSTER = 2 DUP EPASS MOVE_MONSTER = 3 DUP WPASS MOVE_MONSTER ENDCASE DROP ;room number ENDIF ;spontaniously regenerate... INDEX MONSTER_ROOM ADD GET IFZ RND RESS_RATE GET AND IFZ INDEX DUP MONSTER_ROOM ADD RND 77 AND INC PUT ;random room MONSTER_STRENGTH ADD RND 77 AND 45 ADD PUT ;random strength 37-100 ENDIF ENDIF +LOOP ENDIF ;moved UNTIL ;traveler moves ENDIF ;still alive after monsters ENDIF ;still alive UNTIL CRLF "You defeated " $PRINT SCORE GET DUP PNUM DEC IFZ "monster" ELSE "monsters" ENDIF $PRINT " in " $PRINT MOVES GET PNUM "moves." $PRINT STRENGTH GET IFZ ;if dead... CRLF "Play Again? " $PRINT CHRIN 131 SUB IFZ ;if Y is pressed... INIT_MAZE #1 ;loop when it gets to until ELSE #0 ENDIF ;if any other key ELSE #0 ENDIF ;or not dead yet just quit WHILE ;playing again CASE ;on original radix = 12 DECIMAL = 10 OCTAL DEFAULT CRLF "Oddness detected!" $PRINT OCTAL ENDCASE END ; ; extend MAZE definition around MAZE_BODY... "MAZE_BODY" $DEFADR DUP DEC GET "MAZE" $DEFADR DEC SWAP PUT "MAZE" $DEFADR INC SWAP PUT ; "Done" $PRINT CONSOLE