💾 Archived View for thrig.me › blog › 2022 › 12 › 24 › trek.gmi captured on 2023-11-14 at 08:27:45. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-04-19)

🚧 View Differences

-=-=-=-=-=-=-

Trek

trek is a rather old computer game, 1971, ported to BSD at some point and thus included in OpenBSD by way of /usr/games. A notable design choice for the original was that only a Teletype Model 33 ASR was available, therefore no fancy graphics, nor even the fancy interactive terminal that rogue (1980) eventually used.

My version has some modifications on top of the OpenBSD version.

    $ trek

       * * *   S T A R   T R E K   * * *

                         ------*------
         -------------   `---  ------'
         `-------- --'      / /
                  \\-------  --
                  '-----------'

    Press return to continue.
    What length game: short
    What skill game: fair

    11 Klingons
    3 starbases at 7,0, 7,4, 3,1
    It takes 400 units to kill a Klingon

      -0- -1- -2- -3- -4- -5- -6- -7-
    0 ... ... ... ... ... ... ... ... 0
    1 ... ... ... ... ... ... ... ... 1
    2 ... ... ... ... ... ... ... ... 2
    3 ... .1. ... ... ... ... ... ... 3
    4 ... ... ... ... ... ... ... ... 4
    5 ... ... ... ... ... ... ... ... 5
    6   9   4 ... ... ... ... ... ... 6
    7 $$   5 ... ... .1. ... ... ... 7
      -0- -1- -2- -3- -4- -5- -6- -7-

    Short range sensor scan
      0 1 2 3 4 5 6 7 8 9
    0 . . . . . . . E . . 0   stardate      3700.00
    1 . . . . . . @ . . . 1   condition     GREEN
    2 . . . . . . . . . . 2   position      7,0/0,7
    3 . . . . . . . . . . 3   warp factor   5.0
    4 . . . . . . . . . . 4   total energy  5000
    5 . . . . . . . . . . 5   torpedoes     10
    6   . . . . . . . . . 6   shields       up, 100%
    7 . . . . . . . . . . 7   Klingons left 11
    8 .   . . . . . . . . 8   time left     10.00
    9 . . . # . . . . . . 9   life support  active
      0 1 2 3 4 5 6 7 8 9
    Starsystem Stratos

    Command:

And that's the interface, with the convenience of the long and short range scans automatically being shown. With a line printer, you would be wasting paper to play this. Rumor has it that much paper was wasted playing trek, back in the day.

The point of the game is to go all genocidal on the evil invading Klingons, which might tell you a few things, but perhaps nothing new since at least the Paleozoic.

Intermission

(me, furiously reading the expanded man page I wrote and then completely forgot about)

Second Act

I hope you remember all that Trigonometry you forgot or never learned, because you will probably need it. If you do remember enough of it, congratulations!

We are in a not so good position; the edge of the galaxy only allows us to see three adjacent sectors, all free of evil Klingons (who must be destroyed). There are 11 Klingon ships somewhere in the remaining 61 quadrants. Quadrant 4,1 is probably a good place to warp to, as it is nearby and will reveal nine new sectors.

So how do we get to that sector? Trigonometry. Or, as a luxury, the computer can tell us.

    Command: computer

    Request: course 4,1
    Sector: 4,4
    7,0/0,7 to 4,1/4,4: course 15  dist 2.693

    Command: move 15 2.693

    Uhura:  Captain, we have received a distress signal
      from the starbase in quadrant 3,1.
    Uhura: Starfleet command reports that the starbase in
       quadrant 3,1 has been destroyed

    Command:

Oh well, that starbase might have been nice to visit. We probably should do some scans to see what is around us.

    Command: lrscan
    Long range scan for quadrant 4,1

         0     1     2
      -------------------
    3 !   6 ! 305 !   2 !
      -------------------
    4 !   4 !   8 !   6 !
      -------------------
    5 !   1 !   8 !   5 !
      -------------------

    Command: srscan

    Short range sensor scan
      0 1 2 3 4 5 6 7 8 9
    0 . . . . . * . . . . 0   stardate      3701.08
    1 . . * . . . . . . . 1   condition     GREEN
    2 . @ . . * . * . . . 2   position      4,1/4,4
    3 . . . . . . . . . . 3   warp factor   5.0
    4 . . . . E . . . . . 4   total energy  4426
    5 . . . . . . . . . . 5   torpedoes     10
    6 . . . . . . . . . . 6   shields       up, 100%
    7 . . . . . * . . . . 7   Klingons left 11
    8 . . . . . . . . * . 8   time left     8.92
    9 . . . . * . . . . . 9   life support  active
      0 1 2 3 4 5 6 7 8 9
    Starsystem Prometheus II

    Command:

So that's three Klingons (who must be destroyed) on our northern bow, in the sector where the starbase was.

    Command: warp 7
    Damage to warp engines may occur above warp 6.0

    Command: move 0 1
    Computer reports navigation error; Enterprise stopped at 3,4

    Command:

Whoops, bumped into a star, the one directly north of us. A 45 degree line of a suitable distance can probably take us into quadrant 3,1, sector uh 9,8?

    Command: warp 6

    Command: c m 3,1/9,8
    Condition RED
    Klingon at 4,9 moves to 8,9

    Stardate 3701.25: Klingon attack:
    HIT: 146 units from 8,9, shields absorb 100%, effective hit 292
    HIT: 92 units from 6,1, shields absorb 100%, effective hit 184
    HIT: 71 units from 0,4, shields absorb 100%, effective hit 142

    Command:

There's probably a reason I picked "fair" for the game skill instead of "expert" or "kobayashi maru".

    Command: srscan

    Short range sensor scan
      0 1 2 3 4 5 6 7 8 9
    0 . . . . K . . . . . 0   stardate      3701.25
    1 . . * . . . . . . . 1   condition     RED
    2 . . . . . . . . . . 2   position      3,1/9,8
    3 . . . . . . . . . * 3   warp factor   6.0
    4 . . . . . . . . * . 4   total energy  4513
    5 . . * . . . . . . . 5   torpedoes     10
    6 . K . . . . . . . . 6   shields       up, 100%
    7 . . . * . . . . . . 7   Klingons left 11
    8 . . . . . . . . . K 8   time left     8.75
    9 . . . . . . . . E   9   life support  active
      0 1 2 3 4 5 6 7 8 9

    Command:

The Klingons (who must be destroyed) are pretty spread out. The close one could probably benefit from a torpedo.

    Command: c trajectory
    Klingon at 8,9: course 45  dist 0.141
    Klingon at 6,1: course 293  dist 0.762
    Klingon at 0,4: course 336  dist 0.985

    Command: t
    Torpedo course: 45
    Do you want a burst: n
    Photon tubes misfire
    Torpedo track:
       9.5   8.5
       8.6   7.5
       7.8   6.5
       6.9   5.5
       6.0   4.5
       5.2   3.5
       4.3   2.5
       3.4   1.5
       2.5   0.5
    Torpedo missed

    Command: t
    Torpedo course: 45
    Do you want a burst: n
    Torpedo track:
       9.5   8.5
       8.9   9.5
       *** Klingon at 8,9 destroyed ***

    Command:

Or two torpedoes. The other two Klingons (who must be destroyed) are pretty far away, but are not lined up well for phaser fire, so a next move might be to close in on one of them for the attack.

Anyways, that's the trek main game loop.

Test

Recent postings have concerned testing software--therefore, how can we test trek? A goal is good to have, as that may influence what we test and how we go about it. Say we want to modernize the source code,

    int main(argc, argv)
    int argc;
    char **argv;
    {
        int ch;
        ...

perhaps on account of it using rather old C that modern C compilers might eventually come to hate. A code refactor may break the game in various ways; whether the code still compiles is a test, but may not catch the logic bugs we may introduce: sorting a list the wrong way, doubling damage numbers, things like that.

Improving the code to make it more testable might also be a good goal, though we probably want to study the source code in some detail before that. Same story for adding or changing features; best to have a "lay of the land" in mind. Chesterton's Fence and all that.

We could manually play the game after our changes, but that would be slow, and we might miss something. A program that plays the game seems in order. And next, a means to play the same game seed, so that the Klingons (who must be destroyed) and events play out the same way. If we break something the game state will hopefully diverge from what the test expects to see, and then we can figure out what went awry.

So our first change would be to seed the RNG with the same number, perhaps via a new command line flag or environment variable. Such scaffold code could be pretty messy; it just needs to work. With that in place we play the game and record what happens; from this record tests can be built. The OpenBSD expect package ships with the handy autoexpect program. Expect has been ported to other languages if you are not keen on learning TCL.

    $ autoexpect trek
    autoexpect started, file is script.exp

       * * *   S T A R   T R E K   * * *

                         ------*------
         -------------   `---  ------'
         `-------- --'      / /
                  \\-------  --
                  '-----------'

    Press return to continue.

After some amount of play the script.exp can be adapted into a test framework of sorts--send particular keys, confirm that the output contains what we expect, fail otherwise. Ideally a sufficient portion of the gameplay should be worked through, though this can be added to the test program incrementally as we find Klingons (who must be destroyed), shoot them, and carry out other game actions. Not perfect nor complete, but much better than flying blind over a refactor.

    #!/usr/bin/env expect

    set timeout 1
    match_max 100000
    log_file trek.log

    spawn -noecho trek

    proc okay {name want send} {
        expect {
            {*}$want { send -- $send }
            timeout {
                send_user "FAIL $name\r\n"
                interact
            }
        }
    }

    okay "title screen" "Press return to continue" "\r"
    okay "game len" "What length game" "short\n"
    okay "game skill" "What skill game" "novice\n"

    interact

By dropping to interact on error, or at the end of the tests, the tests may be built up incrementally.

tags #expect #testing #startrek