\ Super Star Trek \ Translated from the book BASIC COMPUTER GAMES, edited by \ David Ahl, 1978, New York: Workman Publishing. \ Original program by Mike Mayfield, May 16, 1978 \ Here is the original BASIC header: \ SUPER STARTREK - MAY 16, 1978 - REQUIRES 24K MEMORY \ *** **** STAR TREK **** **** \ *** SIMULATION OF A MISSION OF THE STARSHIP ENTERPRISE, \ *** AS SEEN ON THE STAR TREK TV SHOW. \ *** ORIGINAL PROGRAM BY MIKE MAYFIELD, MODIFIED VERSION \ *** PUBLISHED IN DEC'S "101 BASIC GAMES", BY DAVE AHL. \ *** MODIFICATIONS TO THE LATTER (PLUS DEBUGGING) BY BOB \ *** LEEDOM - APRIL & DECEMBER 1974, \ *** WITH A LITTLE HELP FROM HIS FRIENDS . . . \ *** COMMENTS, EPITHETS, AND SUGGESTIONS SOLICITED -- \ *** SEND TO: R. C. LEEDOM \ *** WESTINGHOUSE DEFENSE & ELECTRONICS SYSTEMS CNTR. \ *** BOX 746, M.S. 338 \ *** BALTIMORE, MD 21203 \ *** \ *** CONVERTED TO MICROSOFT 8 K BASIC 3/16/78 BY JOHN BORDERS \ *** LINE NUMBERS FROM VERSION STREK7 OF 1/12/75 PRESERVED AS \ *** MUCH AS POSSIBLE WHILE USING MULTIPLE STATEMENTS PER LINE \ Revisions: \ 2006-10-14 ported to ANS-Forth by Krishna Myneni, \ Creative Consulting for Research and Education \ (krishnamyneni@bellsouth.net) \ 2006-10-15 new random number generator (thanks to Marcel \ Hendrix), additional logic for ShieldControl and \ DamageControl when docked at starbase. km \ 2006-10-22 fixed logic in KlingonsShoot, CheckEnergy, \ and cleaned up CommandInput using suggestions \ from Ed Beroset and Albert van der Horst. \ Reworked logic for DamageControl and for \ FirePhotonTorpedo to destroy the Enterprise \ if we blow up the starbase to which we are docked. \ Also modified #in to prevent problems with handling \ non-numeric input. \ 2008-09-15 ported to 4tH by Hans Bezemer (hansoft@bigfoot.com) \ 2008-09-19 Bug fixes: \ Increased insufficient size of array n{, used in \ word LongRangeSensors, by 1; bug found by Hans Bezemer. \ Fixed incorrect use of variable "d1" as an fvariable \ in word RepairDamage; bug found by Doug Hoffman. \ 2008-09-26 Several layout issues. "No Klingons found" doesn't \ terminate the computer anymore. \ 2008-09-28 Fixed a bug in QuadrantName, found by Doug Hoffman. \ Quadrant name didn't match quadrant coordinates. \ ---------------------------------------------------------------- \ Notes (by Krishna Myneni): \ 0) This program, and its various ports, appear to be in the public \ domain. If you modify and/or redistribute this Forth version, \ please include the above header. \ 1) The history of this program may be found at: \ http://www3.sympatico.ca/maury/games/space/star_trek.html \ http://www.cactus.org/%7Enystrom/startrek.html \ http://www.dunnington.u-net.com/public/startrek/ \ 2) I first encountered this game in the late 70's in David Ahl's \ book, and I ported it then to my Commodore Vic-20 computer. \ Later, in the 80's, I ported the program to QuickBasic v4.5. \ In the 90's, I began an on and off port to Forth, but it wasn't \ until the fall of 2006 that I found some time to finish the port \ of this classic program to kForth. With trivial mods, documented \ below, this program should run on any ANS-Forth system. The \ floating point wordset is required, but does (should) not have \ a dependency on whether an integrated fp/data stack or separate \ fp stack is used. \ 3) This port is based on my earlier QuickBasic version, as well \ as on Chris Nystrom's well-structured C version of the game, \ The latter is easily found on the Web. \ 4) I've pretty much refrained from making any significant changes to \ the program. I also refrained from changing variable names to \ preserve some of the code's history --- there is some nostalgia \ for those of us who started programming in the 70's using \ unstructured BASIC. This version retains the look and feel \ of the original game, and is, I believe, functionally equivalent \ to the 1978 version. \ Some changes I *have* made are: \ a) I included the instructions as part of a very simple help \ system within the program. \ b) I couldn't follow the logic of the original distance and \ direction calculator, so I rewrote it (DirectionCalc). \ c) The quadrant and sector coordinate pairs are (row,col) \ pairs. For motion of the ship, or torpedo trajectories, \ intermediate variables with x,y naming are provided. \ The mapping of row with "x" and of col with "y", as was done \ in the original program, is confusing to me. Therefore, \ I inverted the use of the x,y variables to correspond \ to their ordinary meaning in a Cartesian coordinate system: \ the "x" variables now represent a horizontal coordinate, \ and the "y" variables represent a vertical coordinate. \ Ship motion and torpedo motion calculations have been \ reworked. All of these changes are internal to the \ program and do not affect the output of sector and \ quadrant coordinate pairs. \ d) I found and fixed some bugs in the original code and/or \ the C version. These are documented in the next note. \ 5) The following bugs are fixed in this Forth version: \ 5.1: In line 4480 in the original BASIC version, and in \ phaser_control() in the C version, the phaser hit \ energy is not calculated with the correct distance: \ FND(0) should be FND(I). The formula also appears to \ allow the hit energy to be greater than the energy \ fired from the ship. These problems are fixed in this \ version, in FirePhasers. \ 5.2: In line 6060 of the BASIC version from Ahl, the incorrect \ distance is used, FND(1) should be FND(I), to compute hit \ energy. This is fixed in KlingonsShoot. \ 5.3: In the C version, in klingons_shoot(), when a Klingon \ ship's energy is low, and it shoots at the Enterprise, \ its energy can diminish to zero due to its integer \ representation. The program logic then no longer treats \ the ship correctly. It remains in the game, but does not \ appear on the SRS display. The problem has been fixed \ in KlingonsShoot, by not allowing the Klingon ship energy \ to go entirely to zero until it is destroyed. \ 5.4: If we are docked at a starbase and we move the ship, \ the docked flag appears to remain set. This has been \ fixed in CourseControl. \ 6) This program is a great way to teach conversion between polar \ coordinates and rectangular coordinates. Locations are given as \ quadrant and sector coordinates (rectangular), while the user \ must input a polar angle (scaled) when firing photon torpedos \ or moving through the galaxy. The user also has to take into \ account the radial distance from the ship when firing phasers, \ or in selecting a warp factor to reach a destination quadrant. include lib/search.4th include lib/null.4th include lib/enter.4th include lib/ulcase.4th include lib/range.4th include lib/userpad.4th include lib/ansfacil.4th include lib/ansfloat.4th include lib/ansfpio.4th include lib/fequals.4th include lib/fatan2.4th include lib/fsinfcos.4th hide e \ "e" is used as a variable in this program fclear \ initialize floating point library 7 set-precision \ seems appropriate \ --- Several FP utility words --- aka f>s ftrunc>s : ftrunc f>d d>f ; : fround>s fround f>s ; : rad>deg 180 s>f f* pi f/ ; : deg>rad pi f* 180 s>f f/ ; : page cr cr ; \ : page ( -- ) 27 emit ." [2J" 27 emit ." [0;0H" ; \ --- UTILITIES (for strings, input, arrays, random numbers, doc) --- \ --- Small strings package --- : $space ( ulen a$ u$ -- | set string variable to be of length ulen, filled with spaces) drop 2dup blank swap chars + 0 swap c! ; : $copy ( a u a$ u$ -- | copy string to string variable) drop place ; : $cat ( a1 u1 a2 u2 -- a3 u3 ) 2swap >pad drop dup >r +place r> count ; \ --- Generic string words --- ( args don't have to be string variables ) : $mid ( a u pos len -- a2 u2 | return a substring) >r 1- nip + r> ; \ origin is 1 for "pos" : $left ( a u u2 -- a2 u2 | return left substring) nip ; : $right ( a u n -- a2 u2 | return right substring) dup >r - 0 max + r> ; : u>$ ( u -- a u2 | return string representing u) s>d <# #s #> ; \ --- String and numeric input --- : $input ( -- a u ) refill drop tib count ; : #in ( -- n | positive integer or -1 ) enter -1 max ; : f#in ( -- f ) begin $input >float until ; \ --- Arrays and matrices --- 1 cells constant INTEGER \ --- Random number generation --- [hex] 7f800000 constant ROL9MASK [decimal] FLOAT array RAND_SCALE -1 0 d>f RAND_SCALE F! :this RAND_SCALE does> f@ ; variable seed : rol9 ( u1 -- u2 | rotate u1 left by 9 bits ) dup ROL9MASK and 23 rshift swap 9 lshift or ; : random2 ( -- u ) seed @ 107465 * 234567 + rol9 dup seed ! ; : ran0 ( -- f ) random2 s>f RAND_SCALE f/ s" 0.5" s>float f+ ; time&date 2drop 2drop + seed ! : % ( n -- f ) s>f 100 s>f f/ ; : chance ( f -- flag | return a true flag f*100 percent of the time) ran0 fswap f<= ; : rnd() ( n -- f | return random number between 0e0 and [n]e0 ) s>f ran0 f* ; \ --- Simple help system --- create help_buf ," 1. When you see COMMAND? printed, enter one of the legal commands" ," (NAV, SRS, LRS, PHA, TOR, SHE, DAM, COM, XXX, or HEL)." ," " ," 2. If you should type in an illegal command, you'll get a short list of" ," the legal commands printed out." ," " ," 3. Some commands require you to enter data (for example, the 'NAV' command" ," comes back with 'COURSE (1-9) ?'.) If you type in illegal data (like" ," negative numbers), that command will be aborted." ," " ," The galaxy is divided into an 8 X 8 quadrant grid, and each quadrant" ," is further divided into an 8 x 8 sector grid." ," " ," You will be assigned a starting point somewhere in the galaxy to begin" ," a tour of duty as commander of the starship Enterprise; your mission:" ," to seek out and destroy the fleet of Klingon warships which are menacing" ," the United Federation of Planets." ," " ," You have the following commands available to you as Captain of the Starship" ," Enterprise:" ," " ," " ," " ," \NAV\ Command = Warp Engine Control --" ," " ," Course is in a circular numerical vector 4 3 2" ," arrangement as shown. Integer and real . . ." ," values may be used. (Thus course 1.5 is ..." ," half-way between 1 and 2. 5 ---*--- 1" ," ..." ," Values may approach 9.0, which itself is . . ." ," equivalent to 1.0. 6 7 8" ," " ," One warp factor is the size of one quadrant. COURSE" ," Therefore, to get from quadrant 6,5 to 5,5" ," you would use course 3, warp factor 1." ," " ," \SRS\ Command = Short Range Sensor Scan" ," " ," Shows you a scan of your present quadrant." ," " ," Symbology on your sensor screen is as follows:" ," <*> = Your starship's position" ," +K+ = Klingon battlecruiser" ," >!< = Federation starbase (Refuel/Repair/Re-Arm here!)" ," * = Star" ," A condensed 'Status Report' will also be presented." ," " ," \LRS\ Command = Long Range Sensor Scan" ," " ," Shows conditions in space for one quadrant on each side of the Enterprise" ," (which is in the middle of the scan). The scan is coded in the form \###\" ," where the units digit is the number of stars, the tens digit is the number" ," of starbases, and the hundreds digit is the number of Klingons." ," " ," Example - 207 = 2 Klingons, No Starbases, & 7 stars." ," " ," \PHA\ Command = Phaser Control." ," " ," Allows you to destroy the Klingon Battle Cruisers by zapping them with" ," suitably large units of energy to deplete their shield power. (Remember," ," Klingons have phasers, too!)" ," " ," \TOR\ Command = Photon Torpedo Control" ," " ," Torpedo course is the same as used in warp engine control. If you hit" ," the Klingon vessel, he is destroyed and cannot fire back at you. If you" ," miss, you are subject to the phaser fire of all other Klingons in the" ," quadrant." ," " ," The Library-Computer (\COM\ command) has an option to compute torpedo" ," trajectory for you (option 2)." ," " ," \SHE\ Command = Shield Control" ," " ," Defines the number of energy units to be assigned to the shields. Energy" ," is taken from total ship's energy. Note that the status display total" ," energy includes shield energy." ," " ," \DAM\ Command = Damage Control report" ," " ," Gives the state of repair of all devices. Where a negative 'State of Repair'" ," shows that the device is temporarily damaged." ," " ," \COM\ Command = Library-Computer" ," " ," The Library-Computer contains six options:" ," " ," Option 0 = Cumulative Galactic Record" ," This option shows computer memory of the results of all previous" ," short and long range sensor scans." ," " ," Option 1 = Status Report" ," This option shows the number of Klingons, stardates, and starbases" ," remaining in the game." ," " ," Option 2 = Photon Torpedo Data" ," Gives directions and distance from Enterprise to all Klingons" ," in your quadrant." ," " ," Option 3 = Starbase Nav Data" ," This option gives direction and distance to any starbase in your" ," quadrant." ," " ," Option 4 = Direction/Distance Calculator" ," This option allows you to enter coordinates for direction/distance" ," calculations." ," " ," Option 5 = Galactic /Region Name/ Map" ," This option prints the names of the sixteen major galactic regions" ," referred to in the game." ," " ," Option < 0 = Exit the library computer." NULL , :this help_buf does> over 1- cells + @c dup NULL = dup if nip else swap count type cr then ; : help ( -- ) 0 begin 1+ dup 24 mod 0= if ." [More (y/n)?] " refill drop tib c@ 95 and [char] N = if drop exit then then help_buf until drop ; \ --- GAME STARTS HERE ------------------------------------------- 9 9 INTEGER [*] [*] array g[] \ the galaxy :this g[] does> rot 9 * rot + cells + ; 9 9 INTEGER [*] [*] array z[] \ cumulative record of galaxy :this z[] does> rot 9 * rot + cells + ; 4 4 INTEGER [*] [*] array k[] \ Klingon data :this k[] does> rot 4 * rot + cells + ; 9 FLOAT [*] array d[] \ damage array d[] :this d[] does> swap FLOAT * + ; \ calculate row offset variable b3 \ number of starbases in quadrant variable b4 \ starbase coordinate in sector variable b5 \ " " variable b9 \ number of starbases variable d0 \ docked flag variable d1 \ damage flag variable e \ current energy variable e0 \ starting energy variable h \ phaser hit energy variable h8 variable k3 \ number of Klingons in quadrant variable k7 \ number of Klingons at start variable k9 \ number of Klingons remaining variable n \ number of sectors to travel variable p \ number of photon torpedos remaining variable p0 \ photon torpedo capacity variable q1 \ quadrant coordinat of Enterprise variable q2 \ " " variable r1 variable r2 variable s \ current shield value variable s1 \ current sector coordinate of Enterprise variable s2 \ " " variable s3 \ number of stars in quadrant variable s9 \ Klingon power variable t0 \ starting stardate variable t9 \ end time FLOAT array c1 FLOAT array t \ current stardate FLOAT array w1 \ warp factor FLOAT array x FLOAT array y 9 string X$ :this X$ count ; 65 string O1$ :this O1$ count ; 65 string C$ :this C$ count ; \ condition string 257 string Q$ :this Q$ count ; \ display of quadrant \ String constants s" * " sconstant STAR$ s" <*>" sconstant ENTERPRISE$ s" +K+" sconstant KLINGON$ s" >!<" sconstant STARBASE$ s" " sconstant EMPTY$ s" NAVSRSLRSPHATORSHEDAMCOMXXXHEL" sconstant COMMANDS$ : fnr() ( n1 -- n2 | return a random integer between n1 and n1*8) rnd() s" 7.98" s>float f* s" 1.01" s>float f+ ftrunc>s ; : RandomLocation ( -- s1|q1 s2|q2 | return a random sector or quadrant location) 1 fnr() 1 fnr() ; : Location>Index ( s1 s2 -- u | return display string index for given location) 1- 3 * swap 1- 24 * + 1+ ; \ convert angle in degrees to direction [1,9) : Angle>Dir ( fangle -- fdir ) fdup f0< IF 360 s>f f+ THEN 45 s>f f/ 1 s>f f+ ; \ convert direction [1,9) to angle in degrees : Dir>Angle ( fdir -- fangle ) 1 s>f f- 45 s>f f* ; \ Distance and direction between two pairs of sector coordinates: \ z1,z2 are the sector coords of the first point. \ z3,z4 are " " second point. : Distance ( z1 z2 z3 z4 -- fdistance ) rot - dup * >r - dup * r> + s>f fsqrt ; \ Direction is a real number in the interval [1,9), with \ 1 corresponding to 0 degrees from horizontal and proceeding \ counter-clockwise. The direction is from the first point \ to the second point. : Direction ( z1 z2 z3 z4 -- fdirection ) rot 2>r - 2r> - \ -- (z1-z3) (z4-z2) >r s>f r> s>f fatan2 rad>deg Angle>Dir ; : DirectionCalc ( z1 z2 z3 z4 -- ) 2over 2over Direction cr ." DIRECTION = " f. 2 spaces Distance ." DISTANCE = " f. ; : KlingonDistance ( u -- f | distance between ship and u^th Klingon in quadrant) >r s1 @ s2 @ r@ 1 k[] @ r> 2 k[] @ Distance ; 0 constant END_NO_WIN 1 constant END_WON_GAME 2 constant END_DESTROYED 3 constant END_STRANDED false value GameEnded? false value PlayAgain? : EndOfGame ( n -- ) true to GameEnded? false to PlayAgain? END_WON_GAME OVER = IF DROP cr ." CONGRATULATIONS, CAPTAIN! THE LAST KLINGON BATTLE CRUISER" cr ." MENACING THE FEDERATION HAS BEEN DESTROYED." cr cr ." YOUR EFFICIENCY RATING IS " k7 @ s>f t f@ t0 @ s>f f- f/ fdup f* 1000 s>f f* ftrunc>s . ELSE END_DESTROYED OVER = IF DROP cr ." THE ENTERPRISE HAS BEEN DESTROYED. THE FEDERATION WILL BE CONQUERED." ELSE END_STRANDED OVER = IF DROP cr ." ** FATAL ERROR ** YOU HAVE JUST STRANDED YOUR SHIP IN" cr ." SPACE!" cr ." YOU HAVE INSUFFICIENT MANEUVERING ENERGY, AND SHIELD" cr ." CONTROL IS PRESENTLY INCAPABLE OF CROSS-CIRCUITING" cr ." TO ENGINE ROOM!!" cr ELSE END_NO_WIN OVER = IF DROP ELSE DROP THEN THEN THEN THEN k9 @ IF cr ." IT IS STARDATE " t f@ f. cr ." THERE WERE " k9 ? ." KLINGON BATTLE CRUISERS LEFT AT" cr ." THE END OF YOUR MISSION." THEN b9 @ IF cr cr cr ." THE FEDERATION IS IN NEED OF A NEW STARSHIP COMMANDER" cr ." FOR A SIMILAR MISSION -- IF THERE IS A VOLUNTEER," cr ." LET HIM STEP FORWARD AND ENTER 'AYE' " $input s>upper s" AYE" compare dup ABORT" Game over" 0= to PlayAgain? THEN ; : Initialize ( -- ) 20 rnd() 20 s>f f+ ftrunc 100 s>f f* t f! t f@ ftrunc>s t0 ! 10 rnd() ftrunc>s 25 + t9 ! false to GameEnded? \ Initialize Enterprise's Position and State RandomLocation q1 ! q2 ! \ quadrant RandomLocation s1 ! s2 ! \ sector false d0 ! 3000 dup e ! e0 ! 10 dup p ! p0 ! 0 s ! 9 0 DO 0 s>f I d[] f! LOOP \ Set up what exists in galaxy \ k3 = Number of Klingons in quadrant \ b3 = Number of Starbases in quadrant \ s3 = Number of Stars in quadrant 0 b9 ! 0 k9 ! 200 s9 ! 9 1 DO 9 1 DO 0 J I z[] ! 100 rnd() ftrunc>s r1 ! r1 @ 98 > IF 3 ELSE r1 @ 95 > IF 2 ELSE r1 @ 80 > IF 1 ELSE 0 THEN THEN THEN dup k3 ! k9 +! 4 % chance IF 1 ELSE 0 THEN dup b3 ! b9 +! k3 @ 100 * b3 @ 10 * + 1 fnr() + J I g[] ! LOOP LOOP k9 @ t9 @ > IF k9 @ 1+ t9 ! THEN b9 @ 0= IF q1 @ q2 @ g[] @ 200 < IF q1 @ q2 @ g[] @ 100 + q1 @ q2 @ g[] ! 1 k9 +! THEN 1 b9 ! q1 @ q2 @ g[] @ 10 + q1 @ q2 @ g[] ! RandomLocation q1 ! q2 ! THEN k9 @ k7 ! page ." YOUR ORDERS ARE AS FOLLOWS:" cr cr cr ." DESTROY THE " k9 ? ." KLINGON WARSHIPS WHICH HAVE INVADED" cr ." THE GALAXY BEFORE THEY CAN ATTACK FEDERATION HEADQUARTERS" cr ." ON STARDATE " t0 @ t9 @ + . cr cr ." THIS GIVES YOU " t9 ? ." DAYS." b9 @ 1 > IF s" S" s" ARE" ELSE pad 0 s" IS " THEN cr cr ." THERE " type BL emit b9 ? ." STARBASE" type ." IN THE GALAXY FOR" cr ." RESUPPLYING YOUR SHIP." cr cr ." PRESS ENTER WHEN READY TO ACCEPT COMMAND." refill drop page ; : QuadrantName ( q1 q2 flag -- a u | flag=true to get region name only) >r 2dup 4 <= IF 1 over = if drop s" ANTARES" else 2 over = if drop s" RIGEL" else 3 over = if drop s" PROCYON" else 4 over = if drop s" VEGA" else 5 over = if drop s" CANOPUS" else 6 over = if drop s" ALTAIR" else 7 over = if drop s" SAGITTARIUS" else 8 over = if drop s" POLLUX" else s" UNKNOWN" rot DROP THEN THEN THEN THEN THEN THEN THEN THEN ELSE 1 over = if drop s" SIRIUS" else 2 over = if drop s" DENEB" else 3 over = if drop s" CAPELLA" else 4 over = if drop s" BETELGUESE" else 5 over = if drop s" ALDEBARAN" else 6 over = if drop s" REGULUS" else 7 over = if drop s" ARCTURUS" else 8 over = if drop s" SPICA" else s" UNKNOWN" rot DROP THEN THEN THEN THEN THEN THEN THEN THEN THEN \ -- q1 q2 a u r> 0= IF 2>r nip dup 4 > if 4 - then 1 over = if drop s" I" else 2 over = if drop s" II" else 3 over = if drop s" III" else 4 over = if drop s" IV" else pad 0 rot DROP THEN THEN THEN THEN 2r> 2swap $cat ELSE 2swap 2drop THEN ; \ Print cumulative galaxy record or galaxy name map \ depending on flag h8 : PrintGalaxy ( -- ) cr ." 1 2 3 4 5 6 7 8" s" _____ _____ _____ _____ _____ _____ _____ _____" O1$ $copy cr O1$ type cr 9 1 DO I . h8 @ 0= IF I 1 true QuadrantName 11 over 2/ - spaces type I 5 true QuadrantName 24 over 2/ - spaces type ELSE 9 1 DO space J I z[] @ 0= IF ." ***" ELSE J I z[] @ 1000 + u>$ 3 $right type THEN 3 spaces LOOP THEN cr O1$ type cr LOOP cr ; : IsAt? ( s1 s2 a u -- flag | string comparison in quadrant array) 2>r Location>Index Q$ rot 3 $mid 2r> compare 0= ; : IsEmpty? ( s1 s2 -- flag | is sector location empty?) EMPTY$ IsAt? ; : EmptyLocation ( -- s1 s2 | Find random place in quadrant which is empty) BEGIN RandomLocation 2dup IsEmpty? 0= WHILE 2drop REPEAT ; variable s8 : PlaceAt ( s1 s2 a u -- | Insert in string array for quadrant) swap >r >r Location>Index s8 ! r@ 3 <> ABORT" ERROR: Incorrect Length" s8 @ 1 = IF r> r> swap Q$ 189 $right ELSE s8 @ 190 = IF Q$ 189 $left r> r> swap ELSE Q$ s8 @ 1- $left r> r> swap $cat Q$ 190 s8 @ - $right THEN THEN $cat Q$ $copy ; FLOAT array d4 : InNewQuadrant ( -- | here any time new quadrant entered) \ Clear number of Klingons, starbases, stars, in quadrant 0 k3 ! 0 b3 ! 0 s3 ! 192 Q$ $space \ clear the quadrant display ran0 s" 0.5" s>float f* d4 f! q1 @ q2 @ g[] @ q1 @ q2 @ z[] ! q1 @ 1 9 within q2 @ 1 9 within and IF q1 @ q2 @ false QuadrantName t f@ t0 @ s>f f= IF cr ." YOUR MISSION BEGINS WITH YOUR STARSHIP LOCATED" cr ." IN THE GALACTIC QUADRANT, '" type ." '." ELSE cr ." NOW ENTERING " type ." QUADRANT . . ." THEN q1 @ q2 @ g[] @ s>f s" 0.01" s>float f* ftrunc>s k3 ! q1 @ q2 @ g[] @ s>f s" 0.1" s>float f* ftrunc>s k3 @ 10 * - b3 ! q1 @ q2 @ g[] @ k3 @ 100 * - b3 @ 10 * - s3 ! k3 @ IF cr ." COMBAT AREA CONDITION RED" s @ 200 <= IF cr ." SHIELDS DANGEROUSLY LOW" THEN THEN 4 0 DO 4 0 DO 0 J I k[] ! LOOP LOOP THEN \ Position Enterprise in quadrant, then place Klingons, Starbases, \ and Stars elsewhere. s1 @ s2 @ ENTERPRISE$ PlaceAt k3 @ 1+ 1 ?DO EmptyLocation 2dup KLINGON$ PlaceAt I 2 k[] ! I 1 k[] ! s9 @ s>f I rnd() s" 0.5" s>float f+ f* fround>s I 3 k[] ! LOOP b3 @ IF EmptyLocation 2dup STARBASE$ PlaceAt b5 ! b4 ! THEN s3 @ 0 ?DO EmptyLocation STAR$ PlaceAt LOOP ; : DeviceName ( n -- a u | return name associated with device number) 1 OVER = IF DROP s" WARP ENGINES" ELSE 2 OVER = IF DROP s" SHORT RANGE SENSORS" ELSE 3 OVER = IF DROP s" LONG RANGE SENSORS" ELSE 4 OVER = IF DROP s" PHASER CONTROL" ELSE 5 OVER = IF DROP s" PHOTON TUBES" ELSE 6 OVER = IF DROP s" DAMAGE CONTROL" ELSE 7 OVER = IF DROP s" SHIELD CONTROL" ELSE 8 OVER = IF DROP s" LIBRARY COMPUTER" ELSE s" UNKNOWN DEVICE" rot DROP THEN THEN THEN THEN THEN THEN THEN THEN ; : KlingonsShoot ( -- ) k3 @ 0 <= IF EXIT THEN d0 @ IF cr ." STARBASE SHIELDS PROTECT THE ENTERPRISE" cr EXIT THEN 4 1 DO I 3 k[] @ 0> IF I 3 k[] @ s>f I KlingonDistance f/ ran0 2 s>f f+ f* ftrunc>s h ! h @ negate s +! I 3 k[] @ s>f 3 s>f ran0 f+ f/ ftrunc>s 1 max \ add this to prevent Klingon ship from becoming ghost -- km I 3 k[] ! cr h ? ." UNIT HIT ON ENTERPRISE FROM SECTOR " I 1 k[] ? ." ," I 2 k[] ? s @ 0 <= IF END_DESTROYED EndOfGame UNLOOP EXIT THEN cr ." " H @ 20 >= IF 60 % chance h @ s>f s @ s>f f/ s" 0.02" s>float f> and IF 1 fnr() r1 ! r1 @ d[] f@ h @ s>f s @ s>f f/ f- ran0 s" 0.5" s>float f* f- r1 @ d[] f! cr ." DAMAGE CONTROL REPORTS, '" r1 @ DeviceName type ." DAMAGED BY THE HIT'" THEN THEN THEN LOOP cr ; : NoEnemyShips ( -- ) cr ." SCIENCE OFFICER SPOCK REPORTS, 'SENSORS SHOW NO ENEMY SHIPS" cr ." IN THIS QUADRANT'" cr ; : NoStarbases ( -- ) cr ." MR. SPOCK REPORTS, 'SENSORS SHOW NO STARBASES IN THIS " cr ." QUADRANT.'" cr ; : TacticalDisplay ( -- ) cr ." =============================" cr 9 1 DO Q$ I 1- 24 * 1+ 24 $mid type I 1 OVER = IF DROP ." STARDATE " t f@ f. ELSE 2 OVER = IF DROP ." CONDITION " C$ type ELSE 3 OVER = IF DROP ." QUADRANT " q1 ? ." ," q2 ? ELSE 4 OVER = IF DROP ." SECTOR " s1 ? ." ," s2 ? ELSE 5 OVER = IF DROP ." PHOTON TORPEDOES " p ? ELSE 6 OVER = IF DROP ." TOTAL ENERGY " e @ s @ + . ELSE 7 OVER = IF DROP ." SHIELDS " s ? ELSE 8 OVER = IF DROP ." KLINGONS REMAINING " k9 ? ELSE DROP THEN THEN THEN THEN THEN THEN THEN THEN cr LOOP ." =============================" ; : NearStarbase? ( -- flag | scan adjacent sectors for starbase) false s1 @ 2 + s1 @ 1- DO s2 @ 2 + s2 @ 1- DO J 1 9 within I 1 9 within and IF J I STARBASE$ IsAt? or THEN dup IF LEAVE THEN LOOP dup IF LEAVE THEN LOOP ; : DockAtStarbase ( -- ) cr ." SHIELDS DROPPED FOR DOCKING" 0 s ! true d0 ! s" DOCKED" C$ $copy e0 @ e ! p0 @ p ! ; : ShortRangeScan ( -- | Short range sensor scan ) NearStarbase? IF DockAtStarbase THEN d0 @ 0= IF k3 @ 0> IF s" *RED*" ELSE e @ e0 @ 10 / < IF s" YELLOW" ELSE s" GREEN" THEN THEN C$ $copy THEN 2 d[] f@ f0< IF cr ." *** SHORT RANGE SENSORS ARE OUT ***" ELSE TacticalDisplay THEN ; 4 INTEGER [*] array n[] :this n[] does> swap INTEGER * + ; : LongRangeSensor ( -- ) 3 d[] f@ f0< IF cr ." LONG RANGE SENSORS ARE INOPERABLE" ELSE cr ." LONG RANGE SCAN FOR QUADRANT " q1 ? ." ," q2 ? cr ." ------------" cr q1 @ 2 + q1 @ 1- DO -1 1 n[] ! -2 2 n[] ! -3 3 n[] ! q2 @ 2 + q2 @ 1- DO J 1 9 within I 1 9 within and IF J I g[] @ I q2 @ - 2 + n[] ! J I g[] @ J I z[] ! THEN LOOP 4 1 DO I n[] @ 0< IF ." *** " ELSE I n[] @ 1000 + u>$ 3 $right type bl emit THEN LOOP cr LOOP ." ------------" cr THEN ; variable h1 : FirePhasers ( -- ) 4 d[] f@ f0< IF cr ." PHASERS INOPERATIVE" EXIT THEN k3 @ 0 <= IF NoEnemyShips EXIT THEN 8 d[] f@ f0< IF cr ." COMPUTER FAILURE HAMPERS ACCURACY" THEN cr ." PHASERS LOCKED ON TARGET" BEGIN cr ." ENERGY AVAILABLE = " E ? ." UNITS" cr ." NUMBER OF UNITS TO FIRE: " #in X ! e @ X @ - 0 >= UNTIL X @ 0> IF X @ negate e +! 7 d[] f@ f0< IF X @ s>f ran0 f* fround>s X ! THEN X @ k3 @ / h1 ! \ distribute phaser energy among klingons present 4 1 DO I 3 k[] @ 0> IF h1 @ s>f I KlingonDistance f/ \ attenuate hit based on distance ( ran0 2e f+ f*) ftrunc>s h ! h @ I 3 k[] @ 3 * 20 / <= IF cr ." SENSORS SHOW NO DAMAGE TO ENEMY AT " I 1 k[] ? ." ," I 2 k[] ? ELSE h @ negate I 3 k[] +! cr h ? ." UNIT HIT ON KLINGON AT SECTOR " I 1 k[] ? ." ," I 2 k[] ? I 3 k[] @ 0 <= IF cr ." *** KLINGON DESTROYED ***" -1 k3 +! -1 k9 +! I 1 k[] @ I 2 k[] @ EMPTY$ PlaceAt 0 I 3 k[] ! q1 @ q2 @ g[] @ 100 - q1 @ q2 @ g[] ! q1 @ q2 @ g[] @ q1 @ q2 @ z[] ! k9 @ 0 <= IF END_WON_GAME EndOfGame EXIT THEN ELSE cr ." (SENSORS SHOW " I 3 k[] ? ." UNITS REMAINING)" THEN THEN THEN LOOP KlingonsShoot THEN ; \ Photon Torpedo code FLOAT array x1 FLOAT array y1 variable x3 variable y3 : FireTorpedo ( -- ) p @ 0 <= IF cr ." ALL PHOTON TORPEDOES EXPENDED" EXIT THEN 5 d[] f@ f0< IF cr ." PHOTON TUBES NOT OPERATIONAL" EXIT THEN cr ." PHOTON TORPEDO COURSE (1-9): " f#in c1 f! c1 f@ 9 s>f f= IF 1 s>f c1 f! THEN c1 f@ ftrunc>s 1 9 within 0= IF cr ." ENSIGN CHEKOV REPORTS, 'INCORRECT COURSE DATA, SIR!'" EXIT THEN -2 e +! -1 p +! c1 f@ Dir>Angle deg>rad fsincos x1 f! fnegate y1 f! s1 @ s>f y f! s2 @ s>f x f! cr ." TORPEDO TRACK: " BEGIN x1 f@ x f@ f+ x f! y1 f@ y f@ f+ y f! x f@ fround>s x3 ! y f@ fround>s y3 ! x3 @ 1 9 within y3 @ 1 9 within and IF cr ." " y3 ? ." , " x3 ? ELSE cr ." TORPEDO MISSED" KlingonsShoot EXIT THEN y3 @ x3 @ IsEmpty? 0= UNTIL y3 @ x3 @ STAR$ IsAt? IF cr ." STAR AT " y3 ? ." ," x3 ? ." ABSORBED TORPEDO ENERGY." KlingonsShoot EXIT THEN y3 @ x3 @ STARBASE$ IsAt? IF cr ." *** STARBASE DESTROYED ***" y3 @ s1 @ - abs 2 < x3 @ s2 @ - abs 2 < and d0 @ and IF END_DESTROYED EndOfGame EXIT THEN -1 b3 +! -1 b9 +! b9 @ 0 <= IF cr ." THAT DOES IT CAPTAIN!! YOU ARE HEREBY RELIEVED OF" cr ." COMMAND AND SENTENCED TO 99 STARDATES AT HARD LABOR" cr ." ON CYGNUS 12!!" END_NO_WIN EndOfGame EXIT THEN cr ." STARFLEET COMMAND REVIEWING YOUR RECORD TO CONSIDER" cr ." COURT MARTIAL!" false d0 ! THEN y3 @ x3 @ KLINGON$ IsAt? IF cr ." *** KLINGON DESTROYED ***" -1 k3 +! -1 k9 +! k9 @ 0 <= IF END_WON_GAME EndOfGame EXIT THEN 4 1 DO I 1 k[] @ I 2 k[] @ y3 @ x3 @ d= IF 0 I 3 k[] ! THEN LOOP THEN y3 @ x3 @ EMPTY$ PlaceAt k3 @ 100 * b3 @ 10 * + s3 @ + q1 @ q2 @ g[] ! q1 @ q2 @ g[] @ q1 @ q2 @ z[] ! k3 @ IF KlingonsShoot THEN ; : ShieldControl ( -- ) d0 @ IF cr ." STARBASE SHIELDS PROTECT THE ENTERPRISE" EXIT THEN 7 d[] f@ f0< IF cr ." SHIELD CONTROL INOPERABLE" ELSE cr ." ENERGY AVAILABLE = " e @ s @ + . cr ." NUMBER OF UNITS TO SHIELDS: " #in X ! X @ 0< X @ s @ = or IF cr ." " ELSE X @ e @ s @ + > IF cr ." SHIELD CONTROL REPORTS, 'THIS IS NOT THE FEDERATION " ." TREASURY.'" cr ." " ELSE s @ X @ - e +! X @ s ! cr ." DEFLECTOR CONTROL ROOM REPORT:" cr ." 'SHIELDS NOW AT " S ? ." UNITS PER YOUR COMMAND.'" THEN THEN THEN ; \ Damage Control FLOAT array d3 : DamageControl ( -- ) 6 d[] f@ f0< IF cr ." DAMAGE CONTROL REPORT NOT AVAILABLE" ELSE cr ." DEVICE STATE OF REPAIR" cr cr 9 1 DO I DeviceName type 4 spaces 9 emit I d[] f@ f. CR LOOP THEN d0 @ IF 0 s>f d3 f! 9 1 DO I 1 I d[] f@ f0< IF d3 f@ s" 0.1" s>float f+ d3 f! THEN LOOP d3 f@ f0= IF EXIT THEN d3 f@ d4 f@ f+ d3 F! d3 f@ 1 s>f f>= IF s" 0.9" s>float d3 f! THEN cr ." TECHNICIANS STANDING BY TO EFFECT REPAIRS TO YOUR SHIP" cr ." ESTIMATED TIME TO REPAIR: " d3 f@ 100 s>f f* ftrunc>s s>d <# # # [char] . hold # #> type ." STARDATES" cr ." WILL YOU AUTHORIZE THE REPAIR ORDER (Y/N) " refill drop tib c@ 95 and [char] Y = IF 9 1 DO I d[] f@ f0< IF 0 s>f I d[] f! THEN LOOP t f@ d3 f@ f+ s" 0.1" s>float f+ t f! THEN THEN ; : LibraryComputer ( -- ) 8 d[] f@ f0< IF cr ." COMPUTER DISABLED" EXIT THEN BEGIN cr ." COMPUTER ACTIVE AND AWAITING COMMAND (0 TO 5, OR -1): " #in dup 0< IF drop cr EXIT THEN \ Cumulative Galactic Record 0 OVER = IF DROP true h8 ! cr ." COMPUTER RECORD OF GALAXY" 5 spaces ." ( YOU ARE AT QUADRANT " q1 ? ." ," q2 ? ." )" cr PrintGalaxy ELSE \ Status report 1 OVER = IF DROP cr ." STATUS REPORT:" k9 @ 1 > IF s" S" ELSE pad 0 THEN cr ." KLINGON" type ." LEFT: " k9 ? cr ." MISSION MUST BE COMPLETED IN " t0 @ t9 @ + s>f t f@ f- fround>s . ." STARDATES" b9 @ 1 < IF cr ." YOUR STUPIDITY HAS LEFT YOU ON YOUR OWN IN" cr ." THE GALAXY -- YOU HAVE NO STARBASES LEFT!" ELSE b9 @ 1 > IF s" S" ELSE pad 0 THEN cr ." THE FEDERATION IS MAINTAINING " b9 ? ." STARBASE" type ." IN THE GALAXY" THEN DamageControl ELSE \ Torpedo, base nav, D/D calculator 2 OVER = IF DROP k3 @ 0 <= IF NoEnemyShips ELSE k3 @ 1 > IF s" S" ELSE pad 0 THEN cr ." FROM ENTERPRISE TO KLINGON BATTLE CRUISER" type 4 1 DO I 3 k[] @ 0> IF s1 @ s2 @ I 1 k[] @ I 2 k[] @ DirectionCalc THEN LOOP THEN ELSE \ Starbase Nav Data 3 OVER = IF DROP b3 @ IF cr ." FROM ENTERPRISE TO STARBASE:" CR s1 @ s2 @ b4 @ b5 @ DirectionCalc ELSE NoStarbases THEN ELSE \ Direction/Distance Calculator 4 OVER = IF DROP cr ." DIRECTION/DISTANCE CALCULATOR:" cr ." YOU ARE AT QUADRANT " q1 ? ." ," q2 ? ." SECTOR " s1 ? ." ," s2 ? cr ." PLEASE ENTER INITIAL COORDINATES (S1, S2)" cr ." S1: " #in ." S2: " #in cr ." PLEASE ENTER FINAL COORDINATES (S1, S2)" cr ." S1: " #in ." S2: " #in DirectionCalc ELSE \ Galaxy region name map 5 OVER = IF DROP cr ." THE GALAXY" false h8 ! PrintGalaxy ELSE \ Invalid command cr cr ." FUNCTIONS AVAILABLE FROM LIBRARY COMPUTER:" cr ." 0 = CUMULATIVE GALACTIC RECORD" cr ." 1 = STATUS REPORT" cr ." 2 = PHOTON TORPEDO DATA" cr ." 3 = STARBASE NAV DATA" cr ." 4 = DIRECTION/DISTANCE CALCULATOR" cr ." 5 = GALAXY 'REGION NAME' MAP" cr DROP THEN THEN THEN THEN THEN THEN AGAIN ; \ Klingons move/fire on moving starship . . . FLOAT array d6 : KlingonsMove ( -- ) k3 @ 1+ 1 ?DO I 3 k[] @ IF I 1 k[] @ I 2 k[] @ EMPTY$ PlaceAt EmptyLocation 2dup KLINGON$ PlaceAt I 2 k[] ! I 1 k[] ! THEN LOOP ; : RepairDamage ( -- ) 0 d1 ! w1 f@ d6 f! w1 f@ 1 s>f f>= IF 1 s>f d6 f! THEN 9 1 DO I d[] f@ f0< IF d6 f@ I d[] f@ f+ I d[] f! I d[] f@ s" -0.1" s>float f> I d[] f@ f0< and IF s" -0.1" s>float I d[] f! ELSE I d[] f@ 0 s>f f>= IF d1 @ 1 <> IF 1 d1 ! THEN cr ." DAMAGE CONTROL REPORT: " 9 emit I r1 ! I DeviceName type ." REPAIR COMPLETED." THEN THEN THEN LOOP 20 % chance IF 1 fnr() r1 ! cr ." DAMAGE CONTROL REPORT: " 9 emit r1 @ DeviceName type 60 % chance IF ran0 5 s>f f* 1 s>f f+ fnegate ." DAMAGED" ELSE ran0 3 s>f f* 1 s>f f+ ." STATE OF REPAIR IMPROVED" THEN r1 @ d[] f@ f+ r1 @ d[] f! THEN ; : ManeuverEnergy ( -- | reroute shields to complete maneuver if needed) n @ 10 + negate e +! e @ 0< IF cr ." SHIELD CONTROL SUPPLIES ENERGY TO COMPLETE THE MANEUVER." e @ s +! 0 e ! s @ 0 max s ! THEN ; \ Adjust quadrant and sector coordinates if we are on boundary between quadrants. : AdjustBoundary ( -- ) s1 @ 0= IF -1 q1 +! 8 s1 ! THEN s2 @ 0= IF -1 q2 +! 8 s2 ! THEN ; : OutsideGalaxy? ( -- flag | are we outside the galaxy?) q1 @ 1 9 within 0= dup IF q1 @ 1 max 8 min dup q1 ! s1 ! THEN q2 @ 1 9 within 0= dup IF q2 @ 1 max 8 min dup q2 ! s2 ! THEN or ; variable q4 variable q5 : MoveShip ( fdirection -- | number of sectors to move is in "n") Dir>Angle deg>rad fsincos x1 f! fnegate y1 f! s1 @ s>f y f! s2 @ s>f x f! s1 @ s2 @ EMPTY$ PlaceAt q1 @ q4 ! q2 @ q5 ! n @ 0 ?DO x1 f@ x f@ f+ x f! y1 f@ y f@ f+ y f! y f@ fround>s s1 ! x f@ fround>s s2 ! s1 @ 1 9 within s2 @ 1 9 within and IF s1 @ s2 @ IsEmpty? 0= IF \ anything blocking our path? y f@ y1 f@ f- fround>s s1 ! x f@ x1 f@ f- fround>s s2 ! cr ." WARP ENGINES SHUT DOWN AT " ." SECTOR " s1 ? ." ," s2 ? ." DUE TO BAD NAVIGATION" I s>f t f@ f+ t f! LEAVE THEN ELSE \ We may be in a new quadrant; compute new quadrant and sector coords. q1 @ 8 * s>f y1 f@ n @ s>f f* f+ y f@ f+ y f! q2 @ 8 * s>f x1 f@ n @ s>f f* f+ x f@ f+ x f! y f@ 8 s>f f/ ftrunc>s q1 ! x f@ 8 s>f f/ ftrunc>s q2 ! y f@ q1 @ 8 * s>f f- ftrunc>s s1 ! x f@ q2 @ 8 * s>f f- ftrunc>s s2 ! AdjustBoundary w1 f@ 1 s>f fmin t f@ f+ t f! OutsideGalaxy? IF cr ." LT. UHURA REPORTS MESSAGE FROM STARFLEET COMMAND:" cr ." 'PERMISSION TO ATTEMPT CROSSING OF GALACTIC PERIMETER" cr ." IS HEREBY *DENIED*. SHUT DOWN ENGINES.'" cr ." CHIEF ENGINEER SCOTT REPORTS, 'WARP ENGINES SHUT DOWN" cr ." AT SECTOR " s1 ? ." ," s2 ? ." OF QUADRANT " q1 ? ." ," q2 ? THEN q1 @ q2 @ q4 @ q5 @ d= 0= IF InNewQuadrant THEN LEAVE THEN LOOP s1 @ s2 @ ENTERPRISE$ PlaceAt ManeuverEnergy ; : CourseControl ( -- ) cr ." COURSE (1-9): " f#in c1 f! c1 f@ 9 s>f f= IF 1 s>f c1 f! THEN c1 f@ ftrunc>s 1 9 within IF s" 8" X$ $copy 1 d[] f@ f0< IF s" 0.2" X$ $copy THEN ELSE cr ." LT. SULU REPORTS, 'INCORRECT COURSE DATA, SIR!'" EXIT THEN cr ." WARP FACTOR (0-" X$ type ." ): " f#in w1 f! w1 f@ f0= IF EXIT THEN 1 d[] f@ f0< w1 f@ s" 0.2" s>float f> and IF cr ." WARP ENGINES ARE DAMAGED. MAXIMUM SPEED = WARP 0.2" EXIT THEN w1 f@ 0 s>f f> w1 f@ 8 s>f f<= and IF w1 f@ 8 s>f f* fround>s n ! \ number of sectors to travel e @ n @ - 0< IF cr ." ENGINEERING REPORTS, 'INSUFFICIENT ENERGY AVAILABLE" cr ." FOR MANEUVERING AT WARP " w1 f@ f. ." !'" s @ n @ e @ - >= 7 d[] f@ 0 s>f f> and IF cr ." DEFLECTOR CONTROL ROOM ACKNOWLEDGES " s ? ." UNITS OF ENERGY" cr ." PRESENTLY DEPLOYED TO SHIELDS." THEN EXIT THEN d0 @ n @ 0> and IF \ undock if we are docked and about to move! cr ." LT. SULU REPORTS, 'UNDOCKING FROM STARBASE, SIR!'" false d0 ! THEN KlingonsMove KlingonsShoot RepairDamage c1 f@ MoveShip ShortRangeScan t f@ t0 @ t9 @ + s>f f> IF END_NO_WIN EndOfGame EXIT THEN ELSE w1 f@ 0 s>f f<> IF cr ." CHIEF ENGINEER SCOTT REPORTS, 'THE ENGINES WON'T TAKE " ." WARP " w1 f@ f. ." '!" THEN THEN ; : CheckEnergy ( -- ) s @ e @ + 10 <= \ Total energy <= 10 ? e @ 10 <= 7 d[] f@ f0< and \ Energy <= 10 and shields damaged? or IF END_STRANDED EndOfGame THEN ; : CommandInput ( -- ) BEGIN COMMANDS$ over swap cr ." COMMAND: " $input s>upper 3 $left search IF drop swap - 3 / 1+ 1 OVER = IF DROP CourseControl ELSE 2 OVER = IF DROP ShortRangeScan ELSE 3 OVER = IF DROP LongRangeSensor ELSE 4 OVER = IF DROP FirePhasers ELSE 5 OVER = IF DROP FireTorpedo ELSE 6 OVER = IF DROP ShieldControl ELSE 7 OVER = IF DROP DamageControl ELSE 8 OVER = IF DROP LibraryComputer ELSE 9 OVER = IF DROP END_NO_WIN EndOfGame ELSE 10 OVER = IF DROP help ELSE DROP THEN THEN THEN THEN THEN THEN THEN THEN THEN THEN ELSE 2drop drop CR ." ENTER ONE OF THE FOLLOWING:" CR ." NAV (TO SET COURSE)" CR ." SRS (FOR SHORT RANGE SENSOR SCAN)" CR ." LRS (FOR LONG RANGE SENSOR SCAN)" CR ." PHA (TO FIRE PHASERS)" CR ." TOR (TO FIRE PHOTON TORPEDOES)" CR ." SHE (TO RAISE OR LOWER SHIELDS)" CR ." DAM (FOR DAMAGE CONTROL REPORTS)" CR ." COM (TO CALL ON LIBRARY COMPUTER)" CR ." XXX (TO RESIGN YOUR COMMAND)" CR ." HEL (FOR HELP ON COMMANDS)" CR THEN GameEnded? 0= IF CheckEnergy THEN GameEnded? UNTIL ; : NewGame ( -- ) BEGIN Initialize InNewQuadrant ShortRangeScan CommandInput PlayAgain? false = UNTIL ; cr cr cr .( ------*------, ) cr .( ,------------- `--- ------' ) cr .( `-------- --' / / ) cr .( --\\-------/ /--, ) cr .( '--------------' ) cr .( ) cr .( The USS Enterprise --- NCC - 1701 ) cr .( ) cr .( Press to begin a game ) cr refill drop page NewGame