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