Improvements to the testing machinery, including the replay option.
[super-star-trek.git] / src / sst.c
index 36f444959238493d6414a44f1ab3b6c9e13671b3..7fbbfc2ef558af029e37e827537410314a35ef4f 100644 (file)
--- a/src/sst.c
+++ b/src/sst.c
@@ -176,8 +176,7 @@ 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;
+FILE *logfp, *replayfp;
 
 char *device[NDEVICES] = {
        "S. R. Sensors",
@@ -595,8 +594,20 @@ int main(int argc, char **argv)
     else
        game.options |= OPTION_TTY;
 
-    while ((option = getopt(argc, argv, "tx")) != -1) {
+    seed = (int)time(NULL);
+    while ((option = getopt(argc, argv, "r:tx")) != -1) {
        switch (option) {
+       case 'r':
+           replayfp = fopen(optarg, "r");
+           if (replayfp == NULL) {
+               fprintf(stderr, "sst: can't open replay file %s\n", optarg);
+               exit(1);        
+           }
+           if (fscanf(replayfp, "seed %d\n", &seed) != 1) {
+               fprintf(stderr, "sst: replay file %s is ill-formed\n", optarg);
+               exit(1);        
+           }
+           /* FALL THROUGH */
        case 't':
            game.options |= OPTION_TTY;
            game.options &=~ OPTION_CURSES;
@@ -612,8 +623,10 @@ int main(int argc, char **argv)
     /* where to save the input in case of bugs */
     logfp = fopen("sst-input.log", "w");
     setlinebuf(logfp);
+    fprintf(logfp, "seed %d\n", seed);
+    srand(seed);
 
-    randomize();
+    srand(seed);
     iostart();
 
     line[0] = '\0';
@@ -715,14 +728,6 @@ double expran(double avrage)
 
 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);
 }
 
@@ -871,7 +876,6 @@ void debugme(void)
        int i;
        for (i = 1; i < NEVENTS; i++) {
            int key;
-           if (!is_scheduled(i)) continue;
            switch (i) {
            case FSNOVA:  proutn("Supernova       "); break;
            case FTBEAM:  proutn("T Beam          "); break;
@@ -880,16 +884,26 @@ 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 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);
+           if (is_scheduled(i)) {
+               proutn("%.2f", scheduled(i)-game.state.date);
+               if (i == FENSLV || i == FREPRO) {
+                   ev = findevent(i);
+                   proutn(" in %d-%d", ev->quadrant.x,ev->quadrant.y);
+               }
+           } else
+               proutn("never");
+           proutn("? ");
            chew();
-           proutn("  ?");
            key = scan();
-           if (key == IHREAL) {
+           if (key == 'n') {
+               unschedule(i);
+               chew();
+           } else if (key == IHREAL) {
                ev = schedule(i, aaitem);
                if (i == FENSLV || i == FREPRO) {
                    chew();
@@ -915,7 +929,7 @@ void debugme(void)
        chew();
     }
     proutn("Induce supernova here? ");
-    if (ja() != 0) {
+    if (ja()) {
        game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova = true;
        atover(1);
     }