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;
}

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?

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.