0

I was recently toying with an idea from my education in computer science, namely that any deterministic algorithm can be expressed with just two control structures: a loop containing a switch. I never doubted it. From a certain point of view, that's what programs look like to the silicon of a CPU. The switch variable is the PC, and the switch case is the instruction at that address. Nevertheless, I decided to play with it.

I decided to use a legacy program I've done a few other things with, namely the original Hunt the Wumpus game from Creative Computing. Look up http://www.atariarchives.org/bcc1/showpage.php?page=247

I've also recoded it in very object-oriented Java. The very is because I found a way to do what amounts to dual polymorphism, on two objects at once, to make the meeting of elements symmetric: the same thing happens whether the player bumps into the Wumpus, or the Wumpus bumps into the player. Maybe I'll post that one.

I must have too much time on my hands. I've done a few other things with this, and more are in the works.

So here's the code, in C. Each line in the original BASIC has become a switch case.

/**
 * @file
 * This is a strict recoding of Gregory Yob's original "Hunt the Wumpus" game
 * into C.  This is done in the peculiar fashion of making a "virtual basic"
 * in the C language.  Sort of.
 *
 * The original can be seen in the Atari archives at
 * http://www.atariarchives.org/bcc1/showpage.php?page=247 
 *
 * This particular approach was inspired by the theory of computation, in which
 * there is a theorem stating that any deterministic algorithm at all can be
 * written using only two control structures:
 * 1) one loop
 * 2) one switch inside the loop
 *
 * I have rewritten the original BASIC, retaining the BASIC in comments, and
 * reducing all of the basic control statements with the loop-switch pair.  The
 * result has to be close to the oddest program I've ever written, in style at
 * least.  But it illustrates a point, and was kinda fun to do.  Once.
 *
 * I have allowed a few additional loops and functions to support the original
 * GOTOs and their targets.   These, too, could be eliminated, but
 * then the relationship to the original BASIC would be lost.
 *
 * I have retained all of the original functionality, including some outputs
 * that are obsolete because they pertain to other available programs in the
 * original environment.  I have also retained the original all-caps form,
 * for the same reason, namely to retain the flavor of the original.  I have
 * created a manifest constant PAD which I define as ": " to create space
 * between questions and their answers.  I find it much easier to read.
 * You can change it most easily by changing the contents in the definition.
 *
 * I do allow inputs in lowercase.  This seems reasonable because the original
 * was all caps only because there was no choice on the input stations of the time.
 *
 * @author Gregory Yob
 * @author Kevin O'Gorman
 * 27 May 2012
 *
 * This re-coding done by Kevin O'Gorman.  No rights reserved.  Have fun.
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <ctype.h>

#define BUFL 1024

/* Purists may want to reduce this to the empty string, but I like it better this way. */
/* This gives space between each prompt and the answer you type.  Commonly not done */
/*     when the original was written, but we've learned better in the meantime, I hope. */
#define PAD ": "

/* Undefine this to disable debugging output */
/* Define this to enable debugging output */
#undef DEBUG

#ifdef DEBUG
    #define PRINT0(f) printf(f)
    #define PRINT1(f,a) printf(f,a)
    #define PRINT2(f,a,b) printf(f,a,b)
    #define PRINT5(f,a,b,c,d,e) printf(f,a,b,c,d,e)
#else
    #define PRINT0(f)
    #define PRINT1(f,a)
    #define PRINT2(f,a,b)
    #define PRINT5(f,a,b,c,d,e)
#endif

/* ALL basic variables were global */

/* this is used in the simulation of BASIC control structures.  Not essential to
 * the program at all, but removing it would lose the connection to the original
 * line numbers.
 */
int lines[] = { 10, 15, 20, 30, 40, 50, 52, 54, 56, 58, 60, 62, 64, 66, 67,
    68, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210,
    220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360,
    365, 370, 375, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490,
    500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 1000, 1010,
    1020, 1030, 1040, 1050, 1060, 1070, 1080, 1090, 1100, 1110, 1120, 1130, 1140,
    1150, 1160, 1170, 1180, 1190, 1200, 1210, 1220, 1230, 1240, 1250, 1260, 1270,
    1280, 1290, 1300, 1310, 1320, 1330, 1340, 1350, 1360, 1370, 1380, 1390, 1400,
    1410, 2000, 2010, 2020, 2030, 2040, 2050, 2060, 2070, 2080, 2090, 2100, 2110,
    2120, 2130, 2140, 2150, 2500, 2510, 2520, 2530, 2540, 2550, 2560, 2570, 2580,
    3000, 3010, 3020, 3030, 3040, 3050, 3060, 3070, 3080, 3090, 3095, 3100, 3105,
    3110, 3115, 3120, 3130, 3140, 3150, 3160, 3170, 3180, 3190, 3200, 3210, 3220,
    3230, 3240, 3250, 3255, 3260, 3270, 3280, 3290, 3295, 3300, 3310, 3320, 3330, 3340,
    3350, 3360, 3370, 3380, 3390, 3400, 3410, 3420, 3430, 3440, 4000, 4010, 4020,
    4030, 4040, 4050, 4060, 4070, 4080, 4090, 4100, 4110, 4120, 4130, 4140, 4150,
    4160, 4170, 4180, 4190, 4200, 4210, 4220, 4230, 4240, 4250, 4260, 4270, 4280,
    4290, 4300, 4310, 5000, 9999};
int climit;
int Bthis, Cthis;
int Bnext, Cnext;
int FNret, FNval;
int stack[100];
int sp=0;

/* Arrays in  Basic start at index 1 */
/* Data here comes from line 130 */
int S[21][4] = {{0,0,0,0},/* there is no room zero */
        {0,2,5,8},{0,1,3,10},{0,2,4,12},{0,3,5,14},{0,1,4,6},{0,5,7,15},{0,6,8,17},
        {0,1,7,9},{0,8,10,18},{0,2,9,11},{0,10,12,19},{0,3,11,13},{0,12,14,20},{0,4,13,15},{0,6,14,16},
        {0,15,17,20},{0,7,16,18},{0,9,17,19},{0,11,18,20},{0,13,16,19}};
int L[7], M[7];
int P[6];
/* Basic variables */
int vA;
int vJ;
int vK;
int vL;
int vF;
int vJ9;
int vK1;
int vO;

void then(int basicLine) {
  int cLine;
  for (cLine = 0; cLine < climit; cLine++) {
    if (lines[cLine] == basicLine) {
      Cnext = cLine;
      break;
    }
  }
  if (lines[Cnext] != basicLine) {
    fprintf(stderr, "NEVER HAPPEN: cannot find Basic line %04d from %04d\n", basicLine, Bnext);
    exit(1);
  }
  Bnext = basicLine;
}

void gosub(int basicLine) {
  stack[sp++] = Bnext;
  PRINT2("GOSUB stack pointer: %d; will return to %d\n", sp, Bnext);
  then(basicLine);
}

void basicReturn() {
  then(stack[--sp]);
  PRINT1("Returning to %d\n", stack[sp]);
}

int
main(int argc, char **argv) {
  climit = sizeof(lines) / sizeof(lines[0]);
  int done = 0;
  char Idollar[BUFL];
  char *bufp;

  Cthis = 0;
  do {
    Bthis = lines[Cthis];
    Cnext = Cthis + 1;
    Bnext = lines[Cnext];
    switch(Bthis) {
    case 10: /* REM- HUNT THE WUMPUS */
        break;
    case 15: /* REM:  BY GREGORY YOB */
        break;
    case 20: /* PRINT "INSTRUCTIONS (Y-N)"; */
        printf("INSTRUCTIONS (Y-N)" PAD);
        break;
    case 30: /* INPUT I$ */
        bufp = fgets(Idollar, BUFL, stdin);
        if (!bufp) {
          fprintf(stderr, "\nUnusual end from fgets()\n");
          exit(EXIT_FAILURE);
        }
        break;
    case 40: /* IF I$="N" THEN 52 */
        if (strcasecmp(Idollar, "N\n") == 0) { then(52); }
        break;
    case 50: /* GOSUB 1000 */
        gosub(1000);
        break;
    case 52: /* REM- ANNOUNCE WUMPUSII FOR ALL AFICIONADOS ... ADDED BY DAVE */
        break;
    case 54: /* PRINT */
        printf("\n");
        break;
    case 56: /* PRINT "     ATTENTION ALL WUMPUS LOVERS!!!" */
        printf("%s\n", "     ATTENTION ALL WUMPUS LOVERS!!!");
        break;
    case 58: /* PRINT "     THERE ARE NOW TWO ADDITIONS TO THE WUMPUS FAMILY"; */
        printf("%s\n", "     THERE ARE NOW TWO ADDITIONS TO THE WUMPUS FAMILY");
        break;
    case 60: /* PRINT " OF PROGRAMS." */
        printf("%s\n", " OF PROGRAMS.");
        break;
    case 62: /* PRINT */
        printf("\n");
        break;
    case 64: /* PRINT "     WUMP2:  SOME DIFFERENT CAVE ARRANGEMENTS" */
        printf("%s\n", "     WUMP2:  SOME DIFFERENT CAVE ARRANGEMENTS");
        break;
    case 66: /* PRINT "     WUMP3:  DIFFERENT HAZARDS" */
        printf("%s\n", "     WUMP3:  DIFFERENT HAZARDS");
        break;
    case 67: /* PRINT */
        printf("\n");
        break;
    case 68: /* REM- SET UP CAVE (DODECAHEDRAL NODE LIST" */
        break;
    case 70: /* DIM S(30,3) */
        break;
    case 80: /*  FOR J=1 TO 20 */
        break;
    case 90: /*   FOR K=1 TO 3 */
        break;
    case 100: /*   READ S(J,K) */
        break;
    case 110: /*   NEXT K */
        break;
    case 120: /*  NEXT J */
        break;
              /* Array S is created above */
    case 130: /* DATA 2,5,8,1,3,10,2,4,12,3,5,14,1,4,6 */
        break;
    case 140: /* DATA 5,7,15,6,8,17,1,7,9,8,10,18,2,9,11 */
        break;
    case 150: /* DATA 10,12,19,3,11,13,12,14,20,4,13,15,6,14,16 */
        break;
    case 160: /* DATA 15,17,20,7,16,18,9,17,19,11,18,20,13,16,19 */
        break;

/* effectively in-lines these, so they're not really control structures */
#define FNA(x) ((int)(20.0 * drand48()) + 1)
    case 170: /* DEF FNA(X)=INT(20*RND(0))+1 */
        break;
#define FNB(x) ((int)(3.0 * drand48()) + 1)
    case 180: /* DEF FNB(X)=INT(3*RND(0))+1 */
        break;
#define FNC(x) ((int)(4.0 * drand48()) + 1)
    case 190: /* DEF FNC(X)=INT(4*RND(0))+1 */
        break;


    case 200: /* REM-LOCATGE L ARRAY ITEMS */
        break;
    case 210: /* REM-1-YOU,2-WUMPUS,3&4-PITS,5&6-BATS */
        break;
    case 220: /* DIM L(6) */
        break;
    case 230: /* DIM M(6) */
        break;
    case 240: /*  FOR J=1 TO 6 */
        vJ = 1;
        break;
    case 250: /*  L(J)=FNA(0) */
        L[vJ] = FNA(0);
        break;
    case 260: /*  M(J)=L(J) */
        M[vJ] = L[vJ];
        break;
    case 270: /*  NEXT J */
        if (++vJ <= 6) {then(250);}
        break;
    case 280: /* REM-CHECK FOR CROSSOVERS (IE L(1)=L(2),ETC) */
        break;
    case 290: /*  FOR J=1 TO 6 */
        vJ = 1;
        break;
    case 300: /*   FOR K=J TO 6 */
        vK = 1;
        break;
    case 310: /*   IF J=K THEN 330 */
        if (vJ == vK) { then(330); }
        break;
    case 320: /*   IF L(J)=L(K) THEN 240 */
        if (L[vJ] == L[vK]) { then(240); }
        break;
    case 330: /*   NEXT K */
        if (++vK <= 6) {then(310);}
        break;
    case 340: /*  NEXT J */
        if (++vJ<= 6) {then(300);}
        break;
    case 350: /* REM-SET# ARROWS */
        break;
    case 360: /* A=5 */
        vA = 5;
        break;
    case 365: /* L=L(1) */
        vL = L[1];
        break;
    case 370: /* REM-RUN THE GAME */
        break;
    case 375: /* PRINT "HUNT THE WUMPUS" */
        printf("%s\n", "HUNT THE WUMPUS");
        break;
    case 380: /* REM-HAZARD WARNINGS & LOCATION */
        break;
    case 390: /* GOSUB 2000 */
        gosub(2000);
        break;
    case 400: /* REM-MOVE OR SHOOT */
        break;
        gosub(2500);
    case 410: /* GOSUB 2500 */
        break;
    case 420: /* GOTO O OF 440,480 */
        switch(vO) {
        case 1: then(440); break;
        case 2: then(480); break;
        default: fprintf(stderr, "NEVER HAPPEN: vO not 1 or 2 (%d)\n", vO); exit(EXIT_FAILURE);
        }
        break;
    case 430: /* REM-SHOOT */
        break;
    case 440: /* GOSUB 3000 */
        gosub(3000);
        break;
    case 450: /* IF F=0 THEN 390 */
        PRINT1("Back from shooting.  F=%d\n", vF);
        if (vF==0) {then(390);}
        break;
    case 460: /* GOTO 500 */
        then(500);
        break;
    case 470: /* REM-MOVE */
        break;
    case 480: /* GOSUB 4000 */
        gosub(4000);
        break;
    case 490: /* IF F=0 THEN 390 */
        if (vF == 0) {then(390);}
        break;
    case 500: /* IF F>0 THEN 550 */
        if (vF>0) {then(550);}
        break;
    case 510: /* REM-LOSE */
        break;
    case 520: /* PRINT "HA HA HA - YOU LOSE!" */
        printf("%s\n", "HA HA HA - YOU LOSE!");
        break;
    case 530: /* GOTO 560 */
        then(560);
        break;
    case 540: /* REM-WIN */
        break;
    case 550: /* PRINT "HEE HEE HEE - THE WUMPUS'LL GETCHA NEXT TIME!!" */
        printf("%s\n", "HEE HEE HEE - THE WUMPUS'LL GETCHA NEXT TIME!!");
        break;
    case 560: /*  FOR J=1 TO 6 */
        vJ = 1;
        break;
    case 570: /*  L(J)=M(J) */
        L[vJ] = M[vJ];
        break;
    case 580: /*  NEXT J */
        if (++vJ <= 6) { then(570); }
        break;
    case 590: /* PRINT "SAME SET-UP (Y-N)"; */
        printf("%s", "SAME SET-UP (Y-N)" PAD);
        break;
    case 600: /* INPUT I$ */
        bufp = fgets(Idollar, BUFL, stdin);
        if (!bufp) {
          fprintf(stderr, "\nUnusual end from fgets()\n");
          exit(EXIT_FAILURE);
        }
        break;
    case 610: /* IF I$#"Y" THEN 240 */
        if (strcasecmp(Idollar, "Y\n") != 0) {then(240);}
        break;
    case 620: /* GOTO 360 */
        then(360);
        break;
    case 1000: /* REM-INSTRUCTIONS */
        break;
    case 1010: /* PRINT "WELCOME TO 'HUNT THE WUMPUS'" */
        printf("%s\n", "WELCOME TO 'HUNT THE WUMPUS'");
        break;
    case 1020: /* PRINT "  THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM" */
        printf("%s\n", "  THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM");
        break;
    case 1030: /* PRINT "HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A" */
        printf("%s\n", "HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A");
        break;
    case 1040: /* PRINT "DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW" */
        printf("%s\n", "DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW");
        break;
    case 1050: /* PRINT "WHAT A DODECAHEDRON IS, ASK SOMEONE)" */
        printf("%s\n", "WHAT A DODECAHEDRON IS, ASK SOMEONE)");
        break;
    case 1060: /* PRINT */
        printf("\n");
        break;
    case 1070: /* PRINT "     HAZARDS:" */
        printf("%s\n", "     HAZARDS:");
        break;
    case 1080: /* PRINT " BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM" */
        printf("%s\n", " BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM");
        break;
    case 1090: /* PRINT "     IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)" */
        printf("%s\n", "     IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)");
        break;
    case 1100: /* PRINT " SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS.  IF YOU" */
        printf("%s\n", " SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS.  IF YOU");
        break;
    case 1110: /* PRINT "     GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER" */
        printf("%s\n", "     GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER");
        break;
    case 1120: /* PRINT "     ROOM AT RANDOM. (WHICH MIGHT BE TROUBLESOME)" */
        printf("%s\n", "     ROOM AT RANDOM. (WHICH MIGHT BE TROUBLESOME)");
        break;
    case 1130: /* PRINT */
        printf("\n");
        break;
    case 1140: /* PRINT "     WUMPUS:" */
        printf("%s\n", "     WUMPUS:");
        break;
    case 1150: /* PRINT " THE WUMPUS IS NOT BOTHERED BY THE HAZARDS (HE HAS SUCKER" */
        printf("%s\n", " THE WUMPUS IS NOT BOTHERED BY THE HAZARDS (HE HAS SUCKER");
        break;
    case 1160: /* PRINT " FEET AND IS TOO BIG FOR A BAT TO LIFT).  USUALLY" */
        printf("%s\n", " FEET AND IS TOO BIG FOR A BAT TO LIFT).  USUALLY");
        break;
    case 1170: /* PRINT " HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOUR ENTERING" */
        printf("%s\n", " FEET AND IS TOO BIG FOR A BAT TO LIFT).  USUALLY");
        break;
    case 1180: /* PRINT " HIS ROOM OR YOUR SHOOTING AN ARROW." */
        printf("%s\n", " HIS ROOM OR YOUR SHOOTING AN ARROW.");
        break;
    case 1190: /* PRINT "     IF THE WUMPUS WAKES, HE MOVES (P=.75) ONE ROOM" */
        printf("%s\n", "     IF THE WUMPUS WAKES, HE MOVES (P=.75) ONE ROOM");
        break;
    case 1200: /* PRINT " OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU" */
        printf("%s\n", " OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU");
        break;
    case 1210: /* PRINT " ARE, HE EATS YOU UP (& YOU LOSE!)" */
        printf("%s\n", " ARE, HE EATS YOU UP (& YOU LOSE!)");
        break;
    case 1220: /* PRINT */
        printf("\n");
        break;
    case 1230: /* PRINT "     YOU:" */
        printf("%s\n", "     YOU:");
        break;
    case 1240: /* PRINT " EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW" */
        printf("%s\n", " EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW");
        break;
    case 1250: /* PRINT "   MOVING: YOU CAN GO ONE ROOM (THRU ONE TUNNEL)" */
        printf("%s\n", "   MOVING: YOU CAN GO ONE ROOM (THRU ONE TUNNEL)");
        break;
    case 1260: /* PRINT "   ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT." */
        printf("%s\n", "   ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT.");
        break;
    case 1270: /* PRINT "   EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING" */
        printf("%s\n", "   EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING");
        break;
    case 1280: /* PRINT "   THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO." */
        printf("%s\n", "   THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO.");
        break;
    /* spelling errors from the original */
    case 1290: /* PRINT "   IF THE ARROG CAN'T GO DHAT WAY(IE NO TUNNEL) IT MOFES" */
        printf("%s\n", "   IF THE ARROG CAN'T GO DHAT WAY(IE NO TUNNEL) IT MOFES");
        break;
    case 1300: /* PRINT "   AT RANDOM TO THE NEXT ROOM." */
        printf("%s\n", "   AT RANDOM TO THE NEXT ROOM.");
        break;
    case 1310: /* PRINT "     IF THE ARROW HITS THE WUMPUS, YOU WIN." */
        printf("%s\n", "     IF THE ARROW HITS THE WUMPUS, YOU WIN.");
        break;
    case 1320: /* PRINT "     IF THE ARROW HITS YOU, YOU LOSE." */
        printf("%s\n", "     IF THE ARROW HITS YOU, YOU LOSE.");
        break;
    case 1330: /* PRINT */
        printf("\n");
        break;
    case 1340: /* PRINT "    WARNINGS:" */
        printf("%s\n", "    WARNINGS:");
        break;
    case 1350: /* PRINT "     WHEN YOU ARE ONE ROOM AWAY FROM WUMPUS OR HAZARD," */
        printf("%s\n", "     WHEN YOU ARE ONE ROOM AWAY FROM WUMPUS OR HAZARD,");
        break;
    case 1360: /* PRINT "    THE COMPUTER SAYS:" */
        printf("%s\n", "    THE COMPUTER SAYS:");
        break;
    case 1370: /* PRINT " WUMPUS-  'I SMELL A WUMPUS'" */
        printf("%s\n", " WUMPUS-  'I SMELL A WUMPUS'");
        break;
    case 1380: /* PRINT " BAT   -  'BATS NEARBY'" */
        printf("%s\n", " BAT   -  'BATS NEARBY'");
        break;
    case 1390: /* PRINT " PIT   -  'I FEEL A DRAFT'" */
        printf("%s\n", " PIT   -  'I FEEL A DRAFT'");
        break;
    case 1400: /* PRINT "" */
        printf("\n");
        break;
    case 1410: /* RETURN */
        basicReturn();
        break;
    case 2000: /* REM-PRINT LOCATION & HAZARD WARNINGS */
        break;
    case 2010: /* PRINT */
        printf("\n");
        break;
    case 2020: /*  FOR J=2 TO 6 */
        vJ = 2;
        break;
    case 2030: /*   FOR K=1 TO 3 */
        vK = 1;
        break;
    case 2040: /*   IF S(L(1),K)#L(J) THEN 2110 */
        if (S[L[1]][vK] != L[vJ]) {then(2110);}
        break;
    case 2050: /*   GOTO J-1 OF 2060,2080,2100,2100 */
        switch (vJ - 1) {
        case 1: then(2060); break;
        case 2: then(2080); break;
        case 3: then(2080); break;
        case 4: then(2100); break;
        case 5: then(2100); break;
        default:
                printf("NEVER HAPPEN: J is not in 2-6 (%d)\n", vJ);
                exit(EXIT_FAILURE);
        }
        break;
    case 2060: /*   PRINT "I SMELL A WUMPUS!" */
        PRINT1("%d\n", L[vJ]);
        printf("%s\n","I SMELL A WUMPUS!");
        break;
    case 2070: /*   GOTO 2110 */
        then(2110);
        break;
    case 2080: /*   PRINT "I FEEL A DRAFT" */
        PRINT1("%d\n", L[vJ]);
        printf("%s\n", "I FEEL A DRAFT");
        break;
    case 2090: /*   GOTO 2110 */
        then(2110);
        break;
    case 2100: /*   PRINT "BATS NEARBY!" */
        PRINT1("%d\n", L[vJ]);
        printf("%s\n", "BATS NEARBY!");
        break;
    case 2110: /*   NEXT K */
        if (++vK <= 3) { then(2040); }
        break;
    case 2120: /*  NEXT J */
        if (++vJ <= 6) { then(2030); }
        break;
    case 2130: /* PRINT "YOU ARE IN ROOM "L(1) */
        printf("%s  %d\n", "YOU ARE IN ROOM", L[1]);
        break;
    case 2140: /* PRINT "TUNNELS LEAD TO "S(L,1);S(L,2);S(L,3) */
        printf("TUNNELS LEAD TO %2d%6d%6d\n", S[vL][1], S[vL][2], S[vL][3]);
        break;
    case 2150: /* PRINT */
        printf("\n");
        break;
    case 2500: /* REM-CHOSE OPTION */
        break;
    case 2510: /* PRINT "SHOOT OR MOVE (S-M)"; */
        printf("SHOOT OR MOVE (S-M)" PAD);
        break;
    case 2520: /* INPUT I$ */
        bufp = fgets(Idollar, BUFL, stdin);
        if (!bufp) {
          fprintf(stderr, "\nUnusual end from fgets()\n");
          exit(EXIT_FAILURE);
        }
        break;
    case 2530: /* IF I$#"S" THEN 2560 */
        if (strcasecmp(Idollar, "S\n") != 0) { then(2560);};
        break;
    case 2540: /* O=1 */
        vO = 1;
        break;
    case 2550: /* RETURN */
        basicReturn();
        break;
    case 2560: /* IF I$#"M" THEN 2510 */
        if (strcasecmp(Idollar, "M\n") != 0) { then(2510);};
        break;
    case 2570: /* O=2 */
        vO = 2;
        break;
    case 2580: /* RETURN */
        basicReturn();
        break;
    case 3000: /* REM-ARROW ROUTINE */
        break;
    case 3010: /* F=0 */
        PRINT0("3010 sets F=0\n");
        vF = 0;
        break;
    case 3020: /* REM-PATH OF ARROW */
        break;
    case 3030: /* DIM P(5) */
        break;
    case 3040: /* PRINT "NO. OF ROOMS(1-5)"; */
        printf("NO. OF ROOMS(1-5)" PAD);
        break;
    case 3050: /* INPUT J9 */
        bufp = fgets(Idollar, BUFL, stdin);
        if (!bufp) {
          fprintf(stderr, "\nUnusual end from fgets()\n");
          exit(EXIT_FAILURE);
        }
        vJ9 = atoi(Idollar);
        PRINT1("vJ9 = %d\n", vJ9);
        break;
    case 3060: /* IF J9<1 OR J9>5 THEN 3040 */
        if (vJ9 < 1 || vJ9 > 5) { then(3040); }
        break;
    case 3070: /*  FOR K=1 TO J9 */
        vK = 1;
        break;
    case 3080: /*  PRINT "ROOM #"; */
        PRINT1("vK = %d\n", vK);
        printf("ROOM #" PAD);
        break;
    case 3090: /*  INPUT P(K) */
        bufp = fgets(Idollar, BUFL, stdin);
        if (!bufp) {
          fprintf(stderr, "\nUnusual end from fgets()\n");
          exit(EXIT_FAILURE);
        }
        P[vK] = atoi(Idollar);
        break;
    case 3095: /*  IF K <= 2 THEN 3115 */
        if (vK <= 2) { then(3115);}
        break;
    case 3100: /*  IF P(K) <> P(K-2) THEN 3115 */
        if (P[vK] != P[vK - 2] ) { then(3115); }
        break;
    case 3105: /*  PRINT "ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM" */
        printf("%s\n", "ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM");
        break;
    case 3110: /*  GOTO 3080 */
        then(3080);
        break;
    case 3115: /*  NEXT K */
        if (++vK <= vJ9) { then(3080);}
        PRINT2("Indexing %d up to %d\n", vK, vJ9);
        break;
    case 3120: /* REM-SHOOT ARROW */
        PRINT0("Indexing ends.\n");
        break;
    case 3130: /* L=L(1) */
        vL = L[1];
        break;
    case 3140: /*  FOR K=1 TO J9 */
        vK = 1;
        break;
    case 3150: /*   FOR K1=1 TO 3 */
        vK1 = 1;
        break;
    case 3160: /*   IF S(L,K1)=P(K) THEN 3295 */
        PRINT5("S[%d][%d](%d) : P[%d](%d)\n",vL, vK1, S[vL][vK1], vK, P[vK]);
        if (S[vL][vK1] == P[vK]) { then(3295); }
        break;
    case 3170: /*   NEXT K1 */
        PRINT0("   No match.\n");
        if (++vK1 <= 3) { then(3160); }
        break;
    case 3180: /*  REM-NO TUNNEL FOR ARROW */
        PRINT0("No tunnel for arrow.\n");
        break;
    case 3190: /*  L=S(L, FNB(1)) */
        vL = S[vL][FNB(0)];
        break;
    case 3200: /*  GOTO 3300 */
        then(3300);
        break;
    case 3210: /*  NEXT K */
        if (++vK <= vJ9) { then(3150);}
        break;
    case 3220: /* PRINT "MISSED" */
        printf("%s\n", "MISSED");
        break;
    case 3230: /* REM-MOVE WUMPUS */
        break;
    case 3240: /* GOSUB 3370 */
        gosub(3370);
        break;
    case 3250: /* REM-AMMO CHECK */
        break;
    case 3255: /* A=A-1 */
        vA--;
        break;
    case 3260: /* IF A>0 THEN 3280 */
        if (vA > 0) { then(3280);}
        break;
    case 3270: /* F=-1 */
        PRINT0("3270 sets F=-1\n");
        vF = -1;
        break;
    case 3280: /* RETURN */
        basicReturn();
        break;
    case 3290: /* REM-SEE IF ARROW IS AT L(1) OR L(2) */
        break;
    case 3295: /* L=P(K) */
        vL = P[vK];
        break;
    case 3300: /* IF L#L(2) THEN 3340 */
        if (vL != L[2]) { then(3340);}
        break;
    case 3310: /* PRINT "AHA! YOU GOT THE WUMPUS!" */
        printf("%s\n", "AHA! YOU GOT THE WUMPUS!");
        break;
    case 3320:
        PRINT0("3320 sets F=1\n");
        vF = 1;
        break;
    case 3330: /* RETURN */
        basicReturn();
        break;
    case 3340: /* IF L#L(1) THEN 3210 */
        if (vL != L[1]) { then(3210);}
        break;
    case 3350: /* PRINT "OUCH! ARROW GOT YOU!" */
        printf("%s\n", "OUCH! ARROW GOT YOU!");
        break;
    case 3360: /* GOTO 3270 */
        then(3270);
        break;
    case 3370: /* REM-MOVE WUMPUS ROUTINE */
        break;
    case 3380: /* K=FNC(0) */
        vK = FNC(0);
        break;
    case 3390: /* IF K=4 THEN 3410 */
        if (vK == 4) { then(3410);}
        break;
    case 3400: /* L(2)=S(L(2),K) */
        L[2] = S[L[2]][vK];
        break;
    case 3410: /* IF L(2)#L THEN 3440 */
        if (L[2] != vL) { then(3440);}
        break;
    case 3420: /* PRINT "TSK TSK TSK- WUMPUS GOT YOU!" */
        printf("%s\n", "TSK TSK TSK- WUMPUS GOT YOU!");
        break;
    case 3430: /* F=-1 */
        PRINT0("3430 sets F=-1\n");
        vF = -1;
        break;
    case 3440: /* RETURN */
        basicReturn();
        break;
    case 4000: /* REM- MOVE ROUTINE */
        break;
    case 4010: /* F=0 */
        PRINT0("4010 sets F=0\n");
        vF = 0;
        break;
    case 4020: /* PRINT "WHERE TO"; */
        printf("WHERE TO" PAD);
        break;
    case 4030: /* INPUT L */
        bufp = fgets(Idollar, BUFL, stdin);
        if (!bufp) {
          fprintf(stderr, "\nUnusual end from fgets()\n");
          exit(EXIT_FAILURE);
        }
        vL = atoi(Idollar);
        break;
    case 4040: /* IF L<1 OR L>20 THEM 4020 */
        if (vL < 1 || vL > 20) { then(4020);}
        break;
    case 4050: /*  FOR K=1 TO 3 */
        vK = 1;
        break;
    case 4060: /*  REM- CHECK IF LEGAL MOVE */
        break;
    case 4070: /*  IF S(L(1),K)=L THEN 4130 */
        if (S[L[1]][vK] == vL) { then(4130);}
        break;
    case 4080: /*  NEXT K */
        if (++vK <= 3) { then(4060);}
        break;
    case 4090: /* IF L=L(1) THEN 4130 */
        if (vL == L[1]) { then(4130);}
        break;
    case 4100: /* PRINT "NOT POSSIBLE -"; */
        printf("NOT POSSIBLE -");
        break;
    case 4110: /* GOTO 4020 */
        then(4020);
        break;
    case 4120: /* REM-CHECK FOR HAZARDS */
        break;
    case 4130: /* L(1)=L */
        L[1] = vL;
        break;
    case 4140: /* REM-WUMPUS */
        break;
    case 4150: /* IF L#L(2) THEN 4220 */
        if (vL != L[2]) { then(4220); }
        break;
    case 4160: /* PRINT "... OOPS! BUMPED A WUMPUS!" */
        printf("%s\n", "... OOPS! BUMPED A WUMPUS!");
        break;
    case 4170: /* REM-MOVE WUMPUS */
        break;
    case 4180: /* GOSUB 3380 */
        gosub(3380);
        break;
    case 4190: /* IF F=0 THEN 4220 */
        if (vF == 0) { then(4220);}
        break;
    case 4200: /* RETURN */
        basicReturn();
        break;
    case 4210: /* REM-PIT */
        break;
    case 4220: /* IF L#L(3) AND L#L(4) THEN 4270 */
        if (vL != L[3] && vL != L[4]) { then(4270);}
        break;
    case 4230: /* PRINT "YYIIIIEEEE . . . FELL IN PIT" */
        printf("%s\n", "YYIIIIEEEE . . . FELL IN PIT");
        break;
    case 4240: /* F=-1 */
        PRINT0("4240 sets F=-1\n");
        vF = -1;
        break;
    case 4250: /* RETURN */
        basicReturn();
        break;
    case 4260: /* REM-BATS */
        break;
    case 4270: /* IF L#L(5) AND L#L(6) THEN 4310 */
        if (vL != L[5] && vL != L[6]) { then(4310);}
        break;
    case 4280: /* PRINT "ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!" */
        printf("%s\n", "ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!");
        break;
    case 4290: /* L=FNA(1) */
        vL = FNA(1);
        break;
    case 4300: /* GOTO 4130 */
        then(4130);
        break;
    case 4310: /* RETURN */
        basicReturn();
        break;
    case 5000: /* END */
        done = 1;
        break;
    default:
        fprintf(stderr, "NEVER HAPPEN: line %04d\n", Bthis);
        exit(1);
    }
    Cthis = Cnext;
  } while (!done);
  printf("Oops.  Fell off the end of the world.\n");
  return EXIT_SUCCESS;
}
2
Contributors
2
Replies
3
Views
5 Years
Discussion Span
Last Post by kogorman
0

I do not get the idea of code as switch statement is a advanced control structure, compared to flags and jumps in machine level, not to talk about Turing machine. Could you state exactly the sourch of theory you refer?

0

Sorry, I cannot cite a source. I think this was an 'aside' comment by one of my professors and I do not even recall which one.

I would never call this form of code advanced. Instead it is interesting that it is sufficient, somewhat like a Turing machine. As an undergraduate around 1962, I was writing turing machine code because it was so odd to find you could do anything with such a primitive tool that you could do with the most advanced.

Of course, there's nothing at all efficient, elegant or advanced about it.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.