!*************************************************************************
!**
!**  Super Z Trek: Star Trek for the Z Machine
!**
!**  Ported to Inform by John Menichelli
!**
!*************************************************************************

!** The Star Trek game has been around since the dawn of personal computers.
!** This version, written in Inform by John Menichelli, is just the latest
!** incarnation of this classic game. If you have any questions, comments
!** or bug reports, please email them to me at menichel@@0064pixi.com. This
!** program and its source code are in the public domain.
!**
!** This version is based on the C port of an old BASIC program. The C version
!** was written by Chris Nystrom and is available from:
!**
!** http://www.cfi.org/pub/ccn/startrek
!**
!** You can contact the author of C port at:
!**
!** Chris Nystrom
!** 1013 Prairie Dove Circle
!** Austin, Texas  78758
!**
!** E-Mail: [email protected], [email protected], or [email protected]

!** The original Super Star Trek game comes from the book "BASIC Computer
!** Games" edited by David Ahl of Creative Computing fame. It was published
!** in 1978 by Workman Publishing, 1 West 39 Street, New York, New York,
!** and the ISBN is: 0-89489-052-3.
!**
!** 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 STATMENTS PER LINE
!**
!** Notes on the Inform version:
!**
!** Since Inform only works with integers, this version eliminates the
!** guesswork involved in moving and firing torpedoes. To make up for
!** this, the torpedo algorithm gives the torped a random chance to miss,
!** which increases as the range increases.

!** Constants

Constant MAX_TORPS 10;
Constant KLINGON_POWER 200;
Constant MAX_POWER 3000;
Constant SCREEN_SIZE 6;
Constant ENTERPRISE 1;
Constant KLINGON 2;
Constant BASE 3;
Constant STAR 4;
Constant WARP_ENGINES 0;
Constant SHORT_RANGE 1;
Constant LONG_RANGE 2;
Constant PHASER_CONTROL 3;
Constant PHOTON_TUBES 4;
Constant DAMAGE_CONTROL 5;
Constant SHIELD_CONTROL 6;
Constant LIBRARY_COMPUTER 7;

!** Global Variables

Global trek_docked_flag;                ! 1 or 2 if Enterprise is docked
Global trek_current_energy;             ! Current energy
Global trek_shield_value;               ! Current shield value
Global trek_torp_capacity = MAX_TORPS;  ! Photon torpedo capacity
Global trek_torps_remaining;            ! Photon torpedoes left
Global trek_max_speed;                  ! Maximum allowed speed
Global trek_end_of_time;                ! End of time/game
Global trek_current_date;               ! Current stardate
Global trek_total_bases;                ! Total starbases
Global trek_total_klingons;             ! Klingons at start
Global trek_klingons_left;              ! Total Klingons left
Global trek_quadrant_position;          ! These two variables are used
Global trek_sector_position;            ! to calculate the quadrant and
                                       ! sector location of the Enterprise
!** Arrays

Array trek_long_range_galaxy --> 64;    ! Holds long range scan data
Array trek_galaxy_history --> 64;       ! Hold history of all long and short
                                       ! range scans
Array trek_temp_array --> 64;           ! Used for printing long range scans
Array trek_sector -> 64;                ! Sector data array
Array trek_damage_array -> 8;           ! Damage Array
Array trek_klingon_array -> 3;          ! Array used to track Klingon damage;
Array text_array -> 60;                 ! Input array for keyboard entry

! Main Program

[ Main ;
  PlayTrek();
];

[ PlayTrek ;
  TrekIntro();
  Initialize();
  EndScreen();
];

[ TrekIntro ;
  font off;
  box "************************************"
      "*                                  *"
      "*                                  *"
      "*       * * Super Z Trek * *       *"
      "*                                  *"
      "*                                  *"
      "************************************";

  print "^^^";
  spaces (0->33)/2 - 12;
  print "Press any key to begin...";

  Pause();
];

[ Initialize i j bases stars klingons;

  ! Initialize time

  trek_current_date = (20 + random(10)) * 1000;
  trek_end_of_time = (25 + random(10)) * 10;

 ! Setup What Exists in Galaxy

  for (i = 0: i < 64: i++)
     trek_galaxy_history-->i = 999;

  for (i = 0: i < 64: i++)
  {
     j = random(100);
     switch(j)
        {
           98 to 99: klingons = 3;
        95 to 97: klingons = 2;
        81 to 94: klingons = 1;
        default:  klingons = 0;
     }

     trek_klingons_left = trek_klingons_left + klingons;

        if (random(100) > 96)
           bases = 1;
        else
           bases = 0;

     trek_total_bases = trek_total_bases + bases;

     stars = random(8);

     trek_long_range_galaxy-->i = (klingons * 100) +
                                  (bases * 10)     +
                                   stars;
  }

  if (trek_total_bases == 0)
  {
     i = random(64) - 1;
     j = trek_long_range_galaxy-->i;
     j = j + 10;
     trek_long_range_galaxy-->i = j;
     trek_total_bases++;
  }

  if (trek_klingons_left > trek_end_of_time / 10)
    trek_end_of_time = (trek_klingons_left + 1) * 10;

  trek_total_klingons = trek_klingons_left;

 ! Initialize Enterprise

  trek_docked_flag = 0;
  trek_current_energy = MAX_POWER;
  trek_torps_remaining = trek_torp_capacity;
  trek_shield_value = 0;
  trek_max_speed = 8;
  trek_quadrant_position = random(64) - 1;
  trek_sector_position = random(64) - 1;

  for (i = 0: i < 8: i++)
     trek_damage_array->i = 5;

  MissionBrief();
  SetScreen();
  NewQuadrant();
  UpdateStatus();
  ShortRangeScan();
  MainMenu();
];

[ NewQuadrant i j k b s ;
  trek_galaxy_history-->trek_quadrant_position =
  trek_long_range_galaxy-->trek_quadrant_position;

  for (i = 0: i < 3: i++)
     trek_klingon_array->i = KLINGON_POWER;

  i = trek_long_range_galaxy-->trek_quadrant_position;

  k = i / 100;                     ! Klingons
  b = i / 10 - (10 * k);           ! Bases
  s = i - (100 * k) - (10 * b);    ! Stars

  for (i = 0: i < 64: i++)
     trek_sector->i = 0;

  trek_sector->trek_sector_position = ENTERPRISE;

  for (i = 1: i <= k: i++)         ! Position Klingons
  {
Retry1;
     j = random(64) - 1;
     if (trek_sector->j ~= 0)
        jump Retry1;
     else
        trek_sector->j = KLINGON;
  }

  for (i = 1: i <= b: i++)         ! Position base
  {
Retry2;
     j = random(64) - 1;
     if (trek_sector->j ~= 0)
        jump Retry2;
     else
        trek_sector->j = BASE;
  }

  for (i = 1: i <= s: i++)         ! Position stars
  {
Retry3;
     j = random(64) - 1;
     if (trek_sector->j ~= 0)
        jump Retry3;
     else
        trek_sector->j = STAR;
  }
];


[ SetScreen i j;
  @erase_window $ffff;
  @split_window SCREEN_SIZE;
  @set_window 1;
  style reverse;
  j = SCREEN_SIZE;
  for (i = 1 : i <= j: i++)
  {
     @set_cursor i 1;
     spaces (0->33)-1;
  }
  style roman;
];

[ MissionBrief ;
  @erase_window $ffff;
  new_line;
  new_line;
  print "To:      Captain, USS Enterprise, NCC-1701^^";

  print "From:    Starfleet Command^^";

  print "Subject: War Warning^^";

  print "1. Approximately three (3) hours ago, warships of the Imperial
         Klingon Empire Navy crossed the border into Federation space. These
         vessels have destroyed all outposts and ships in their path and
         have not answered any hails.^^";

  print "2. Therefore, effective immediately, a state of war exists between
         the United Federation of Planets and the Imperial Klingon
         Empire.^^";

  print "3. As the Enterprise is the only vessel available in this portion
         of the galaxy, your orders are as follows:^^";

  print "4. Engage and destroy any and all Klingon vessels you encounter
         within your designated patrol zone. Long range sensor scans indicate
         a total of ", trek_klingons_left, " Klingon battlecruisers
         in your area.^^";

  print "5. Starfleet Operations calculates that it will take
         approximately ", trek_end_of_time / 10, " days to mobilize our
         forces and begin sending reinforcements to the front. We need you
         to hold off the invading Klingon fleet until those reinforcements
         arrive.^^";

  print "6. Good luck and good hunting.^^";

  print "[Press any key to accept command]";

  Pause();
];

[ UpdateStatus i;
  @set_window 1;

  @set_cursor 1 1;
  style reverse;
  for (i = 1: i <= 2: i++) {
     @set_cursor i 1;
     spaces (0->33)-1; }

  @set_cursor 1 1;
  print "Current Date:                   Days Remaining:^";
  print "Klingons Remaining:               Bases Remaining:^";
  print "Shield Value:           Total Energy Remaining:^^";

  print "1: Nav     2: SRS     3: LRS      4: Phaser  5: Torp^";
  print "6: Shield  7: Damage  8: Library  9: Help    0: Quit";

  @set_cursor 1 15;
  print (trek_current_date / 10), ".", (trek_current_date % 10);

  if (trek_end_of_time < 100)
     @set_cursor 1 50;
  else
     @set_cursor 1 49;

  print trek_end_of_time / 10, ".", trek_end_of_time % 10;

  @set_cursor 2 21;
  print trek_klingons_left;
  @set_cursor 2 52;
  print trek_total_bases;

  @set_cursor 3 15;
  print trek_shield_value;
  i = trek_current_energy + trek_shield_value;
  @set_cursor 3 49;

  switch(i)
  {
     0 to 9     : print "   ", i;
     10 to 99   : print "  ", i;
     100 to 999 : print " ", i;
     default    : print i;
  }

  style roman;

  @set_window 0;
];

[ MainMenu i ;
  for (::)
  {
     @read_char 1 -> i;

     switch(i)
     {
        '0' : break;
        '1' : CourseControl();
        '2' : ShortRangeScan();
        '3' : LongRangeScan();
        '4' : PhaserControl();
        '5' : PhotonTorps();
        '6' : ShieldControl();
        '7' : DamageControl();
        '8' : Library();
        '9' : Help();
     }
  if (i == '0') break;
  }
];

[ CourseControl i course speed;
  PrintCompass();

  print "^Enter course (1-8): ";
  @read_char 1 -> i;

  if (i < '1' || i > '8')
     "^Lt. Sulu reports: ~Incorrect course data, sir!~^";

  course = i - 48;
  print course;

  trek_max_speed = trek_damage_array->WARP_ENGINES;
  trek_max_speed = trek_max_speed + 3;
  print "^^Enter warp speed (1-", trek_max_speed, "): ";
  @read_char 1 -> i;
  speed = i - 48;

  if (speed < 1)
     "^Lt. Sulu reports: ~Incorrect speed, sir!~^^";

  if (speed > trek_max_speed)
     "^Chief Engineer Scott reports: ~The engines won't take more than warp ",
      trek_max_speed, "!~^^";

  if (speed * 10 > trek_current_energy + trek_shield_value)
     "^Chief Engineer Scott reports: ~We don't have enough energy power to go
      that fast!~^^";

  trek_current_energy = trek_current_energy - (speed * 10);

  print speed, "^^";

 if (trek_current_energy < 0)
 {
    print "^Shield Control supplies energy to complete the maneuver.^";

    trek_shield_value = trek_shield_value + trek_current_energy;
    trek_current_energy = 0;

    if (trek_shield_value < 0)
       trek_shield_value = 0;

  }
  CompleteManeuver(course, speed);
  if (trek_current_energy + trek_shield_value <= 0)
     OutOfEnergy();
];

[ CompleteManeuver course speed i j xs ys xq yq;
  xs = (trek_sector_position % 8) + 1;
  ys = 8 - (trek_sector_position / 8);

  xq = (trek_quadrant_position % 8) + 1;
  yq = 8 - (trek_quadrant_position / 8);

  j = trek_sector_position;

  for (i = 1: i <= speed: i++)
  {

     if (OutOfBounds(course) == 1)
     {
           print "^Movement aborted - you may not leave your designated
                  patrol area.^";
           break;
     }

     switch(course)
     {
        1: ys++;
        2: xs++; ys++;
        3: xs++;
        4: xs++; ys--;
        5: ys--;
        6: ys--; xs--;
        7: xs--;
        8: xs--; ys++;
     }

     if (xs < 1 || xs > 8 || ys < 1 || ys > 8)
     {
        if (xs < 1) { xs = 8; xq--; }
        if (xs > 8) { xs = 1; xq++; }
        if (ys < 1) { ys = 8; yq--; }
        if (ys > 8) { ys = 1; yq++; }

        j = (8 * (8 - ys)) + xs - 1;
        trek_sector_position = j;
        trek_quadrant_position = (8 * (8 - yq)) + xq - 1;
        if (trek_docked_flag > 0)
           trek_docked_flag = 0;
        NewQuadrant();
     }
     else
     {
        j = (8 * (8 - ys)) + xs - 1;

        if (trek_sector->j == KLINGON or STAR) ! You can pass through a base
        {
           print "^Movement aborted due to improper navigation.^";
           break;
        }
        if (trek_sector->j == BASE)
        {
           if (i == speed)
           {
              print "^The Enterprise is now docked.^";
              trek_docked_flag = 1;
              trek_sector->trek_sector_position = 0;
              trek_sector_position = j;
!               jump DoneMoving;
           }
           else
              continue;
        }
        else
        {
           trek_sector->j = ENTERPRISE;
           if (trek_docked_flag > 0)
           {
              trek_docked_flag = 0;
              trek_sector->trek_sector_position = BASE;
           }
           else
              trek_sector->trek_sector_position = 0;

           trek_sector_position = j;
        }
     }
  }
!.DoneMoving;
  trek_current_date = trek_current_date + speed;
  trek_end_of_time = trek_end_of_time - speed;
  if (trek_end_of_time <= 0)
     EndOfTime();
  UpdateStatus();
  DamageRepair();
  UpdateStatus();
  ShortRangeScan();
];

[ OutOfBounds course xs ys xq yq;
  xs = (trek_sector_position % 8) + 1;
  ys = 8 - (trek_sector_position / 8);

  xq = (trek_quadrant_position % 8) + 1;
  yq = 8 - (trek_quadrant_position / 8);

  if (xq == 1 && yq == 1 && xs == 1 && ys == 1) ! Lower left corner
  {
     if (course == 4 or 5 or 6 or 7 or 8)
        return 1;
     else
        return 0;
  }

  if (xq == 8 && yq == 8 && xs == 8 && ys == 8) ! Upper right corner
  {
     if (course == 1 or 2 or 3 or 4 or 8)
        return 1;
     else
        return 0;
  }

  if (xq == 8 && yq == 1 && xs == 8 && ys == 1) ! Lower right corner
  {
     if (course == 2 or 3 or 4 or 5 or 6)
        return 1;
     else
        return 0;
  }

  if (xq == 1 && yq == 8 && xs == 1 && ys == 8) ! Upper left corner
  {
     if (course == 1 or 2 or 6 or 7 or 8)
        return 1;
     else
        return 0;
  }

  if (xq == 1 && xs == 1) ! Left edge
  {
     if (course == 6 or 7 or 8)
        return 1;
     else
        return 0;
  }

  if (xq == 8 && xs == 8) ! Right Edge
  {
     if (course == 2 or 3 or 4)
        return 1;
     else
        return 0;
  }

  if (yq == 8 && ys == 8) ! Top edge
  {
     if (course == 1 or 2 or 8)
        return 1;
     else
        return 0;
  }

  if (yq == 1 && ys == 1) ! Bottom edge
  {
     if (course == 4 or 5 or 6)
        return 1;
     else
        return 0;
  }

  return 0;
];

[ PrintCompass ;
  new_line;
  print " 8  1  2^";
  print "  @@0092 | /^";
  print "7  -+-  3^";
  print "  / | @@0092^";
  print " 6  5  4^";
];

[ ShortRangeScan x y ;
  if (trek_damage_array->SHORT_RANGE < 5)
     "^Short Range Sensors are inoperative.^";

  ! Determine Quadrant

  x = (trek_quadrant_position % 8) + 1;
  y = 8 - (trek_quadrant_position / 8);

  print "^Short range scan of quadrant ";
  print x, ", ", y, " (";
  PrintQuadrantName(x, y);
  print ")^^";

  print "     1   2   3   4   5   6   7   8^";
  print "    --- --- --- --- --- --- --- ---^";
  for (x = 0: x < 64: x++)
  {
     if (x % 8 == 0)
     {
        print " ";
        print 8 - (x/8);
        print ":";
     }

     switch (trek_sector->x)
     {
        0 : print "  . ";
        1 : print " +E+";
        2 : print " +K+";
        3 : if (trek_docked_flag == 0)
               print " >B<";
            else
               print " >D<";
        4 : print "  # ";
     }

     if ((x + 1) % 8 == 0)
        print "^";
  }

  y = 0;
  for (x = 1: x < 64: x++)
     if (trek_sector->x == 2) y++;

  print "^Alert Condition: ";

  if (y > 0)
     print "Red^";
  else if (trek_current_energy * 10 < MAX_POWER)
     print "Yellow^";
  else
     print "Green^";

];

[ LongRangeScan i j temp_pos;
  if (trek_damage_array->LONG_RANGE < 5)
     "^Long Range Sensors are inoperative.^";

  for (i = 0: i < 64: i++)
     trek_temp_array-->i = 999;

  temp_pos = trek_quadrant_position;

  if (temp_pos == 0)   ! Upper left
  {
     trek_temp_array-->0 = trek_long_range_galaxy-->0;
     trek_temp_array-->1 = trek_long_range_galaxy-->1;
     trek_temp_array-->8 = trek_long_range_galaxy-->8;
     trek_temp_array-->9 = trek_long_range_galaxy-->9;

     trek_galaxy_history-->0 = trek_long_range_galaxy-->0;
     trek_galaxy_history-->1 = trek_long_range_galaxy-->1;
     trek_galaxy_history-->8 = trek_long_range_galaxy-->8;
     trek_galaxy_history-->9 = trek_long_range_galaxy-->9;

     jump Printit;
  }

  if (temp_pos == 7)   ! Upper right
  {
     trek_temp_array-->6  = trek_long_range_galaxy-->6;
     trek_temp_array-->7  = trek_long_range_galaxy-->7;
     trek_temp_array-->14 = trek_long_range_galaxy-->14;
     trek_temp_array-->15 = trek_long_range_galaxy-->15;

     trek_galaxy_history-->6  = trek_long_range_galaxy-->6;
     trek_galaxy_history-->7  = trek_long_range_galaxy-->7;
     trek_galaxy_history-->14 = trek_long_range_galaxy-->14;
     trek_galaxy_history-->15 = trek_long_range_galaxy-->15;

     jump Printit;
  }

  if (temp_pos == 56)  ! Lower left
  {
     trek_temp_array-->48 = trek_long_range_galaxy-->48;
     trek_temp_array-->49 = trek_long_range_galaxy-->49;
     trek_temp_array-->56 = trek_long_range_galaxy-->56;
     trek_temp_array-->57 = trek_long_range_galaxy-->57;

     trek_galaxy_history-->48 = trek_long_range_galaxy-->48;
     trek_galaxy_history-->49 = trek_long_range_galaxy-->49;
     trek_galaxy_history-->56 = trek_long_range_galaxy-->56;
     trek_galaxy_history-->57 = trek_long_range_galaxy-->57;

     jump Printit;
  }

  if (temp_pos == 63)  ! Lower right
  {
     trek_temp_array-->54 = trek_long_range_galaxy-->54;
     trek_temp_array-->55 = trek_long_range_galaxy-->55;
     trek_temp_array-->62 = trek_long_range_galaxy-->62;
     trek_temp_array-->63 = trek_long_range_galaxy-->63;

     trek_galaxy_history-->54 = trek_long_range_galaxy-->54;
     trek_galaxy_history-->55 = trek_long_range_galaxy-->55;
     trek_galaxy_history-->62 = trek_long_range_galaxy-->62;
     trek_galaxy_history-->63 = trek_long_range_galaxy-->63;

     jump Printit;
  }

  if (temp_pos < 8)    ! Top edge
  {
     trek_temp_array-->temp_pos     = trek_long_range_galaxy-->temp_pos;
     trek_temp_array-->(temp_pos-1) = trek_long_range_galaxy-->(temp_pos-1);
     trek_temp_array-->(temp_pos+1) = trek_long_range_galaxy-->(temp_pos+1);
     trek_temp_array-->(temp_pos+7) = trek_long_range_galaxy-->(temp_pos+7);
     trek_temp_array-->(temp_pos+8) = trek_long_range_galaxy-->(temp_pos+8);
     trek_temp_array-->(temp_pos+9) = trek_long_range_galaxy-->(temp_pos+9);

     trek_galaxy_history-->temp_pos     = trek_long_range_galaxy-->temp_pos;
     trek_galaxy_history-->(temp_pos-1) = trek_long_range_galaxy-->(temp_pos-1);
     trek_galaxy_history-->(temp_pos+1) = trek_long_range_galaxy-->(temp_pos+1);
     trek_galaxy_history-->(temp_pos+7) = trek_long_range_galaxy-->(temp_pos+7);
     trek_galaxy_history-->(temp_pos+8) = trek_long_range_galaxy-->(temp_pos+8);
     trek_galaxy_history-->(temp_pos+9) = trek_long_range_galaxy-->(temp_pos+9);

     jump Printit;
  }

  if (temp_pos > 55)   ! Bottom edge
  {
     trek_temp_array-->temp_pos     = trek_long_range_galaxy-->temp_pos;
     trek_temp_array-->(temp_pos-1) = trek_long_range_galaxy-->(temp_pos-1);
     trek_temp_array-->(temp_pos+1) = trek_long_range_galaxy-->(temp_pos+1);
     trek_temp_array-->(temp_pos-7) = trek_long_range_galaxy-->(temp_pos-7);
     trek_temp_array-->(temp_pos-8) = trek_long_range_galaxy-->(temp_pos-8);
     trek_temp_array-->(temp_pos-9) = trek_long_range_galaxy-->(temp_pos-9);

     trek_galaxy_history-->temp_pos     = trek_long_range_galaxy-->temp_pos;
     trek_galaxy_history-->(temp_pos-1) = trek_long_range_galaxy-->(temp_pos-1);
     trek_galaxy_history-->(temp_pos+1) = trek_long_range_galaxy-->(temp_pos+1);
     trek_galaxy_history-->(temp_pos-7) = trek_long_range_galaxy-->(temp_pos-7);
     trek_galaxy_history-->(temp_pos-8) = trek_long_range_galaxy-->(temp_pos-8);
     trek_galaxy_history-->(temp_pos-9) = trek_long_range_galaxy-->(temp_pos-9);

     jump Printit;
  }

  if (temp_pos % 8 == 0)  ! Left edge
  {
     trek_temp_array-->temp_pos     = trek_long_range_galaxy-->temp_pos;
     trek_temp_array-->(temp_pos-8) = trek_long_range_galaxy-->(temp_pos-8);
     trek_temp_array-->(temp_pos+8) = trek_long_range_galaxy-->(temp_pos+8);
     trek_temp_array-->(temp_pos-7) = trek_long_range_galaxy-->(temp_pos-7);
     trek_temp_array-->(temp_pos+1) = trek_long_range_galaxy-->(temp_pos+1);
     trek_temp_array-->(temp_pos+9) = trek_long_range_galaxy-->(temp_pos+9);

     trek_galaxy_history-->temp_pos     = trek_long_range_galaxy-->temp_pos;
     trek_galaxy_history-->(temp_pos-8) = trek_long_range_galaxy-->(temp_pos-8);
     trek_galaxy_history-->(temp_pos+8) = trek_long_range_galaxy-->(temp_pos+8);
     trek_galaxy_history-->(temp_pos-7) = trek_long_range_galaxy-->(temp_pos-7);
     trek_galaxy_history-->(temp_pos+1) = trek_long_range_galaxy-->(temp_pos+1);
     trek_galaxy_history-->(temp_pos+9) = trek_long_range_galaxy-->(temp_pos+9);

     jump Printit;
  }
  if ((temp_pos+1) % 8 == 0)  ! Right edge
  {
     trek_temp_array-->temp_pos     = trek_long_range_galaxy-->temp_pos;
     trek_temp_array-->(temp_pos-8) = trek_long_range_galaxy-->(temp_pos-8);
     trek_temp_array-->(temp_pos+8) = trek_long_range_galaxy-->(temp_pos+8);
     trek_temp_array-->(temp_pos+7) = trek_long_range_galaxy-->(temp_pos+7);
     trek_temp_array-->(temp_pos-1) = trek_long_range_galaxy-->(temp_pos-1);
     trek_temp_array-->(temp_pos-9) = trek_long_range_galaxy-->(temp_pos-9);

     trek_galaxy_history-->temp_pos     = trek_long_range_galaxy-->temp_pos;
     trek_galaxy_history-->(temp_pos-8) = trek_long_range_galaxy-->(temp_pos-8);
     trek_galaxy_history-->(temp_pos+8) = trek_long_range_galaxy-->(temp_pos+8);
     trek_galaxy_history-->(temp_pos+7) = trek_long_range_galaxy-->(temp_pos+7);
     trek_galaxy_history-->(temp_pos-1) = trek_long_range_galaxy-->(temp_pos-1);
     trek_galaxy_history-->(temp_pos-9) = trek_long_range_galaxy-->(temp_pos-9);

     jump Printit;
  }

  ! Everything else

  trek_temp_array-->temp_pos     = trek_long_range_galaxy-->temp_pos;
  trek_temp_array-->(temp_pos-9) = trek_long_range_galaxy-->(temp_pos-9);
  trek_temp_array-->(temp_pos-8) = trek_long_range_galaxy-->(temp_pos-8);
  trek_temp_array-->(temp_pos-7) = trek_long_range_galaxy-->(temp_pos-7);
  trek_temp_array-->(temp_pos-1) = trek_long_range_galaxy-->(temp_pos-1);
  trek_temp_array-->(temp_pos+1) = trek_long_range_galaxy-->(temp_pos+1);
  trek_temp_array-->(temp_pos+7) = trek_long_range_galaxy-->(temp_pos+7);
  trek_temp_array-->(temp_pos+8) = trek_long_range_galaxy-->(temp_pos+8);
  trek_temp_array-->(temp_pos+9) = trek_long_range_galaxy-->(temp_pos+9);

  trek_galaxy_history-->temp_pos     = trek_long_range_galaxy-->temp_pos;
  trek_galaxy_history-->(temp_pos-9) = trek_long_range_galaxy-->(temp_pos-9);
  trek_galaxy_history-->(temp_pos-8) = trek_long_range_galaxy-->(temp_pos-8);
  trek_galaxy_history-->(temp_pos-7) = trek_long_range_galaxy-->(temp_pos-7);
  trek_galaxy_history-->(temp_pos-1) = trek_long_range_galaxy-->(temp_pos-1);
  trek_galaxy_history-->(temp_pos+1) = trek_long_range_galaxy-->(temp_pos+1);
  trek_galaxy_history-->(temp_pos+7) = trek_long_range_galaxy-->(temp_pos+7);
  trek_galaxy_history-->(temp_pos+8) = trek_long_range_galaxy-->(temp_pos+8);
  trek_galaxy_history-->(temp_pos+9) = trek_long_range_galaxy-->(temp_pos+9);

Printit;
  new_line;
  new_line;

  print "                 Long Range Scan Results^^";
  print "      1     2     3     4     5     6     7     8^";
  print "    ----- ----- ----- ----- ----- ----- ----- -----^";

  for (i = 0: i < 64: i++)
  {
     if (i%8 == 0)
     {
        print " ";
        print 8 - i/8;
        print ":";
     }

     j = trek_temp_array-->i;

     print " ";

     if (i == temp_pos)
        style reverse;
     else
        style roman;

     switch(j)
     {
        0 to 9   : print " 00"; print j;
        10 to 98 : print " 0";  print j;
        999      : print " ***";
        default  : print " "; print j;
     }

     print " ";

     style roman;

  if (i%8 == 7)
     print "^";
  }
];

[ TextToNumber n x len mul tot;
   text_array -> 0 = 60;
   read text_array 0;

   if (text_array->1 > 4)
      return -1;

   x = 0;
   len = text_array->1;

   if (len == 4) mul=1000;
   if (len == 3) mul=100;
   if (len == 2) mul=10;
   if (len == 1) mul=1;

   tot = 0;

   for (n = 0: n < len: n++)
   {
      if (text_array->(n+2) > 47 && text_array->(n+2) < 58)
      {
         x = text_array->(n+2);
         x = x - 48;
         tot = tot + mul * x;
         mul = mul/10;
      }
      else
         return -1;
   }
   return tot;
];

[ PhaserControl i j k x1 y1 x2 y2 z rng dmg;
  if (trek_damage_array->PHASER_CONTROL < 5)
     "^Science Officer Spock reports: ~Phasers are inoperative, Captain.~^";

  k = trek_long_range_galaxy-->trek_quadrant_position;

  k = k / 100;                     ! Klingons

  if (k == 0)
     "^Science Officer Spock reports: ~Sensors show no enemy ships in this
      quadrant~^";

  if (trek_damage_array->LIBRARY_COMPUTER < 5)
     print "^Science Officer Spock reports: ~Computer failure will hamper
            accuracy, Captain.~^";

  print "^Phasers locked on target. Energy available = ",
         trek_current_energy + trek_shield_value;

  print "^Enter number of units to fire: ";

  i = TextToNumber();

  if (i <= 0)
     "^Science Officer Spock reports: ~Phaser fire aborted.~^";

  if (i > trek_current_energy)
     "^Science Officer Spock reports: ~Insufficient energy for that
      attack.~^";

  trek_current_energy = trek_current_energy - i;

  if (trek_damage_array->LIBRARY_COMPUTER < 5) ! Computer damage affects targeting
     i = i * trek_damage_array->LIBRARY_COMPUTER / 5;

  i = i / k; ! Divide the energy between each target

  x1 = (trek_sector_position % 8) + 1;
  y1 = 8 - (trek_sector_position / 8);

  k = -1;

  for (j = 0: j < 64: j++)
  {
     if (trek_sector->j == KLINGON)
     {
        k++;
        x2 = (j % 8) + 1;
        y2 = 8 - (j / 8);

        rng = Range(x1, y1, x2, y2);

        dmg = i;

        dmg = dmg * 10 / (rng + random(5) - 1);

        z = trek_klingon_array->k;

        if (dmg <= 0)
           "^Science Officer Spock reports: ~Sensors show no damage to
            the Klingon battlecruiser at ", x2, ", ", y2, ".~^";

        if (dmg >= z)
        {
           print "^Science Officer Spock reports: ~The Klingon battlecruiser
                  at ", x2, ", ", y2, " has been destroyed.~^";
           trek_klingon_array->k = 0;
           trek_sector->j = 0;
           trek_klingons_left--;
           if (trek_klingons_left == 0)
              WonGame();

           z = trek_long_range_galaxy-->trek_quadrant_position;
           z = z - 100;
           trek_long_range_galaxy-->trek_quadrant_position = z;
           if (z / 100 == 0)
              ShortRangeScan();
           UpdateStatus();
        }

        else
        {
           z = z - dmg;
           trek_klingon_array->k = z;
           print "^Science Officer Spock reports: ~Sensors show that the
                  Klingon battlecruiser at ", x2, ", ", y2, " suffered a ",
                  dmg, " unit hit.~^";
        }
     }
  }
  KlingonsShoot();
];

[ PhotonTorps course i x1 y1 x2 y2 z index ;
  if (trek_torps_remaining == 0)
     "^Ensign Chekov reports: ~All photon torpedoes expended, sir!~^";

  if (trek_damage_array->PHOTON_TUBES < 5)
     "^Ensign Chekov reports: ~Photon torpedo tubes not operational, sir!~^";

  i = trek_long_range_galaxy-->trek_quadrant_position;

  i = i / 100;                     ! Klingons

  if (i == 0)
     "^Ensign Chekov reports: ~There are no Klingons in this quadrant, sir!~^";

  trek_torps_remaining--;
  x1 = (trek_sector_position % 8) + 1;
  y1 = 8 - (trek_sector_position / 8);

  PrintCompass();

  print "^Enter torpedo course (1-8): ";

  @read_char 1 -> i;

  if (i < '1' || i > '8')
     "^Ensign Chekov reports: ~Incorrect course data, sir!~^";

  course = i - 48;

  print course, "^";

  for (i = 1: i < 8: i++)
  {
     switch(course)
     {
        1: y1++;
        2: x1++; y1++;
        3: x1++;
        4: x1++; y1--;
        5: y1--;
        6: y1--; x1--;
        7: x1--;
        8: x1--; y1++;
     }

     if (x1 < 1 || x1 > 8 || y1 < 1 || y1 > 8)
     {
        print "^Ensign Chekov reports: ~The torpedo missed, sir!~^";
        break;
     }

     index = (8 * (8 - y1)) + x1 - 1;

     if (trek_sector->index == KLINGON)
     {
        x2 = (trek_sector_position % 8) + 1;
        y2 = 8 - (trek_sector_position / 8);

        z = Range(x1, y1, x2, y2);

        z = z / 15;

        if (random(10) - 1 < z)
        {
           print "^Ensign Chekov reports: ~The torpedo missed, sir!~^";
           break;
        }
        else
        {
           trek_sector->index = 0;
           trek_klingons_left--;
           if (trek_klingons_left == 0)
              WonGame();
           z = trek_long_range_galaxy-->trek_quadrant_position;
           z = z - 100;
           trek_long_range_galaxy-->trek_quadrant_position = z;
           print "^Ensign Chekov reports: ~The Klingon battlecruiser in
                  sector ", x2, ", ", y2, " has been destroyed, sir!~^";
           UpdateStatus();
           ShortRangeScan();
           break;
        }
     }

     if (trek_sector->index == BASE)
     {
        print "^Ensign Chekov reports: ~You destroyed a base, sir!~^";
        trek_total_bases--;
        z = trek_long_range_galaxy-->trek_quadrant_position;
        z = z - 10;
        trek_long_range_galaxy-->trek_quadrant_position = z;

        if (trek_total_bases == 0 &&
            trek_klingons_left <= (trek_current_date / 10) -
                                  trek_end_of_time / 10)
        {
           print "That does it, Captain!! You are hereby relieved of command
                  and sentenced to 99 stardates of hard labor on Cygnus 12!! ";
           LoseGame();
        }

        if (trek_docked_flag > 0) ! Undock
        {
           trek_docked_flag = 0;
           trek_sector->trek_sector_position = ENTERPRISE;
           ShortRangeScan();
        }

        break;
     }

     if (trek_sector->index == STAR)
     {
        print "^Ensign Chekov reports: ~The star absorbed the torpedo's
               energy, sir!~^";
        break;
     }
  }
  KlingonsShoot();
];

[ DamageControl ;
  new_line;
  new_line;
  print "System                    Status^";
  print "-------------------------------------^";

  print "Warp Engines              ";
  if (trek_damage_array->WARP_ENGINES == 5)
     print "Operational^";
  else
     print "Damaged^";

  print "Short Range Sensors       ";
  if (trek_damage_array->SHORT_RANGE == 5)
     print "Operational^";
  else
     print "Damaged^";

  print "Long Range Sensors        ";
  if (trek_damage_array->LONG_RANGE == 5)
     print "Operational^";
  else
     print "Damaged^";

  print "Phaser Control            ";
  if (trek_damage_array->PHASER_CONTROL == 5)
     print "Operational^";
  else
     print "Damaged^";

  print "Photon Torpedo Tubes      ";
  if (trek_damage_array->PHOTON_TUBES == 5)
     print "Operational^";
  else
     print "Damaged^";

  print "Damage Control            ";
  if (trek_damage_array->DAMAGE_CONTROL == 5)
     print "Operational^";
  else
     print "Damaged^";

  print "Shield Control            ";
  if (trek_damage_array->SHIELD_CONTROL == 5)
     print "Operational^";
  else
     print "Damaged^";

  print "Library-Computer          ";
  if (trek_damage_array->LIBRARY_COMPUTER == 5)
     print "Operational^";
  else
     print "Damaged^";
];

[ ShieldControl i;
  if (trek_damage_array->SHIELD_CONTROL < 5)
     "Shield Control is inoperative.";

  print "^Total energy available = ", trek_current_energy + trek_shield_value;

  print "^Input number of units to shields: ";

  i = TextToNumber();

  if (i == -1)
     "^Shield Control reports: ~Invalid request - shields unchanged.~^";

  if (i == trek_shield_value)
     "^<Shields Unchanged>^";

  if (i >= trek_current_energy + trek_shield_value)
      "^Shield Control reports: ~There is insufficient energy available -
       shields unchanged.~^";

  trek_current_energy = trek_current_energy + trek_shield_value - i;
  trek_shield_value = i;

  print "^Shield Control reports: ~Shields now at ", trek_shield_value,
         " units per your command.~^";
  UpdateStatus();
];

[ Library i;
  if (trek_damage_array->LIBRARY_COMPUTER < 5)
     "^The Library Computer is inoperative.^";

  print "^Choose which library-computer function you wish to use:^^";
  print "1: Galactic Record^";
  print "2: Status Report^";
  print "3: Exit^^";
  print "Enter choice: ";

  @read_char 1 -> i;
  print i - 48, "^";
  switch(i)
  {
     '1' : GalacticRecord();
     '2' : StatusReport();
     '3' : "^Library-computer exited.^^";
     default: "^Invalid choice.^";
  }
];

[ GalacticRecord i j;
  new_line;
  new_line;

  print "                        The Galaxy^^";
  print "      1     2     3     4     5     6     7     8^";
  print "    ----- ----- ----- ----- ----- ----- ----- -----^";

  for (i = 0: i < 64: i++)
  {
     if (i%8 == 0)
     {
        print " ";
        print 8 - i/8;
        print ":";
     }

     j = trek_galaxy_history-->i;

     print " ";

     if (i == trek_quadrant_position)
        style reverse;
     else
        style roman;

     switch(j)
     {
        0 to 9   : print " 00"; print j;
        10 to 98 : print " 0";  print j;
        999      : print " ***";
        default  : print " "; print j;
     }

     print " ";

     style roman;

  if (i%8 == 7)
     print "^";
  }
];

[ StatusReport i j x y;
  for (i = 1: i < 64: i++)
     if (trek_sector->i == KLINGON) j++;

  print "^Status Report:^^";

  print "Startdate: ", (trek_current_date / 10), ".",
         (trek_current_date % 10), "^^";

  print "Time remaining in mission: ", trek_end_of_time / 10, ".",
         trek_end_of_time % 10, " days^^";

  x = (trek_quadrant_position % 8) + 1;
  y = 8 - (trek_quadrant_position / 8);

  print "Position:^^";
  print "   Quadrant: ", x, ", ", y, " (";
  PrintQuadrantName(x, y);
  print ")^^";

  x = (trek_sector_position % 8) + 1;
  y = 8 - (trek_sector_position / 8);

  print "   Sector:   ",  x, ", ", y, "^^";

  print "Alert Condition: ";

  if (j > 0)
     print "Red^^";
  else if (trek_current_energy * 10 < MAX_POWER)
     print "Yellow^^";
  else
     print "Green^^";

  print "Klingon warships remaining: ", trek_klingons_left, "^^";

  print "Total bases remaining: ", trek_total_bases, "^^";

  print "Total energy remaining: ", trek_current_energy +
         trek_shield_value, "^^";

  print "Current shield setting: ", trek_shield_value, "^^";

  print "Total torpedoes remaining: ", trek_torps_remaining, "^";
];

[ KlingonsShoot i j k x1 y1 x2 y2 rng dmg;
  i = trek_long_range_galaxy-->trek_quadrant_position;

  i = i / 100;                     ! Klingons

  if (i == 0) return;

  if (trek_docked_flag > 0)
     "^Starbase shields protect the Enterprise^^";

  j = -1;
  for (k = 0: k < 64: k++)
  {
     if (trek_sector->k == KLINGON)
     {
        j++;
        x1 = (k % 8) + 1;
        y1 = 8 - (k / 8);

        x2 = (trek_sector_position % 8) + 1;
        y2 = 8 - (trek_sector_position / 8);

        rng = Range(x1, y1, x2, y2);

        dmg = trek_klingon_array->j;

        x2 = trek_klingon_array->j;

        x2 = x2 * 2 / 3; ! Reduce available Klingon energy by 1/3

        trek_klingon_array->j = x2;

        dmg = dmg * 10 / (rng + random(5) - 1);

        print "^The Klingon battlecruiser at ", x1, ", ", y1,
              " fires on you for ", dmg, " units of damage.^";

        if (dmg > trek_shield_value)
        {
           ShipDestroyed();
        }
        else
        {
           trek_shield_value = trek_shield_value - dmg;
           print "^Shield energy is down to ", trek_shield_value,
                 " units.^";
           if (dmg >= 20)
           {
              if (random(10) < 7 || (dmg * 10 / trek_shield_value > 2))
              {
                 dmg = random(8) - 1;
                 if (trek_damage_array->dmg > 0)
                 {
                    x2 = trek_damage_array->dmg;
                    x2--;
                    trek_damage_array->dmg = x2;
                 }
                 print "^Damage control reports: ~";
                 switch(dmg)
                 {
                    0 :  print "The warp engines were";
                    1 :  print "The short range sensors were";
                    2 :  print "The long range sensors were";
                    3 :  print "Phaser controls were";
                    4 :  print "The photon torpedo tubes were";
                    5 :  print "Damage control was";
                    6 :  print "Shield control was";
                    7 :  print "The library-computer was";
                 }
                 print " damaged in the attack.~^";
              }
           }
        }
     }
  }
  KlingonsMove();
  UpdateStatus();
  ShortRangeScan();
];

[ KlingonsMove i j k;
  j = 0;
  for (i = 0: i < 64: i++)
  {
     if (trek_sector->i == KLINGON)
     {
        j++;                  ! Count the number of Klingons in the sector
        trek_sector->i = 0;   ! and zero their location
     }
  }

  for (i = 1: i <= j: i++)   ! Position Klingons
  {
Retry4;
     k = random(64) - 1;
     if (trek_sector->k ~= 0)
        jump Retry4;
     else
        trek_sector->k = KLINGON;
  }

  if (trek_klingon_array->0 == 0)     ! "Garbage collect" the damage array
     trek_klingon_array->0 = trek_klingon_array->1;

  if (trek_klingon_array->1 == 0)
     trek_klingon_array->1 = trek_klingon_array->2;
];

[ DamageRepair i j k;
  if (trek_docked_flag == 1) ! Docked
  {
     trek_docked_flag = 2;
     trek_current_energy = MAX_POWER;
     trek_torps_remaining = trek_torp_capacity;
     if (trek_shield_value > 0)
        print "^Shields dropped for docking purposes.^";

     trek_shield_value = 0;

     j = 0;
     for (i = 0: i < 8: i++)
     {
        if (trek_damage_array->i < 5)
        j = j + (5 - trek_damage_array->i);
     }

     if (j > 0)
     {
        print "^Technicians are standing by to effect repairs to your ship.
               These repairs will take ", j / 10, ".", j % 10, " days to
               complete. Will you authorize the repair order? (Y/N) ";

        @read_char->k;
        if (k == 'Y' or 'y')
        {
           trek_current_date = trek_current_date + j;
           trek_end_of_time = trek_end_of_time - j;
           if (trek_end_of_time <= 0)
              EndOfTime();
           for (i = 0: i < 8: i++)
              trek_damage_array->i = 5;
           print "^";
        }
        else
           "^";
     }
  }
  else
  {
     k = trek_damage_array->DAMAGE_CONTROL;
     for (i = 0: i < 8: i++)
     {
        if (trek_damage_array->i < 5 && random(20) < k)
        {
           j = trek_damage_array->i;
           j++;
           trek_damage_array->i = j;
           print "^Damage control reports: ~The ";
           switch(i)
           {
              0 : print "warp engines have";
              1 : print "short range sensors have";
              2 : print "long range sensors have";
              3 : print "phaser control system has";
              4 : print "photon torpedo tubes have";
              5 : print "damage control system has";
              6 : print "shield control system has";
              7 : print "library-computer has";
           }
           if (j < 5)
              print " been partially repaired.~^";
           else
              print " been completely repaired.~^";
        }
     }
  }
];

[ PrintQuadrantName x y;
  if (x == 1 or 2)
  {
     if (y == 1 or 2)
        print "Antares";
     if (y == 3 or 4)
        print "Rigel";
     if (y == 5 or 6)
        print "Procyon";
     if (y == 7 or 8)
        print "Vega";
  }
  if (x == 3 or 4)
  {
     if (y == 1 or 2)
        print "Canopus";
     if (y == 3 or 4)
        print "Altair";
     if (y == 5 or 6)
        print "Sagittarius";
     if (y == 7 or 8)
        print "Pollux";
  }
  if (x == 5 or 6)
  {
     if (y == 1 or 2)
        print "Sirius";
     if (y == 3 or 4)
        print "Deneb";
     if (y == 5 or 6)
        print "Capella";
     if (y == 7 or 8)
        print "Betelgeuse";
  }
  if (x == 7 or 8)
  {
     if (y == 1 or 2)
        print "Aldebaran";
     if (y == 3 or 4)
        print "Regulus";
     if (y == 5 or 6)
        print "Arcturus";
     if (y == 7 or 8)
        print "Spica";
  }

  if (x == 1 or 3 or 5 or 7)
  {
     if (y == 1 or 3 or 5 or 7)
        print " I";
     else
        print " III";
  }

  if (x == 2 or 4 or 6 or 8)
  {
     if (y == 1 or 3 or 5 or 7)
        print " II";
     else
        print " IV";
  }
];

[ Range x1 y1 x2 y2 delta_x delta_y result;
  delta_x = (x1 - x2) * 10;
  delta_x = delta_x * delta_x;

  delta_y = (y1 - y2) * 10;
  delta_y = delta_y * delta_y;

  result = SquareRoot(delta_x + delta_y);

 return result;
];

! Brute force approach to finding the square root of a number

[ SquareRoot a b;
  for (b = 1: b <= 110: b++)
  {
     if (b * b > a)
        return (b - 1);
  }
];

[ ShipDestroyed ;
  print "The Enterprise has been destroyed. You have failed. ";
  LoseGame();
];

[ OutOfEnergy ;
  print "^You've stranded yourself in space without enough energy to get to
         a base! ";
  LoseGame();
];

[ EndOfTime ;
  print "You've run out of time, Captain! ";
  LoseGame();
];

[ LoseGame ;
  print "It is stardate ", (trek_current_date / 10), ".",
         (trek_current_date % 10), ". ";

  print "There ";

  if (trek_klingons_left == 1)
     print "was ";
  else
     print "were ";
  print trek_klingons_left, " Klingon battlecruiser";

  if (trek_klingons_left ~= 1)
     print "s";

  print " left at the end of your mission.^^";

  print "[Press any key to continue.]^";
  Pause();
  EndScreen();
];

[ WonGame ;
  print "Congratulations, Captain! You have destroyed the last Klingon
         battlecruiser in your patrol area.^^";

  print "[Press any key to continue.]^";
  Pause();
  EndScreen();
];

[ EndScreen ;
  @set_cursor 1 1;
  @split_window 0;
  @erase_window $ffff;

  print "^Thanks for playing Super Z Trek.^^";
  @quit;
];

[ Pause dummy;
       @read_char 1 dummy;
       return dummy;
];

[ Help i;
  print "^Choose which file to read:^^";
  print "1: How To Play Super Z Trek^";
  print "2: About This Game^";
  print "3: Exit^^";
  print "Enter choice: ";

  @read_char 1 -> i;
  print i - 48, "^";
  switch(i)
  {
     '1' : HowToPlay();
     '2' : About();
     '3' : "^Library-computer exited.^^";
     default: "^Invalid choice.^";
  }
];

[ HowToPlay ;
  print "^Welcome to Super Z Trek, the classic computer game ported to the
         Z machine.^^";

  print "The Z Trek galaxy is divided into an 8 x 8 quadrant grid, and each
         quadrant is further divided into an 8 x 8 sector grid.^^";

  print "You will be assigned a starting point somewhere in the galaxy to
         begin a tour of duty as captain of the starship Enterprise. Your
         mission: to seek out and destroy a fleet of Klingon warships which
         have invaded the United Federation of Planets.^^";

  print "COMMANDS^^";

  print "The menu bar at the top of the screen displays information about the
         current game and a list of allowable commands. Each command (numbered
         '1' through '0') is activated by pressing the appropriate key. Each
         key only has to be pressed once; you do not have to press 'Enter'
         to complete the command. Each command is described below.^^";

  print "1. Nav: This command is used to move the Enterprise around the
         galaxy. Two additional pieces of information are required to
         complete this command: course and speed. Course is an integer
         from 1 to 8, as follows:^^";

  PrintCompass();

  print "^As with the command keys, only one keypress is required to enter
         the course.^^";

  print "The second entry is the speed, which is also an integer. The
         Enterprise's speed ranges from 1 up to a maximum of 8, but this
         maximum may be reduced due to damage to the warp engines. Speed is
         entered in the same way as course, with only one keypress
         required.^^";

  print "If you wish to abort the movement command, enter an invalid value
         for either the course or speed.^^";

  print "2. SRS: This command prints out the results of a Short Range Sensor
         scan. The print out shows what occupies the Enterprise's current
         quadrant. The symbols used are:^^";

  print "     +E+ = Your starship's position^";
  print "     +K+ = Klingon battlecruiser^";
  print "     >B< = Federation starbase (Refuel/Repair/Re-Arm here)^";
  print "     >D< = Federation starbase with the Enterprise docked^";
  print "      #  = Star^";
  print "      .  = Empty space^^";

  print "3. LRS: This shows shows conditions in space for one quadrant on
         each side of the Enterprise (which is in the middle of the scan
         in reverse video). 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.^^";

  print "Example: 207 = 2 Klingons, No Starbases, and 7 stars.^^";

  print "4. Phaser: Allows you to destroy the Klingon battlecruisers by
         zapping them with suitably large units of energy to deplete their
         shield power. With this command, you must enter the number of units
         of energy you want to fire, then press the 'Enter' key. The amount
         of energy you use will be divided evenly between all of the Klingons
         in the quadrant.^^";

  print "5. Torp: This commands fires one photon torpedo at one Klingon
         ship. You will have to enter the torpedo's course, which is the
         same used in movement. If you hit the Klingon vessel, it is
         destroyed and cannot fire back at you. If you miss, you are subject
         to the disrupter fire of all other Klingons in the quadrant.^^";

  print "Note: Since Inform only works with integers, this version
         eliminates the guesswork involved in moving and firing torpedoes.
         To make up for this, the torpedo algorithm gives the torpedo a
         random chance to miss, which increases as the range increases.^^";

  print "6. Shield: This command defines the number of energy units to be
         assigned to the shields. Energy for the shields is taken from the
         ship's total energy.
         If the Enterprise is hit and the shield value is reduced to zero or
         less, the Enterprise is destroyed. Don't forget to put energy into
         the shields before entering combat! Note that the ~Total Energy
         Remaining~ heading on the menu bar includes shield energy.^^";

  print "7. Damage: This command shows the state of repair of all devices,
         either ~Operational~ or ~Damaged.~ If a device is damaged, the
         ship's crew will attempt to repair it each time the ship moves.
         All damaged may be repaired while docked at a starbase. To dock,
         simply move into the same sector as the starbase.^^";

  print "8. Library: The library-computer has two functions: ^^";

  print "Function 1: Cumulative Galactic Record. This shows computer
         memory of the results of all previous short and long range sensor
         scans.^^";

  print "Function 2: Status Report. This function shows the number of
         Klingons, stardates, and starbases remaining in the game.^^";

  print "9. Help: Brings up the help menu.^^";

  print "0. Quit: Quits the game.^^";

];

[ About ;
  print "^The Star Trek game has been around since the dawn of personal
         computers. This version, written in Inform by John Menichelli,
         is just the latest incarnation of this classic game. If you
         have any questions, comments or bug reports, please email them to
         me at menichel@@0064pixi.com. This program and its source code are
         in the public domain.^^";

  print "The Inform version is based on the C port of an old BASIC program.
         The C version was written by Chris Nystrom and is available
         from:^^";

  print "http://www.cfi.org/pub/ccn/startrek^^";

  print "You can contact the author of the C port at:^^";

  print "Chris Nystrom^
         1013 Prairie Dove Circle^
         Austin, Texas  78758^^
         E-Mail: chris@@0064gnu.ai.mit.edu, nystrom@@0064cactus.org,
         or ccn@@0064cfi.org^^";

  print "The original Super Star Trek game comes from the book ~BASIC
         Computer Games~ edited by David Ahl of Creative Computing fame. It
         was published in 1978 by Workman Publishing, 1 West 39 Street,
         New York, New York, and the ISBN is: 0-89489-052-3.^^";

  print "Here is the original BASIC header:^^";

  print "SUPER STARTREK - MAY 16, 1978 - REQUIRES 24K MEMORY^^";

  print "      **** STAR TREK ****^";

  print "SIMULATION OF A MISSION OF THE STARSHIP ENTERPRISE,^";
  print "AS SEEN ON THE STAR TREK TV SHOW.^";
  print "ORIGINAL PROGRAM BY MIKE MAYFIELD, MODIFIED VERSION^";
  print "PUBLISHED IN DEC'S ~101 BASIC GAMES~, BY DAVE AHL.^";
  print "MODIFICATIONS TO THE LATTER (PLUS DEBUGGING) BY BOB^";
  print "LEEDOM - APRIL & DECEMBER 1974,^";
  print "WITH A LITTLE HELP FROM HIS FRIENDS . . .^";
  print "COMMENTS, EPITHETS, AND SUGGESTIONS SOLICITED --^";
  print "SEND TO:  R. C. LEEDOM^";
  print "          WESTINGHOUSE DEFENSE & ELECTRONICS SYSTEMS CNTR.^";
  print "          BOX 746, M.S. 338^";
  print "          BALTIMORE, MD  21203^^";

  print "CONVERTED TO MICROSOFT 8 K BASIC 3/16/78 BY JOHN BORDERS^";
  print "LINE NUMBERS FROM VERSION STREK7 OF 1/12/75 PRESERVED AS^";
  print "MUCH AS POSSIBLE WHILE USING MULTIPLE STATMENTS PER LINE^^";
];