Hunt the Wumpus

Since retro gaming seems to be all the rage on PIs I thought I’d try some vintage BASIC computer games. While psBASIC is great for many things including translating CSV bank reconciliation files, mining data from Apache logs and automating tasks with other CLI oriented tools, I thought I’d take a whack at running the “Hunt the Wumpus” game with it.

Growing up with the TRS-80 model 1 I was given a copy of the “BASIC Computer Games” from Creative Computing. I typed in many of those games. But in those early years saving and loading from cassettes was iffy at best. I must have lost about 75% of what I typed in. I think I lost “Super Star Trek” at least a dozen times before I managed to get one to stick on cassette. Thank heaven for floppies!

I wanted to try a smaller game to begin with. And several years back I translated “Super Star Trek” to FreePascal, making a Linux terminal version with some enhancements, including: color and added difficulty. So I wanted to try something new to me. I chased down the source to “wumpus”. Its actually available many places, including the Atari archives.

The biggest problem I’ve seen with these historic archives of BASIC programs is that it seems they are all OCR’d from scanned listings. There are usually a number of scan+OCR gaffs to chase and fix. But Wumpus is small and it seemed there was only one mistranslation, which was easily fixed with S&R.

Here’s a patch of changes I made:

--- wumpus1.bas	2024-10-29 14:50:05.631744515 -0700
+++ wumpus3.bas	2024-10-29 15:15:18.509937884 -0700
@@ -24,9 +24,9 @@
-0170  DEF FNA(X)=INT(20*RND(0))+1
-0180  DEF FNB(X)=INT(3*RND(0))+1
-0190  DEF FNC(X)=INT(4*RND(0))+1
+0170  FUNCTION FNA(X) : FNA=INT(20*RND(0))+1 : END FUNCTION
+0180  FUNCTION FNB(X) : FNB=INT(3*RND(0))+1 : END FUNCTION
+0190  FUNCTION FNC(X) : FNC=INT(4*RND(0))+1 : END FUNCTION
@@ -51,7 +51,7 @@
-0420  GOTO O OF 440,480
+0420  ON O GOTO 440,480
@@ -70,7 +70,7 @@
-0610  IF I$#"Y" THEN 240
+0610  IF I$<>"Y" THEN 240
@@ -118,8 +118,8 @@
-2040    IF S(L(1),K)#L(J) THEN 2110
+2040    IF S(L(1),K)<>L(J) THEN 2110
-2050    GOTO J-1 OF 2060,2080,2080,2100,2100
+2050    ON J-1 GOTO 2060,2080,2080,2100,2100
@@ -134,10 +134,10 @@
-2530  IF I$#"S" THEN 2560
+2530  IF I$<>"S" THEN 2560
-2560  IF I$#"M" THEN 2510
+2560  IF I$<>"M" THEN 2510
@@ -176,18 +176,18 @@
-3300  IF L#L(2) THEN 3340
+3300  IF L<>L(2) THEN 3340
-3340  IF L#L(1) THEN 3210
+3340  IF L<>L(1) THEN 3210
-3410  IF L(2)#L THEN 3440
+3410  IF L(2)<>L THEN 3440
@@ -206,19 +206,19 @@
-4150  IF L#L(2) THEN 4220
+4150  IF L<>L(2) THEN 4220
-4220  IF L#L(3) AND L#L(4) THEN 4270
+4220  IF L<>L(3) AND L<>L(4) THEN 4270
-4270  IF L#L(5) AND L#L(6) THEN 4310
+4270  IF L<>L(5) AND L<>L(6) THEN 4310

I dropped the context from the patch. Since all lines are numbered its irrelevant. I also interleaved the changes so that they are hopefully more obvious. The changes were pretty simple:

  • Replace “#” with “<>”. Apparently OCR doesn’t understand the less than and greater than being side-by-side.
  • The original BASIC dialect for Wumpus apparently had a strange syntax for ON ... GOTO that needed translation.
  • psBASIC doesn’t have the condensed DEF FN... syntax in favor of the more powerful FUNCTION syntax.

It was not uncommon for variations in BASIC dialects to require edits for BASIC programs to succeed on your particular machine. In those days I learned quite a lot about BASIC programming by trying to deduce what the original author’s dialect was doing and then adapting the source to run on my TRS-80.

It didn’t take but half an hour and I finally got to try my hand at hunting the Wumpus. And then I decided to add some sound effects from my collection of sound clip CDs that came with my original SoundBlaster “Multimedia kit for windows” (win3.0). Using psBASIC’s shell() function its easy enough to pass MP3s or WAVs off to the appropriate program to play. :smiley: And then for the fun of it I added the ability to shoot the bats too!

:wink:

1 Like

Having similarly misspent my youth typing in game listings from magazines and David H. Ahl books, I am super excited to have a go at Wumpus and mess around with psBASIC. I appreciate your efforts!

Enjoy! There were worse things I could have misspent my youth on. :wink: And having a TRS-80 to game on saved a fortune in quarters. In some cases it even had an educational benefit. :laughing:

The program is pretty small so I think I’ll try to post the corrected source here:

  10 REM- HUNT THE WUMPUS
  15 REM:  BY GREGORY YOB
  20 PRINT "INSTRUCTIONS (Y-N)";
  30 INPUT I$
  40 IF I$="N" THEN GOTO 52
  50 GOSUB 1000
  52 REM- ANNOUNCE WUMPUSII FOR ALL AFICIONADOS ... ADDED BY DAVE
  54 PRINT
  56 PRINT "     ATTENTION ALL WUMPUS LOVERS!!!"
  58 PRINT "     THERE ARE NOW TWO ADDITIONS TO THE WUMPUS FAMILY";
  60 PRINT " OF PROGRAMS."
  62 PRINT
  64 PRINT "     WUMP2:  SOME DIFFERENT CAVE ARRANGEMENTS"
  66 PRINT "     WUMP3:  DIFFERENT HAZARDS"
  67 PRINT
  68 REM- SET UP CAVE (DODECAHEDRAL NODE LIST)
  70 DIM S(20,3)
  80 FOR J=1 TO 20
  90  FOR K=1 TO 3
 100   READ S(J,K)
 110  NEXT K
 120 NEXT J
 130 DATA 2,5,8,1,3,10,2,4,12,3,5,14,1,4,6
 140 DATA 5,7,15,6,8,17,1,7,9,8,10,18,2,9,11
 150 DATA 10,12,19,3,11,13,12,14,20,4,13,15,6,14,16
 160 DATA 15,17,20,7,16,18,9,17,19,11,18,20,13,16,19
 170 FUNCTION FNA(X) : FNA=INT(20*RND(0))+1 : END FUNCTION
 180 FUNCTION FNB(X) : FNB=INT(3*RND(0))+1 : END FUNCTION
 190 FUNCTION FNC(X) : FNC=INT(4*RND(0))+1 : END FUNCTION
 200 REM-LOCATE L ARRAY ITEMS
 210 REM-1-YOU,2-WUMPUS,3&4-PITS,5&6-BATS
 220 DIM L(6)
 230 DIM M(6)
 240 FOR J=1 TO 6
 250  L(J)=FNA(0)
 260  M(J)=L(J)
 270 NEXT J
 280 REM-CHECK FOR CROSSOVERS (IE L(1)=L(2),ETC)
 290 FOR J=1 TO 6
 300  FOR K=J TO 6
 310   IF J=K THEN GOTO 330
 320   IF L(J)=L(K) THEN GOTO 240
 330  NEXT K
 340 NEXT J
 350 REM-SET# ARROWS
 360 A=5
 365 L=L(1)
 370 REM-RUN THE GAME
 375 PRINT "HUNT THE WUMPUS"
 380 REM-HAZARD WARNINGS & LOCATION
 390 GOSUB 2000
 400 REM-MOVE OR SHOOT
 410 GOSUB 2500
 420 ON O GOTO 440,480
 430 REM-SHOOT
 440 GOSUB 3000
 450 IF F=0 THEN GOTO 390
 460 GOTO 500
 470 REM-MOVE
 480 GOSUB 4000
 490 IF F=0 THEN GOTO 390
 500 IF F>0 THEN GOTO 550
 510 REM-LOSE
 520 PRINT "HA HA HA - YOU LOSE!"
 530 GOTO 560
 540 REM-WIN
 550 PRINT "HEE HEE HEE - THE WUMPUS'LL GETCHA NEXT TIME!!"
 560 FOR J=1 TO 6
 570  L(J)=M(J)
 580 NEXT J
 590 PRINT "SAME SET-UP (Y-N)";
 600 INPUT I$
 610 IF I$<>"Y" THEN GOTO 240
 620 GOTO 360
1000 REM-INSTRUCTIONS
1010 PRINT "WELCOME TO 'HUNT THE WUMPUS'"
1020 PRINT "  THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM"
1030 PRINT "HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A"
1040 PRINT "DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW"
1050 PRINT "WHAT A DODECAHEDRON IS, ASK SOMEONE)"
1060 PRINT
1070 PRINT "     HAZARDS:"
1080 PRINT " BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM"
1090 PRINT "     IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)"
1100 PRINT " SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU"
1110 PRINT "     GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER"
1120 PRINT "     ROOM AT RANDOM. (WHICH MIGHT BE TROUBLESOME)"
1130 PRINT
1140 PRINT "     WUMPUS:"
1150 PRINT " THE WUMPUS IS NOT BOTHERED BY THE HAZARDS (HE HAS SUCKER"
1160 PRINT " FEET AND IS TOO BIG FOR A BAT TO LIFT).  USUALLY"
1170 PRINT " HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOUR ENTERING"
1180 PRINT " HIS ROOM OR YOUR SHOOTING AN ARROW."
1190 PRINT "     IF THE WUMPUS WAKES, HE MOVES (P=.75) ONE ROOM"
1200 PRINT " OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU"
1210 PRINT " ARE, HE EATS YOU UP (& YOU LOSE!)"
1220 PRINT
1230 PRINT "     YOU:"
1240 PRINT " EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW"
1250 PRINT "   MOVING: YOU CAN GO ONE ROOM (THRU ONE TUNNEL)"
1260 PRINT "   ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT."
1270 PRINT "   EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING"
1280 PRINT "   THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO."
1290 PRINT "   IF THE ARROW CAN'T GO THAT WAY (IE NO TUNNEL) IT MOVES"
1300 PRINT "   AT RAMDOM TO THE NEXT ROOM."
1310 PRINT "     IF THE ARROW HITS THE WUMPUS, YOU WIN."
1320 PRINT "     IF THE ARROW HITS YOU, YOU LOSE."
1330 PRINT
1340 PRINT "    WARNINGS:"
1350 PRINT "     WHEN YOU ARE ONE ROOM AWAY FROM WUMPUS OR HAZARD,"
1360 PRINT "    THE COMPUTER SAYS:"
1370 PRINT " WUMPUS-  'I SMELL A WUMPUS'"
1380 PRINT " BAT   -  'BATS NEARBY'"
1390 PRINT " PIT   -  'I FEEL A DRAFT'"
1400 PRINT ""
1410 RETURN
2000 REM-PRINT LOCATION & HAZARD WARNINGS
2010 PRINT
2020 FOR J=2 TO 6
2030  FOR K=1 TO 3
2040   IF S(L(1),K)<>L(J) THEN GOTO 2110
2050   ON J-1 GOTO 2060,2080,2080,2100,2100
2060   PRINT "I SMELL A WUMPUS!"
2070   GOTO 2110
2080   PRINT "I FEEL A DRAFT"
2090   GOTO 2110
2100   PRINT "BATS NEARBY!"
2110  NEXT K
2120 NEXT J
2130 PRINT "YOU ARE IN ROOM "L(1)
2140 PRINT "TUNNELS LEAD TO "S(L,1);S(L,2);S(L,3)
2150 PRINT
2160 RETURN
2500 REM-CHOOSE OPTION
2510 PRINT "SHOOT OR MOVE (S-M)";
2520 INPUT I$
2530 IF I$<>"S" THEN GOTO 2560
2540 O=1
2550 RETURN
2560 IF I$<>"M" THEN GOTO 2510
2570 O=2
2580 RETURN
3000 REM-ARROW ROUTINE
3010 F=0
3020 REM-PATH OF ARROW
3030 DIM P(5)
3040 PRINT "NO. OF ROOMS(1-5)";
3050 INPUT J9
3060 IF J9<1 OR J9>5 THEN GOTO 3040
3070 FOR K=1 TO J9
3080  PRINT "ROOM #";
3090  INPUT P(K)
3095  IF K<=2 THEN GOTO 3115
3100  IF P(K)<>P(K-2) THEN GOTO 3115
3105  PRINT "ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM"
3110  GOTO 3080
3115 NEXT K
3120 REM-SHOOT ARROW
3130 L=L(1)
3140 FOR K=1 TO J9
3150  FOR K1=1 TO 3
3160   IF S(L,K1)=P(K) THEN GOTO 3295
3170  NEXT K1
3180  REM-NO TUNNEL FOR ARROW
3190  L=S(L,FNB(1))
3200  GOTO 3300
3210 NEXT K
3220 PRINT "MISSED"
3225 L=L(1)
3230 REM-MOVE WUMPUS
3240 GOSUB 3370
3250 REM-AMMO CHECK
3255 A=A-1
3260 IF A>0 THEN GOTO 3280
3270 F=-1
3280 RETURN
3290 REM-SEE IF ARROW IS AT L(1) OR L(2)
3295 L=P(K)
3300 IF L<>L(2) THEN GOTO 3340
3310 PRINT "AHA! YOU GOT THE WUMPUS!"
3320 F=1
3330 RETURN '
3340 IF L<>L(1) THEN GOTO 3210
3350 PRINT "OUCH! ARROW GOT YOU!"
3360 GOTO 3270
3370 REM-MOVE WUMPUS ROUTINE
3380 K=FNC(0)
3390 IF K=4 THEN GOTO 3410
3400 L(2)=S(L(2),K)
3410 IF L(2)<>L THEN GOTO 3440
3420 PRINT "TSK TSK TSK- WUMPUS GOT YOU!"
3430 F=-1
3440 RETURN
4000 REM- MOVE ROUTINE
4010 F=0
4020 PRINT "WHERE TO";
4030 INPUT L
4040 IF L<1 OR L>20 THEN GOTO 4020
4050 FOR K=1 TO 3
4060  REM- CHECK IF LEGAL MOVE
4070  IF S(L(1),K)=L THEN GOTO 4130
4080 NEXT K
4090 IF L=L(1) THEN GOTO 4130
4100 PRINT "NOT POSSIBLE -";
4110 GOTO 4020
4120 REM-CHECK FOR HAZARDS
4130 L(1)=L
4140 REM-WUMPUS
4150 IF L<>L(2) THEN GOTO 4220
4160 PRINT "...OOPS! BUMPED A WUMPUS!"
4170 REM-MOVE WUMPUS
4180 GOSUB 3380
4190 IF F=0 THEN GOTO 4220
4200 RETURN
4210 REM-PIT
4220 IF L<>L(3) AND L<>L(4) THEN GOTO 4270
4230 PRINT "YYYIIIIEEEE . . . FELL IN PIT"
4240 F=-1
4250 RETURN
4260 REM-BATS
4270 IF L<>L(5) AND L<>L(6) THEN GOTO 4310
4280 PRINT "ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!"
4290 L=FNA(1)
4300 GOTO 4130
4310 RETURN
5000 END

I haven’t played it through yet but psBASIC recognizes all the commands in it. The RND() function with 0 as its argument operates the same as what Wumpus is expecting. It should be playable.

It still needs some clean up: OCR is horrible about OCRing spaces so much of the text indentation is off. The instructions (lines 1000-1390) are affected by this and need some reformatting, as does the “announcement” (lines 54-67).

The other thing that would need some attention: It appears this was played on a teletype. The length of output from the program was irrelevant since you could simply read back through the continuous paper that was printed. On a “terminal” the instructions will scroll off the screen. If you have scrollback, as GUI users do, you can scroll back to read them. However it would be better to put a “press [ENTER] to continue” prompt about every 20 lines or so.

Oh! And it needs a RANDOMIZE statement at the top, or you’ll play the same game every time. :smiley: