Checkpoint with several changes, committed so Stas can play with debug code.
[super-star-trek.git] / src / sst.c
index 080a9a01b0224f42870138fce382f97e15eca17f..36f444959238493d6414a44f1ab3b6c9e13671b3 100644 (file)
--- a/src/sst.c
+++ b/src/sst.c
@@ -155,9 +155,13 @@ for a lot of magic numbers and refactored the heck out of it.
 
    5. Half the quadrants now have inhabited planets, from which one 
       cannot mine dilithium (there will still be the same additional number
-      of dilithium-bearing planets).  Right now this is just color, but
-      eventually we'll fold in BSD-Trek-like logic for Klingons to attack
-      and enslave inhabited worlds.
+      of dilithium-bearing planets).  Torpedoing an inhabited world is *bad*.
+      There is BSD-Trek-like logic for Klingons to attack and enslave 
+      inhabited worlds, producing more ships (only is skill is 'good' or 
+      better). (Controlled by OPTION_WORLDS and turned off if game 
+      type is "plain" or "almy".)
+
+   6. User input is now logged so we can do regression testing.
 */
 
 /* the input queue */
@@ -166,10 +170,14 @@ static char line[128], *linep = line;
 struct game game;
 coord thing;
 int iqhere, iqengry;
-int iscore, iskill; // Common PLAQ
+int iscore, iskill;    // Common PLAQ
 double aaitem;
 double perdate;
 char citem[10];
+int seed;              // the random-number seed
+bool idebug;           // debug mode
+bool randready;                // Has the random-number generator initialized?
+FILE *logfp;
 
 char *device[NDEVICES] = {
        "S. R. Sensors",
@@ -270,6 +278,8 @@ commands[] = {
        {"QUIT",        QUIT,           0},
 #define HELP   36
        {"HELP",        HELP,           0},
+#define SEED   37
+       {"SEED",        SEED,           0},
 };
 
 #define NUMCOMMANDS    sizeof(commands)/sizeof(commands[0])
@@ -375,7 +385,7 @@ void enqueue(char *s)
 
 static void makemoves(void) 
 {
-    int i, v = 0;
+    int key, i, v = 0;
     bool hitme;
     clrscr();
     setwnd(message_window);
@@ -437,7 +447,7 @@ static void makemoves(void)
            if (game.ididit) hitme = true;
            break;
        case MOVE:                      // move
-           warp(1);
+           warp(false);
            break;
        case SHIELDS:                   // shields
            doshield(1);
@@ -529,9 +539,7 @@ static void makemoves(void)
            if (game.ididit) hitme = true;
            break;
        case DEBUGCMD:                  // What do we want for debug???
-#ifdef DEBUG
            debugme();
-#endif
            break;
        case MAYDAY:                    // Call for help
            mayday();
@@ -539,20 +547,19 @@ static void makemoves(void)
            break;
        case QUIT:
            game.alldone = 1;           // quit the game
-#ifdef DEBUG
-           if (game.idebug) score();
-#endif
            break;
        case HELP:
-           helpme();   // get help
+           helpme();                   // get help
+           break;
+       case SEED:                      // set random-number seed
+           key = scan();
+           if (key == IHREAL)
+               seed = (int)aaitem;
            break;
        }
        commandhook(commands[i].name, false);
        for (;;) {
            if (game.alldone) break;            // Game has ended
-#ifdef DEBUG
-           if (game.idebug) prout("2500");
-#endif
            if (game.optime != 0.0) {
                events();
                if (game.alldone) break;        // Events did us in
@@ -574,6 +581,7 @@ static void makemoves(void)
        }
        if (game.alldone) break;
     }
+    if (idebug) prout("=== Ending");
 }
 
 
@@ -587,17 +595,23 @@ int main(int argc, char **argv)
     else
        game.options |= OPTION_TTY;
 
-    while ((option = getopt(argc, argv, "t")) != -1) {
+    while ((option = getopt(argc, argv, "tx")) != -1) {
        switch (option) {
        case 't':
            game.options |= OPTION_TTY;
            game.options &=~ OPTION_CURSES;
            break;
+       case 'x':
+           idebug = true;
+           break;
        default:
-           fprintf(stderr, "usage: sst [-t] [startcommand...].\n");
+           fprintf(stderr, "usage: sst [-t] [-x] [startcommand...].\n");
            exit(0);
        }
     }
+    /* where to save the input in case of bugs */
+    logfp = fopen("sst-input.log", "w");
+    setlinebuf(logfp);
 
     randomize();
     iostart();
@@ -609,9 +623,6 @@ int main(int argc, char **argv)
     }
     for(;;) { /* Play a game */
        setwnd(fullscreen_window);
-#ifdef DEBUG
-       prout("INITIAL OPTIONS: %0lx", game.options);
-#endif /* DEBUG */
        clrscr();
        prelim();
        setup(line[0] == '\0');
@@ -702,8 +713,17 @@ double expran(double avrage)
     return -avrage*log(1e-7 + Rand());
 }
 
-double Rand(void) {
-       return rand()/(1.0 + (double)RAND_MAX);
+double Rand(void) 
+{
+    if (!randready) {
+       if (seed == 0)
+           seed = (unsigned)time(NULL);
+       if (logfp)
+           fprintf(logfp, "seed %d\n", seed);
+       srand(seed);
+       randready = true;
+    }
+    return rand()/(1.0 + (double)RAND_MAX);
 }
 
 void iran(int size, int *i, int *j) 
@@ -808,14 +828,13 @@ int isit(char *s)
 
 }
 
-#ifdef DEBUG
 void debugme(void) 
 {
     proutn("Reset levels? ");
     if (ja() != 0) {
-       if (energy < game.inenrg) energy = game.inenrg;
-       shield = game.inshld;
-       torps = game.intorps;
+       if (game.energy < game.inenrg) game.energy = game.inenrg;
+       game.shield = game.inshld;
+       game.torps = game.intorps;
        game.lsupres = game.inlsr;
     }
     proutn("Reset damage? ");
@@ -825,10 +844,10 @@ void debugme(void)
            if (game.damage[i] > 0.0) 
                game.damage[i] = 0.0;
     }
-    proutn("Toggle game.idebug? ");
+    proutn("Toggle debug flag? ");
     if (ja() != 0) {
-       game.idebug = !game.idebug;
-       if (game.idebug) prout("Debug output ON");
+       idebug = !idebug;
+       if (idebug) prout("Debug output ON");
        else prout("Debug output OFF");
     }
     proutn("Cause selective damage? ");
@@ -847,6 +866,8 @@ void debugme(void)
     }
     proutn("Examine/change events? ");
     if (ja() != 0) {
+       event *ev;
+       coord w;
        int i;
        for (i = 1; i < NEVENTS; i++) {
            int key;
@@ -859,13 +880,36 @@ void debugme(void)
            case FCDBAS:  proutn("Base Destroy    "); break;
            case FSCMOVE: proutn("SC Move         "); break;
            case FSCDBAS: proutn("SC Base Destroy "); break;
+           //case FDSPROB:proutn("Probe Move      "); break;
+           case FDISTR:  proutn("Distress Call   "); break;
+           case FENSLV:  proutn("Enlavement      "); break;
+           case FREPRO:  proutn("Klingon Build   "); break;
            }
            proutn("%.2f", scheduled(i)-game.state.date);
            chew();
            proutn("  ?");
            key = scan();
            if (key == IHREAL) {
-               schedule(i, aaitem);
+               ev = schedule(i, aaitem);
+               if (i == FENSLV || i == FREPRO) {
+                   chew();
+                   proutn("In quadrant- ");
+                   key = scan();
+                   if (key != IHREAL) {
+                       prout("Event %d canceled, no y coordinate.", i);
+                       unschedule(i);
+                       continue;
+                   }
+                   w.y = (int)aaitem;
+                   key = scan();
+                   if (key != IHREAL) {
+                       prout("Event %d canceled, no x coordinate.", i);
+                       unschedule(i);
+                       continue;
+                   }
+                   w.x = (int)aaitem;
+                   ev->quadrant = w;
+               }
            }
        }
        chew();
@@ -876,4 +920,3 @@ void debugme(void)
        atover(1);
     }
 }
-#endif