The SuperPET was an educational computer developed in cooperation with the University of Waterloo as an inexpensive environment for students to learn programming and released as a product by Commodore in 1981. Thirty one years later the Raspberry Pi was released in cooperation with Cambridge University as an inexpensive computer for education. This project aims to explore the similarities and differences of the design, implementation and impact these two computers had on education, the hobbyist, the maker community and the industry in their historical contexts.
For reference this project continues the topics touched on in
viewtopic.php?p=1738151#p1738151
viewtopic.php?p=1714665#p1714665
as well as the computer literacy topics in
viewtopic.php?t=227343
viewtopic.php?t=240287
viewtopic.php?f=31&t=257317
While it may seem tangential, this thread begins with a discussion of what has historically been classified as the first computer-based adventure game. Hunt the Wumpus was written by Gregory Yob in 1972 at the People's Computer Center in Menlo Park California and published by People's Computer Company in a no-advertising-allowed newsletter targeted at teachers and students in primary and secondary schools.
While it would be interesting to compare the PCC newsletter to the MagPi, this publication also shared much in common with Raspberry Pi Learn and the associated Hello World magazine. Such a comparison, however, is outside the scope of the present project. Here we focus directly on the software and hardware of the SuperPET and the Pi.
As memories of how the SuperPET actually worked have been clouded by time and functional 31-year-old hardware is difficult to find, we begin with an exploration of the SuperPET through emulation. Fortunately, the Versatile Commodore Emulator VICE fully emulates the original hardware--including the 6702 secure boot environment--and also runs on the Raspberry Pi. To understand how all this works, the current task is to port the Unix version of Hunt the Wumpus written by Ken Thompson around 1973 to Waterloo microPascal running on the SuperPET as if it were 1982.
In beginning, the recent talk
https://uwaterloo.ca/watitis/university ... w-trenches
indicates that others have also been reflecting on how past computer literacy efforts connect to the present and provide a context for understanding the future.
A Birthday Present for Fido
Last edited by ejolson on Sun Oct 11, 2020 4:58 pm, edited 2 times in total.
Re: A Birthday Present for Fido
To get started, here is a screen dump of my microPascal port of Ken's version of Hunt the Wumpus running on the SuperPET using VICE with a Pi 4B









just in time for Fido's birthday.
Subsequent posts will describe what needed to be done to compile and install the latest version of VICE on the Pi and compare this with what needed to be done to port Ken's C code to microPascal for the SuperPET. After that a version of Hunt the Wumpus written in Rust for the Raspberry Pi will form the basis to further understand the relative contexts of these two historically significant educational computing platforms.
Then, moving to a modern setting--unless the thread is closed by then--I plan to consider the development of an artificial intelligence that uses a convolutional neural network to learn how to reliably win while playing Hunt the Wumpus. The question here is whether today's Raspberry Pi constitutes a sufficient platform for a student to learn about such computer-science techniques.
As in the other threads, help, feedback and additions to these topics would be very much appreciated.









just in time for Fido's birthday.
Subsequent posts will describe what needed to be done to compile and install the latest version of VICE on the Pi and compare this with what needed to be done to port Ken's C code to microPascal for the SuperPET. After that a version of Hunt the Wumpus written in Rust for the Raspberry Pi will form the basis to further understand the relative contexts of these two historically significant educational computing platforms.
Then, moving to a modern setting--unless the thread is closed by then--I plan to consider the development of an artificial intelligence that uses a convolutional neural network to learn how to reliably win while playing Hunt the Wumpus. The question here is whether today's Raspberry Pi constitutes a sufficient platform for a student to learn about such computer-science techniques.
As in the other threads, help, feedback and additions to these topics would be very much appreciated.
Re: A Birthday Present for Fido
Promising launch! Though impressive for their age, it was disappointing to discover that these are language interpreters, not compilers. No way to explore the unique features of the make believe 6809! There's an assembler and linker provided, so maybe...
Re: A Birthday Present for Fido
Why Rust and not Python or C ? Why not just use Ken's original C code ?ejolson wrote: ↑Sun Oct 11, 2020 3:04 amSubsequent posts will describe what needed to be done to compile and install the latest version of VICE on the Pi and compare this with what needed to be done to port Ken's C code to microPascal for the SuperPET. After that a version of Hunt the Wumpus written in Rust for the Raspberry Pi will form the basis to further understand the relative contexts of these two historically significant educational computing platforms.
Re: A Birthday Present for Fido
The tradition of interpreted languages for teaching beginners seems to have continued with Scratch and Python. It's not clear to me whether the reason for this is a perceived inability to tell hot dogs from food or the development costs.
In the case of the emulated SuperPET, simply pressing alt-W turns on warp mode and the program then runs at the speed as if it had been compiled for the original hardware. Indeed, warp mode is almost a necessity when generating the random graphs used for the maze in the Pascal version of Hunt the Wumpus. If anyone knows how to turn off the auto repeat to prevent the keyboard from creating 7 to 14 characters with each key press, that would make warp even more useful.
The fact that microPascal, microBasic, microFortran, microAPL and microCOBOL were interpreted seems a distinguishing trait of a toy designed for teaching rather than a real computer for business use. Though Commodore marketed the SuperPET as the MicroMainframe 9000, they did not provide the development tools, for example OS/9 and a C compiler, needed to allow the SuperPET to be easily used as a real computer.
The distinction between a real computer and a toy to teach children programming continues to this day: I find it interesting the original concept of the Raspberry Pi was a teaching device limited to running only MicroPython.
https://micropython.org/download/
Had this happened, the Pi would have been not only closer to the SuperPET in implementation but likely popularity as well. After age 5 children get tired of pretending with lumps of plastic and want something that really works. The same is likely true of hobbyists, makers and even most software professionals.
Although Python and Scratch continue in the tradition of interactive programming languages with slow performance that were designed for teaching, the vendor supported software included with the Pi, while only 32-bit, is a full distribution of Linux with all the same compilers and development tools used from embedded to the cloud. The difference is significant though the similarities are many.
Last edited by ejolson on Sun Oct 11, 2020 5:11 pm, edited 1 time in total.
Re: A Birthday Present for Fido
When the SuperPET was deployed, the strong typing, structured programming and single-entry single-exit constraints of Pascal were innovations in software development thought to be significant enough to include in any introductory course on computer science. Today we have done away with the fashion of hiding data in objects and moved to the strongly enforced data ownership model of Rust. This is the latest innovation in language design. Therefore, programming in Rust on the Pi is the closest thing to Pascal on the SuperPET when it comes to teaching computer science in historical context, at least in my opinion.
Thanks for the input! Further discussion is very welcome.
Re: A Birthday Present for Fido
The structured programming fad predated the OO fad and were distinct sea changes.
Indeed, I hadn't thought of it that way.Therefore, programming in Rust on the Pi is the closest thing to Pascal on the SuperPET when it comes to teaching computer science in historical context, at least in my opinion.
Idle musing. How many topographically unique graphs or caves can be formed with 20 vertices, each connected to exactly 3 neighbors, without overlapping edges, in three dimensional space?
Re: A Birthday Present for Fido
An answer to how many random mazes are possible was partially discussed and referenced inlurk101 wrote: ↑Sun Oct 11, 2020 5:22 pmThe structured programming fad predated the OO fad and were distinct sea changes.Indeed, I hadn't thought of it that way.Therefore, programming in Rust on the Pi is the closest thing to Pascal on the SuperPET when it comes to teaching computer science in historical context, at least in my opinion.
Idle musing. How many topographically unique graphs or caves can be formed with 20 vertices, each connected to exactly 3 neighbors, without overlapping edges, in a three dimensional space?
viewtopic.php?p=1714376#p1714376
From a deep-learning AI point of view, randomly generated mazes seem much more challenging than a torus or the original dodecahedron--there is much more hidden state to be reconstructed.
It is not clear how a deep learning neural network would cope with that directly. Humans tend to look at the scroll-back buffer or draw a map, so an AI should probably have access to some sort of record of past moves in order to make the next. Note that the use of Hunt the Wumpus for AI student projects was also touched on in the above-linked thread.
I would emphasize that Ken's random graphs, the fact that you can smell the Wumpus from two vertices away and the greater tendency of the Wumpus to not eat you you make the Unix version of Hunt the Wumpus noticeably different than the BASIC program by Gregory Yob. Although the original game has been translated into many languages, the Unix variant has not. Even if the Unix version had been widely translated, it would still be necessary to write more programs to understand the suitability of each educational computer for teaching and learning. This is because with programming, as with as most other measurable skills, the way forward is to learn by doing.
Re: A Birthday Present for Fido
I just finished conferencing with Fido on Zoom about the origins of Hunt the Wumpus. It seems, even through banned from the computer, the former dog developer may have got wind of my coming birthday surprise.
At any rate, some sources say the actual code for Hunt the Wumpus was written in 1972 while Gregory was a student at the University of Massachusetts, not at the People's Computer Company but inspired by games developed by others there. At the same time, artwork created by Gregory on the daisy-wheel printer in Menlo Park appears in PCC volume 2 number 5. Fido claims that Gregory was actually in both places at the same time and might be here right now as well.
I found a BASIC Hunt the Wumpus with random graphs for the PDP-8 at
http://www.pdp8.net/pdp8cgi/os8_html/WU ... ,0;plain=1
The game dynamics do not seem to be equivalent to the Unix C code--the player has a lamp that can be turned on and off among other differences. These additions suggest Ken's version didn't derive from the PDP-8 but possibly other way around.
Note that Ken's Unix version had 22 goto statements while the PDP-8 version has 88 GOTO statements. Although Pascal allows goto statements, in order to make a proper birthday present for the super pet, I played the role of a student writing a program for an assignment where 1 percent was removed for each goto.
The results were
On the deep-learning front there appears to have been an implementation of a Wumpus expert system developed at the MIT Artificial Intelligence Laboratory in 1976 by James Stansfield, Brian Carr and Ira Goldstein.
https://files.eric.ed.gov/fulltext/ED207585.pdf
The actual code is missing, but enough details may be present to write a similar program using Rust for the Pi if not microPascal for the SuperPET.
At any rate, some sources say the actual code for Hunt the Wumpus was written in 1972 while Gregory was a student at the University of Massachusetts, not at the People's Computer Company but inspired by games developed by others there. At the same time, artwork created by Gregory on the daisy-wheel printer in Menlo Park appears in PCC volume 2 number 5. Fido claims that Gregory was actually in both places at the same time and might be here right now as well.
I found a BASIC Hunt the Wumpus with random graphs for the PDP-8 at
http://www.pdp8.net/pdp8cgi/os8_html/WU ... ,0;plain=1
The game dynamics do not seem to be equivalent to the Unix C code--the player has a lamp that can be turned on and off among other differences. These additions suggest Ken's version didn't derive from the PDP-8 but possibly other way around.
Note that Ken's Unix version had 22 goto statements while the PDP-8 version has 88 GOTO statements. Although Pascal allows goto statements, in order to make a proper birthday present for the super pet, I played the role of a student writing a program for an assignment where 1 percent was removed for each goto.
The results were
Code: Select all
goto count score grade
microPascal 0 100 A
K&R C 22 78 C+
PDP-8 Basic 88 12 F
https://files.eric.ed.gov/fulltext/ED207585.pdf
The actual code is missing, but enough details may be present to write a similar program using Rust for the Pi if not microPascal for the SuperPET.
Last edited by ejolson on Mon Oct 12, 2020 4:34 pm, edited 2 times in total.
Re: A Birthday Present for Fido
While a bit off topic for this thread, I couldn't resist trying the PDP-8 version of Wumpus. Since the PDP-8 was surplussed long ago and I didn't want to figure out how to spin DECtape on SIMH, I decided it'd be easier to translate the code to BBC BASIC. The main changes were rewriting lines of the form
IF condition GOTO statement
to read as
IF condition THEN statement
and then changing all RND(0) calls to RND(1). I also removed the RANDOMIZE statement and replaced it by M=RND(-ABS(M)) to restore the apparent functionality that had been lost for setting the random seed. After this, I made some formatting changes based on differences in how semicolons were interpreted between BASICs and then changed the MAP command to output a suitable format for graphviz as discussed at
viewtopic.php?p=1719586#p1719586
I've played a couple games now. It seems the graph generator sometimes gets stuck in an infinite loop, so if after entering a random seed it hangs, then press <ESC> and run the program again with a different seed. I'm not sure if this is an error with my modifications to make it work on BBC BASIC or whether the bug was in the original program. If anyone wants to check the original running under OS8 on the SIMH PDP-8 emulator, that would be appreciated. Since BBC BASIC and SIMH run on the Raspberry Pi but the not SuperPET, it would also be interesting to know the changes needed to run the program under Waterloo microBASIC.
For reference, the BBC BASIC code is
The game play is noticeably more chaotic than the Unix game as well as the original BASIC games by Gregory Yob including Wumpus 1, Wumpus 2 and Wumpus 3. I'll include a transcript in the next post as an example.
IF condition GOTO statement
to read as
IF condition THEN statement
and then changing all RND(0) calls to RND(1). I also removed the RANDOMIZE statement and replaced it by M=RND(-ABS(M)) to restore the apparent functionality that had been lost for setting the random seed. After this, I made some formatting changes based on differences in how semicolons were interpreted between BASICs and then changed the MAP command to output a suitable format for graphviz as discussed at
viewtopic.php?p=1719586#p1719586
I've played a couple games now. It seems the graph generator sometimes gets stuck in an infinite loop, so if after entering a random seed it hangs, then press <ESC> and run the program again with a different seed. I'm not sure if this is an error with my modifications to make it work on BBC BASIC or whether the bug was in the original program. If anyone wants to check the original running under OS8 on the SIMH PDP-8 emulator, that would be appreciated. Since BBC BASIC and SIMH run on the Raspberry Pi but the not SuperPET, it would also be interesting to know the changes needed to run the program under Waterloo microBASIC.
For reference, the BBC BASIC code is
Code: Select all
1 PRINT "FOR HELP TYPE 'HELP WUMPUS' AS AN OS8 COMMAND"
2 PRINT "ENTER A RANDOM NUMBER";
3 INPUT M
4 PRINT "HERE WE GO----"
5 PRINT "DOWN"
6 PRINT " O"
7 PRINT " W"
8 PRINT "DOWN"
9 PRINT
10 DIM A(20),B(20),C(20),D(20)
20 DIM Q$(20),P$(10)
25 READ Q$
30 M=RND(-ABS(M))
40 FOR Z=1 TO 20
50 A(Z)=0
60 B(Z)=0
70 C(Z)=0
80 D(Z)=0
90 NEXT Z
100 R0=.02
105 B0=0
110 L0=0
120 FOR Z=1 TO 20
130 IF A(Z)<>0 THEN 190
140 F=INT(20*RND(1))+1
150 IF F=Z THEN 140
160 IF A(F)<>0 THEN 140
170 A(Z)=F
180 A(F)=Z
190 NEXT Z
200 FOR Z=1 TO 20
210 IF B(Z)<>0 THEN 280
220 F=INT(20*RND(1))+1
230 IF F=Z THEN 220
240 IF A(Z)=F THEN 220
250 IF B(F)<>0 THEN 220
260 B(Z)=F
270 B(F)=Z
280 NEXT Z
290 FOR X=1 TO 20
300 IF D(X)<>0 THEN 410
310 IF X=1 THEN 340
320 B(Y)=X
330 B(X)=Y
340 Y=X
350 D(Y)=1
360 Y=A(Y)
370 D(Y)=1
380 IF B(Y)=X THEN 410
390 Y=B(Y)
400 GOTO 350
410 D(X)=0
420 NEXT X
430 B(Y)=1
440 B(1)=Y
450 FOR Z=1 TO 20
460 IF C(Z)<>0 THEN 540
470 F=INT(20*RND(1))+1
480 IF F=Z THEN 470
490 IF F=A(Z) THEN 470
500 IF F=B(Z) THEN 470
510 IF C(F)<>0 THEN 470
520 C(Z)=F
530 C(F)=Z
540 NEXT Z
550 FOR X=1000 TO 10000 STEP 9000
560 FOR Z=1 TO 3
570 F=INT(20*RND(1))+1
580 IF D(F)>=X THEN 570
590 D(F)=D(F)+X
600 GOSUB 2130
610 NEXT Z
620 NEXT X
630 F=INT(20*RND(1))+1
640 X=100000
650 D(F)=D(F)+X
660 GOSUB 2130
670 W=F
680 F=A(W)
690 GOSUB 2130
700 F=B(W)
710 GOSUB 2130
720 F=C(W)
730 GOSUB 2130
740 H=INT(20*RND(1))+1
750 IF D(H)>=1000 THEN 740
760 FOR S=5 TO 1 STEP -1
770 IF L0=0 THEN 777
772 GOSUB 1740
774 PRINT "I SEE THAT TUNNELS A B AND C LEAD TO ROOMS ";
776 PRINT "";A(H);" ";B(H);" AND ";C(H);" RESPECTIVELY"
777 IF RND(1)>.04 THEN 779
778 GOSUB 2191
779 J=D(H)
780 IF J>=1000 THEN 1240
790 GOTO 1090
800 IF J=0 THEN 890
810 IF J=INT(J/10)*10 THEN 830
820 PRINT "I HEAR SQUEAKING, ";
830 J=INT(J/10)
840 IF J=INT(J/10)*10 THEN 860
850 PRINT "I FEEL A DRAFT, ";
860 IF J<10 THEN 880
870 PRINT "I SMELL A WUMPUS ";
880 PRINT
890 PRINT "YOU ARE IN ROOM ";H;" MOVE THROUGH TUNNEL";
895 H1=H
900 INPUT P$
905 IF P$="Q" THEN 2310
910 IF P$<>"A" THEN 940
920 H=A(H)
930 GOTO 770
940 IF P$<>"B" THEN 970
950 H=B(H)
960 GOTO 770
970 IF P$<>"C" THEN 1000
980 H=C(H)
990 GOTO 770
1000 IF P$="SHOOT" THEN 1470
1010 IF P$<>"MAP" THEN 1040
1020 GOSUB 2200
1030 GOTO 779
1040 IF P$<>"LIGHTS ON" THEN 1070
1050 L0=1
1060 GOTO 770
1070 IF P$<>"LIGHTS OFF" THEN 770
1075 L0=0
1080 GOTO 770
1090 IF RND(1)>R0 THEN 800
1100 PRINT "YOU TRIPPED ON A ";Q$;" IN ROOM ";H;" ";
1110 F=INT(20*RND(1))+1
1120 IF F=A(H) THEN 1150
1130 IF F=B(H) THEN 1150
1140 IF F<>C(H) THEN 1110
1145 IF F=H THEN 1110
1150 PRINT "AND HAVE TUMBLED INTO ROOM ";F
1160 IF R0<.2 THEN 1190
1165 IF RND(1)<.5 THEN 1190
1170 PRINT "YOU ARE GETTING CLUMSIER BY THE MINUTE"
1180 PRINT "YOU SEEM TO BE STUMBLING AROUND ";R0*100;"% OF THE TIME"
1190 R0=R0+.02
1200 H=F
1210 IF D(H)>=100000 THEN 1430
1220 GOSUB 1740
1230 GOTO 770
1240 J=INT(J/1000)
1250 IF J>=10 THEN 1300
1260 PRINT "THERE IS A SUPER-BAT IN ROOM ";H;". FLAP--FLAP OUCH!!"
1270 H=INT(20*RND(1))+1
1280 IF D(H)>999 THEN 1270
1283 IF H=H1 THEN 1270
1290 GOTO 770
1300 IF J>=100 THEN 1430
1310 PRINT "YOU FELL INTO THE BOTTOMLESS PIT IN ROOM ";H
1320 IF J-10<>0 THEN 2050
1330 IF D(H)<>INT(D(H)/10)*10 THEN 2070
1340 PRINT "PLAY AGAIN (YES OR NO)";
1350 RESTORE
1360 INPUT P$
1370 PRINT
1380 IF P$="YES" THEN 40
1390 IF P$<>"MAP" THEN 1420
1400 GOSUB 2200
1410 GOTO 1340
1420 STOP
1430 PRINT "YOU HAVE BEEN DEVOURED BY THE WUMPUS IN ROOM ";H
1440 GOTO 1340
1450 PRINT "YOU SHOT YOURSELF"
1460 GOTO 1340
1470 PRINT "THE ARROW ZINGS IN ";
1480 K=H
1490 K1=H
1500 FOR R=1 TO 5
1510 PRINT "TO ROOM";
1520 INPUT M
1530 IF M=A(K) THEN 1600
1540 IF M=B(K) THEN 1600
1550 IF M=C(K) THEN 1600
1560 IF M=0 THEN 1700
1570 R=6
1580 M=INT(20*RND(1))+1
1590 GOTO 1530
1600 IF R<=5 THEN 1626
1620 PRINT "THE ARROW WENT ASTRAY"
1624 GOTO 1630
1626 IF M=K1 THEN 1570
1630 IF M=H THEN 1450
1640 IF D(M)<100000 THEN 1670
1650 PRINT "YOU HAVE SLAIN THE WUMPUS"
1655 S=S-1
1660 GOTO 1340
1670 IF INT(D(M)/1000)=INT(D(M)/10000)*10 THEN 1678
1671 PRINT "YOU PICKED OFF AN INNOCENT SUPER-BAT"
1672 X=-1000
1673 F=M
1674 GOSUB 2130
1675 D(M)=D(M)-1000
1676 B0=B0+1
1677 GOTO 1700
1678 K1=K
1680 K=M
1690 NEXT R
1700 GOSUB 1740
1710 NEXT S
1720 PRINT "YOU HAVE EXHAUSTED YOUR SUPPLY OF ARROWS -- THE SHOW'S OVER"
1730 GOTO 1340
1740 IF RND(1)>.5 THEN 2000
1750 PRINT "ROAR**THUD**THUD**RRUUMMBBLLEE**THWUMP**ZZZZZZZZZZZ"
1760 X=-100000
1770 F=W
1780 GOSUB 2130
1790 F=A(W)
1800 GOSUB 2130
1810 F=B(W)
1820 GOSUB 2130
1830 F=C(W)
1840 GOSUB 2130
1850 D(W)=D(W)-100000
1860 F=INT(20*RND(1))+1
1870 IF F=A(W) THEN 1900
1880 IF F=B(W) THEN 1900
1890 IF F<>C(W) THEN 1860
1900 X=100000
1910 D(F)=D(F)+X
1920 W=F
1930 GOSUB 2130
1940 F=A(W)
1950 GOSUB 2130
1960 F=B(W)
1970 GOSUB 2130
1980 F=C(W)
1990 GOSUB 2130
2000 READ Q$
2010 IF Q$<>"END" THEN 2040
2020 RESTORE
2030 GOTO 2000
2040 RETURN
2050 PRINT "YOU HAVE BEEN SNATCHED UP BY A SUPER-BAT"
2060 GOTO 1270
2070 PRINT "THERE IS A BAT IN AN ADJACENT ROOM -- HE'S FLYING THIS WAY!"
2080 IF RND(1)>.25 THEN 2110
2090 PRINT "YOU STRUCK YOUR HEAD ON A ";Q$;" GOOD-BYYEEE"
2100 GOTO 1340
2110 PRINT "PHEWWW!!! ";
2120 GOTO 2050
2130 F1=A(F)
2140 D(F1)=D(F1)+X/1000
2150 F1=B(F)
2160 D(F1)=D(F1)+X/1000
2170 F1=C(F)
2180 D(F1)=D(F1)+X/1000
2190 RETURN
2191 IF B0<0 THEN 2199
2192 B0=B0-1
2193 F=INT(20*RND(1))+1
2194 IF INT(D(F)/1000)<>INT(D(F)/10000)*10 THEN 2193
2195 X=1000
2196 D(F)=D(F)+X
2197 GOSUB 2130
2198 PRINT "ANOTHER SUPER-BAT HAS BEEN BORN. LOOKS LIKE A STRONG ONE!"
2199 RETURN
2200 Z=1
2205 PRINT "graph maze {"
2210 PRINT " overlap=false; splines=true; sep=1.0"
2215 IF Z>A(Z) THEN 2225
2220 PRINT " ";Z;" -- ";A(Z)
2225 IF Z>B(Z) THEN 2235
2230 PRINT " ";Z;" -- ";B(Z)
2235 IF Z>C(Z) THEN 2245
2240 PRINT " ";Z;" -- ";C(Z)
2245 Z=Z+1
2250 IF Z<=20 THEN 2215
2255 PRINT "}"
2280 RETURN
2290 DATA "CORPSE","DEAD BAT","BROKEN ARROW","STALAGMITE","PEBBLE"
2291 DATA "WUMPUS CLAW","LEDGE","LUNCH BAG","DOG"
2300 DATA "END"
2310 END
Last edited by ejolson on Mon Oct 12, 2020 4:38 pm, edited 2 times in total.
Re: A Birthday Present for Fido
Here is a sample game of PDP-8 Hunt the Wumpus played using BBC BASIC.
While playing the game I marked up a graph previously generated by the MAP command in a barely legible way using xournal with a mouse and then converted it to PNG format using the PrtScr button.

It appears the random graph is generated in such a way that the edges may be labeled A, B and C and that each vertex in the graph has exactly one edge of each type connecting to it. My understanding is the random graphs created by Ken's algorithm do not necessarily have this property. On the other hand, from what I can tell, it is possible the graphs made by the PDP-8 program do not all admit a Hamiltonian path that visits each vertex only once. Which makes for a better game is difficult to determine.
For reference, the instructions for the game are available through the OS8 help facility and read
Note the instructions do not mention the MAP command, which was clearly a way to cheat. At any rate, I modified the command to make the graphical output and to remove the exact location of the Wumpus, pits and bats. This is still cheating a bit, because I knew ahead of time how the rooms were linked in order to shoot my arrow for the last turn. Without the map, it would have required additional exploration to finish the game.
Code: Select all
$ ./bbcbasic
BBC BASIC for Linux Console v0.28
(C) Copyright R. T. Russell, 2020
>LOAD "WUMP.BAS"
>RUN
FOR HELP TYPE 'HELP WUMPUS' AS AN OS8 COMMAND
ENTER A RANDOM NUMBER? 3141
HERE WE GO----
DOWN
O
W
DOWN
I HEAR SQUEAKING,
YOU ARE IN ROOM 16 MOVE THROUGH TUNNEL? A
I HEAR SQUEAKING, I FEEL A DRAFT,
YOU ARE IN ROOM 14 MOVE THROUGH TUNNEL? A
I HEAR SQUEAKING,
YOU ARE IN ROOM 16 MOVE THROUGH TUNNEL? B
YOU ARE IN ROOM 15 MOVE THROUGH TUNNEL? B
I HEAR SQUEAKING,
YOU ARE IN ROOM 16 MOVE THROUGH TUNNEL? B
YOU ARE IN ROOM 15 MOVE THROUGH TUNNEL? A
I FEEL A DRAFT,
YOU ARE IN ROOM 11 MOVE THROUGH TUNNEL? A
YOU ARE IN ROOM 15 MOVE THROUGH TUNNEL? C
I HEAR SQUEAKING,
YOU ARE IN ROOM 20 MOVE THROUGH TUNNEL? LIGHTS ON
I SEE THAT TUNNELS A B AND C LEAD TO ROOMS 13 3 AND 15 RESPECTIVELY
I HEAR SQUEAKING,
YOU ARE IN ROOM 20 MOVE THROUGH TUNNEL? LIGHTS OFF
I HEAR SQUEAKING,
YOU ARE IN ROOM 20 MOVE THROUGH TUNNEL? B
I SMELL A WUMPUS
YOU ARE IN ROOM 3 MOVE THROUGH TUNNEL? SHOOT
THE ARROW ZINGS IN TO ROOM? 1
TO ROOM? 6
YOU HAVE SLAIN THE WUMPUS
PLAY AGAIN (YES OR NO)? NO
STOP at line 1420

It appears the random graph is generated in such a way that the edges may be labeled A, B and C and that each vertex in the graph has exactly one edge of each type connecting to it. My understanding is the random graphs created by Ken's algorithm do not necessarily have this property. On the other hand, from what I can tell, it is possible the graphs made by the PDP-8 program do not all admit a Hamiltonian path that visits each vertex only once. Which makes for a better game is difficult to determine.
For reference, the instructions for the game are available through the OS8 help facility and read
Code: Select all
Note: This is a basic game, see BASIC instructions.
YOU ARE A FAMOUS HUNTER DESCENDING DOWN INTO THE CAVES OF DARKNESS,
LAIR OF THE INFAMOUS MAN-EATING WUMPUS. YOU ARE EQUIPPED WITH FIVE
BENT ARROWS, AND ALL YOUR SENSES. THERE ARE TWENTY CAVES CONNECTED
BY TUNNELS, AND THERE ARE TWO OTHER KINDS OF HAZARDS:
A) PITS, WHICH ARE BOTTOMLESS, AND USUALLY FATAL TO FALL
INTO. THERE ARE THREE SUCH PITS IN THE NETWORK.
B) SUPER-BATS, WHICH IF YOU STUMBLE INTO THEIR ROOM WILL
PICK YOU UP AND DROP YOU IN SOME RANDOM ROOM IN THE NETWORK.
YOU MAY SHOOT SUPER-BATS, THERE IS ONE IN EACH OF THREE OR
FOUR ROOMS WITHIN THE NETWORK. THE SUPER-BATS GENERALLY STAY
IN THEIR OWN ROOMS, EXCEPT WHEN DISPOSING OF INTRUDERS OR
SCAVENGING FOR FOOD IN THE PITS.
IF YOU BLUNDER INTO THE SAME ROOM AS THE WUMPUS, YOU LOSE....
THE NORMALLY SLEEPING WUMPUS DOES NOT MOVE (HAVING GORGED HIMSELF UPON
A PREVIOUS HUNTER). HOWEVER SEVERAL THINGS CAN WAKE HIM UP:
1) WALKING INTO HIS ROOM,
2) SHOOTING AN ARROW ANYWHERE IN THE NETWORK,
3) TRIPPING OVER DEBRIS (CLUMSINESS),
4) TURNING ON THE LIGHTS, IN ORDER TO SEE WHERE YOU ARE
HEADED.
IF HE WAKES UP THERE'S A POSSIBILITY HE WILL MOVE, HOWEVER, HE'S TOO
LAZY TO MOVE MORE THAN ONE ROOM BETWEEN SNOOZES. THE WUMPUS IS TOO
BIG TO BE PICKED UP BY SUPER-BATS AND HAS SUCKER FEET, SO HE DOESN'T
FALL INTO THE PITS.
YOU CAN SMELL THE WUMPUS FROM ONE OR TWO ROOMS AWAY. YOU WILL
TREMBLE WITH FEAR WHEN HE MOVES ABOUT. YOU CAN HEAR SUPER-BATS FROM
ONE ROOM AWAY, AND FEEL DRAFTS (FROM BOTTOMLESS PITS) FROM ONE ROOM
AWAY (AND TASTE THE FEAR...).
TO SHOOT AN ARROW TYPE "SHOOT" INSTEAD OF A MOVE, AND THEN
SPECIFY WHICH ROOMS THE ARROW SHOULD PASS THROUGH. YOU ARE STRONG
ENOUGH TO SHOOT IT THROUGH AS MANY AS FIVE ROOMS. BENT ARROWS HAVE
NO PROBLEM ROUNDING CORNERS OF LESS THAN 98.6 DEGREES. IF YOU
SPECIFY AN IMPOSSIBLE PATH THE ARROW WILL RICOCHET OFF THE WALLS OF
THE ROOM, LOSING SPEED, AND WILL EVENTUALLY COME TO REST IN ONE OF
THE ADJOINING ROOMS. THE PATH MAY BE TERMINATED BY SPECIFYING ROOM 0.
EACH ROOM IS CONNECTED TO THREE OTHER ROOMS BY THREE TUNNELS A, B
AND C. YOU MUST ALWAYS MOVE BETWEEN ROOMS BY SPECIFYING WHICH
TUNNEL YOU WISH TO EXPLORE. YOU CAN ALWAYS RETRACE YOUR FOOT STEPS
BY MOVING BACK USING THE SAME TUNNEL DESIGNATOR.
IF YOU WISH TO SEE WHICH ROOMS ARE AT THE ENDS OF THE TUNNELS YOU
MAY TYPE "LIGHTS ON" INSTEAD OF A MOVE. THIS MAY BE AN UNHEALTHY
LUXURY HOWEVER BECAUSE THE LIGHT GIVES THE WUMPUS INSOMNIA. TO
EXTINGUISH THE LIGHTS SIMPLY TYPE "LIGHTS OFF".
GOOD LUCK HUNTING!!
Last edited by ejolson on Mon Oct 12, 2020 4:39 pm, edited 1 time in total.
Re: A Birthday Present for Fido
I've been studying the BASIC code which makes the random graphs and came across an interesting algorithm between lines 290 through 440. This loop appears to guarantee that taking alternatively A and then B tunnels will complete a Hamiltonian circuit that visits all the vertices once and ends up back where you started. Alternating A and C in general does not visit all the nodes nor does alternatively choosing tunnels C and B. At any rate, it would appear the random graphs generated by the BASIC code for the PDP-8 may form a subset of those generated by the Unix C code.
My guess is that sometimes the random selection of edges leads to a partial maze which cannot be completed to a regular valence-three graph. At that point the BASIC code gets stuck in an infinite loop. On the other hand, when the Unix program detects such a problem it simply tries again from the beginning. Does anyone want to exterminate a 48-year-old bug from the past?
From a machine learning point of view, I think it would be preferable to choose from among the tunnels A, B and C for each move rather than selecting the destination by room number. Of course both are possible in the PDP-8 version since the lamp can be turned on and off.
Being able to turn on the lights also allowed me to win one game where I was trapped behind two pits. In that case I turned on the lights and then moved back and forth in the limited part of the maze I had access to until the Wumpus crossed over the pits using those sucker feet, at which point I deployed an arrow.
My guess is that sometimes the random selection of edges leads to a partial maze which cannot be completed to a regular valence-three graph. At that point the BASIC code gets stuck in an infinite loop. On the other hand, when the Unix program detects such a problem it simply tries again from the beginning. Does anyone want to exterminate a 48-year-old bug from the past?
From a machine learning point of view, I think it would be preferable to choose from among the tunnels A, B and C for each move rather than selecting the destination by room number. Of course both are possible in the PDP-8 version since the lamp can be turned on and off.
Being able to turn on the lights also allowed me to win one game where I was trapped behind two pits. In that case I turned on the lights and then moved back and forth in the limited part of the maze I had access to until the Wumpus crossed over the pits using those sucker feet, at which point I deployed an arrow.
Last edited by ejolson on Tue Oct 13, 2020 2:55 pm, edited 1 time in total.
Re: A Birthday Present for Fido
It occured to me that any computer used for teaching must also support legacy programming languages, not only because the old has value, but because textbooks and other educational materials are updated more slower than technology and not all teachers want or have the time to keep up with every new innovation. In 1982 this meant that the SuperPET needed to run BASIC programs while today the Pi needs to run Python.
Before comparing the legacy capabilities of these two computing platforms, it seems reasonable to present the finished form of Hunt the Wumpus written in Waterloo microPascal with a student-level understanding of all the latest advances in programming technology circa 1982.
Other than serving as a birthday present for Fido, another reason for writing the above code was to experience what it might have been like trying to learn structured programming with strong typing using the SuperPET. Please skip the following observations unless you have a high tolerance for boredom:
Before comparing the legacy capabilities of these two computing platforms, it seems reasonable to present the finished form of Hunt the Wumpus written in Waterloo microPascal with a student-level understanding of all the latest advances in programming technology circa 1982.
Code: Select all
(*
* wumpus.pas
*
* a translation from the c code that appears in the 7th edition
* of unix on the pdp-11 that attempts to be dynamically accurate
* by implementing the exact same random number generator. note
* the c code was written by ken thompson and apparently predates
* the 6th edition of unix by a number of years.
*
* all this was inspired by the original basic adventure games
*
* gregory yob, hunt the wumpus, posted by magnus olsson
* on usenet in 1972, pc-blue collection, simtel20.
*
* gregory yob, hunt the wumpus, people's computer company,
* vol 2, no 2, 1973, page 22.
*
* gregory yob, hunt the wumpus, creative computing, vol 1,
* no 5, 1975, pages 51-54.
*
*)
program main(input,output);
const nroom=20; ntunn=3; nbat=3; npit=3;
type int5=array[0..4] of integer;
prompt=packed array[1..25] of char;
things=(empty,epit,ebat);
var r7a,r7c,r7x:int5;
rms:array[1..nroom] of array[1..ntunn] of integer;
pits:array[1..npit] of integer;
bats:array[1..nbat] of integer;
arrow,loc,wloc:integer;
tchar:char;
blank:prompt;
procedure r7init;
begin
r7a[0]:=109; r7a[1]:=28; r7a[2]:=25; r7a[3]:=14; r7a[4]:=4;
r7c[0]:=57; r7c[1]:=96; r7c[2]:=0; r7c[3]:=0; r7c[4]:=0;
r7x[0]:=1; r7x[1]:=0; r7x[2]:=0; r7x[3]:=0; r7x[4]:=0;
blank:=' ';
end;
procedure r7mul(var r:int5;a,b:int5);
var i,j,c,p:integer;
begin
c:=0;
for i:=0 to 4 do begin
r[i]:=c; c:=0;
for j:=0 to i do begin
p:=r[i]+a[i-j]*b[j];
r[i]:=p mod 128;
c:=c+(p div 128)
end
end;
r[4]:=r[4] mod 16
end;
procedure r7add(var r:int5;a,b:int5);
var i,c,p:integer;
begin
c:=0;
for i:=0 to 4 do begin
p:=a[i]+b[i]+c;
r[i]:=p mod 128;
c:=p div 128
end
end;
procedure r7seed(x:integer);
begin
if(x>=0) then begin
r7x[0]:=x mod 128;
x:=x div 128;
r7x[1]:=x mod 128;
x:=x div 128;
r7x[2]:=x mod 4;
r7x[3]:=0; r7x[4]:=0
end else begin
x:=x+16384+16384;
r7x[0]:=x mod 128;
x:=x div 128;
r7x[1]:=x mod 128;
x:=(x div 128)+2;
r7x[2]:=x mod 4;
r7x[3]:=0; r7x[4]:=0
end
end;
function r7rand:integer;
begin
r7mul(r7x,r7x,r7a);
r7add(r7x,r7x,r7c);
r7rand:=(r7x[2] div 4)+r7x[3]*32+(r7x[4] mod 8)*4096
end;
function rnum(n:integer):integer;
begin
rnum:=trunc((r7rand/32768.0)*n)+1
end;
procedure rmsprint;
var i,j:integer;
begin
for i:=1 to nroom do begin
write(i:2,':');
for j:=1 to ntunn do begin
write(' ',rms[i][j]:2)
end;
writeln
end
end;
procedure rmsgraph;
var i,j:integer;
begin
writeln('graph maze {');
writeln(' overlap=false');
writeln(' splines=true');
writeln(' sep=1.0');
for i:=1 to nroom do begin
for j:=1 to ntunn do begin
if i<rms[i][j] then begin
writeln(' ',i:1,' -- ',rms[i][j]:1)
end
end
end;
writeln('}')
end;
function getchar:char;
var c:char;
begin
if eof then begin
getchar:=chr(0)
end else if eoln then begin
readln;
getchar:=chr(10)
end else begin
read(c);
getchar:=c
end
end;
function snarf(l:integer;p:prompt):char;
var c:char;
i:integer;
snarfed:boolean;
begin
for i:=1 to l do write(p[i]);
i:=0;
snarfed:=false;
repeat
i:=i+1;
c:=getchar;
if i>l then snarfed:=true
else if c<>p[i] then snarfed:=true
until snarfed;
while c=' ' do begin
c:=getchar
end;
snarf:=c
end;
function rin(l:integer;p:prompt):integer;
var c:char;
n:integer;
begin
c:=snarf(l,p);
n:=0;
while (c<>chr(10)) and (c<>' ') do begin
if (ord(c)<ord('0')) or (ord(c)>ord('9')) then begin
while c<>chr(10) do begin
c:=getchar
end;
n:=0;
c:=' '
end else begin
n:=n*10+ord(c)-ord('0');
c:=getchar
end
end;
rin:=n
end;
function rline(l:integer;p:prompt):char;
var c,r:char;
begin
c:=snarf(l,p);
r:=c;
while (c<>chr(10)) and (c<>' ') do begin
c:=getchar
end;
tchar:=c;
rline:=r
end;
function tunnel(i:integer):integer;
var c,j,n,r:integer;
begin
r:=0; c:=20;
repeat
n:=rnum(nroom);
while (n=i) and (c>1) do begin
c:=c-1;
n:=rnum(nroom)
end;
for j:=ntunn downto 1 do begin
if rms[n][j]=0 then r:=j
end
until r>0;
rms[n][r]:=i;
tunnel:=n
end;
procedure connect;
var i,j,k:integer;
begin
k:=1; i:=2;
while i<=nroom do begin
j:=rnum(nroom);
if (j<>k) and (rms[j][1]=0) and (rms[j][2]=0) then begin
rms[j][2]:=k; rms[k][1]:=j;
k:=j; i:=i+1
end
end
end;
function finish:boolean;
var i,j,k:integer;
r:boolean;
begin
i:=1; j:=1; r:=true;
repeat
if rms[i][j]=0 then begin
rms[i][j]:=tunnel(i)
end;
if rms[i][j]=i then begin
r:=false
end else begin
for k:=1 to j-1 do begin
if rms[i][j]=rms[i][k] then begin
r:=false
end
end
end;
if j<ntunn then begin
j:=j+1
end else begin
j:=1; i:=i+1;
end
until (not r) or (i>nroom);
finish:=r
end;
(*
* initialize the room connections
*)
procedure doinit;
var i,j,k,n:integer;
begin
repeat
for i:=1 to nroom do begin
for j:=1 to ntunn do begin
rms[i][j]:=0
end
end;
connect
until finish;
for i:=1 to nroom do begin
for j:=ntunn downto 2 do begin
for k:=j-1 downto 1 do begin
if rms[i][j]<rms[i][k] then begin
n:=rms[i][j];
rms[i][j]:=rms[i][k];
rms[i][k]:=n
end
end
end
end
end;
function occupied(n:integer):things;
var i:integer;
begin
occupied:=empty;
for i:=1 to npit do begin
if pits[i]=n then occupied:=epit
end;
for i:=1 to nbat do begin
if bats[i]=n then occupied:=ebat
end
end;
(*
* put in player, wumpus
* pits and bats
*)
procedure dosetup;
var i,n:integer;
begin
for i:=1 to npit do pits[i]:=0;
for i:=1 to nbat do bats[i]:=0;
arrow:=5;
i:=1;
while i<=npit do begin
n:=rnum(nroom);
if occupied(n)=empty then begin
pits[i]:=n;
i:=i+1
end
end;
i:=1;
while i<=nbat do begin
n:=rnum(nroom);
if occupied(n)=empty then begin
bats[i]:=n;
i:=i+1
end
end;
wloc:=rnum(nroom);
i:=1;
while i<=1 do begin
n:=rnum(nroom);
if (occupied(n)=empty) and (wloc<>n) then begin
loc:=n;
i:=i+1
end
end
end;
procedure mwump;
var i:integer;
begin
i:=rnum(ntunn+1);
if i<=ntunn then wloc:=rms[wloc][i];
end;
procedure goroom(i:integer);
begin
loc:=i;
if i=wloc then mwump
end;
function doagain:boolean;
var i,j,k,p:integer;
c:char;
bump:boolean;
begin
doagain:=true;
repeat
bump:=true;
c:=rline(20,'Move or shoot (m-s) ');
if c='m' then begin
if tchar=chr(10) then begin
i:=rin(12,'which room? ')
end else begin
i:=rin(0,blank)
end;
for j:=1 to ntunn do begin
if i=rms[loc][j] then bump:=false
end;
if bump then begin
writeln('you hit the wall')
end else begin
goroom(i)
end
end else if c='s' then begin
if tchar=chr(10) then begin
writeln('Give list of rooms terminated by 0')
end;
p:=loc; i:=1;
j:=rin(0,blank);
while (j>0) and (i<=5) do begin
repeat
for k:=1 to ntunn do begin
if j=rms[p][k] then begin
p:=j; bump:=false
end
end;
if bump then j:=rnum(nroom);
until not bump;
if j=loc then begin
writeln('You shot yourself');
j:=0; doagain:=false
end else if j=wloc then begin
writeln('You slew the wumpus');
j:=0; doagain:=false
end else begin
i:=i+1;
j:=rin(0,blank);
bump:=true
end
end;
bump:=false; arrow:=arrow-1;
if arrow=0 then begin
writeln('That was you last shot');
doagain:=false
end
end else if c='g' then begin
rmsgraph
end
until not bump
end;
function near(t:things):boolean;
var j:integer;
begin
near:=false;
for j:=1 to ntunn do begin
if occupied(rms[loc][j])=t then near:=true
end
end;
function smell:boolean;
var i,j,k:integer;
begin
smell:=false;
for j:=1 to ntunn do begin
k:=rms[loc][j];
if wloc=k then smell:=true;
for i:=1 to ntunn do begin
if wloc=rms[k][i] then smell:=true
end
end
end;
(*
* main loop of the game
*)
function status:boolean;
var alive,moved:boolean;
i:integer;
begin
alive:=true;
repeat
moved:=false;
writeln('You are in room ',loc:1);
if occupied(loc)=epit then begin
writeln('You fell into a pit');
alive:=false;
end else if loc=wloc then begin
writeln('You were eaten by the wumpus');
alive:=false;
end else if occupied(loc)=ebat then begin
writeln('Theres a bat in your room');
loc:=rnum(nroom);
moved:=true;
end
until not moved;
if alive then begin
if smell then writeln('I smell a wumpus');
if near(ebat) then writeln('Bats nearby');
if near(epit) then writeln('I feel a draft');
write('There are tunnels to');
for i:=1 to ntunn do begin
write(' ',rms[loc][i]:1)
end;
writeln;
end;
status:=alive
end;
procedure help;
begin
writeln;
writeln('Welcome to ''Hunt the Wumpus.''');
writeln('The Wumpus lives in a cave of ',nroom:1,' rooms.');
writeln('Each room has ',ntunn:1,' tunnels leading to other rooms.');
writeln;
writeln('Hazards:');
writeln;
writeln('Bottomless Pits - Some rooms have Bottomless Pits in them.');
writeln(' If you go there, you fall into the pit and lose!');
writeln('Super Bats - Some other rooms have super bats.');
writeln(' If you go there, a bat will grab you and take you to');
writeln(' somewhere else in the cave where you could');
writeln(' fall into a pit or run into the . . .');
writeln;
writeln('Wumpus:');
writeln;
writeln('The Wumpus is not bothered by the hazards since');
writeln('he has sucker feet and is too big for a bat to lift.');
writeln;
writeln('Usually he is asleep.');
writeln('Two things wake him up:');
writeln(' your entering his room');
writeln(' your shooting an arrow anywhere in the cave.');
writeln('If the wumpus wakes, he either decides to move one room or');
writeln('stay where he was. But if he ends up where you are,');
writeln('he eats you up and you lose!');
writeln;
writeln('You:');
writeln;
writeln('Each turn you may either move or shoot a crooked arrow.');
writeln;
writeln('Moving - You can move to one of the adjoining rooms;');
writeln(' that is, to one that has a tunnel connecting it with');
writeln(' the room you are in.');
writeln;
writeln('Shooting - You have 5 arrows. You lose when you run out.');
writeln(' Each arrow can go from 1 to 5 rooms.');
writeln(' You aim by telling the computer');
writeln(' The arrow''s path is a list of room numbers');
writeln(' telling the arrow which room to go to next.');
writeln(' The list is terminated with a 0.');
writeln(' The first room in the path must be connected to the');
writeln(' room you are in. Each succeeding room must be');
writeln(' connected to the previous room.');
writeln(' If there is no tunnel between two of the rooms');
writeln(' in the arrow''s path, the arrow chooses one of the');
writeln(' three tunnels from the room it''s in and goes its');
writeln(' own way.');
writeln;
writeln(' If the arrow hits the wumpus, you win!');
writeln(' If the arrow hits you, you lose!');
writeln;
writeln('Warnings:');
writeln;
writeln('When you are one or two rooms away from the wumpus,');
writeln('the computer says:');
writeln(' ''I smell a Wumpus''');
writeln('When you are one room away from some other hazard, it says:');
writeln(' Bat - ''Bats nearby''');
writeln(' Pit - ''I feel a draft''');
writeln;
end;
procedure doplay;
var alive,finished:boolean;
begin
finished:=false;
doinit;
repeat
dosetup;
alive:=true;
while alive do begin
alive:=status;
if alive then alive:=doagain
end;
if rline(20,'Another game? (y-n) ')='y' then begin
if rline(23,'Same room setup? (y-n) ')<>'y' then doinit
end else begin
finished:=true
end
until finished
end;
begin
r7init;
if rline(20,'Instructions? (y-n) ')='y' then help;
if tchar=chr(10) then begin
r7seed(rin(25,'What is the random seed? '))
end else begin
r7seed(rin(0,blank))
end;
doplay;
end.
- The built-in editor was easy to use and reasonably powerful.
- It was modal like vi but the commands were different and the regular expressions employed a different syntax.
- The keyboard mappings for page down were broken on the GTK3 version of VICE but worked using SDL.
- SDL put the open and close parenthesis above 8 and 9 like they are on the PET keyboard, this nearly ruined my typing until I discovered the GTK3 version of VICE doesn't do this.
- The strong typing rules of Pascal insisted that strings had to be the exact same length in order to be type compatible.
- Strings literals were padded with spaces to be the same length when used as function and procedure arguments.
- This trouble with Pascal strings was so annoying as to make strong typing seem like a joke--commented on, for example, in the SuperPET Gazette.
- Turbo Pascal and Free Pascal allow strings of different lengths to be type compatible.
- Pascal allows nesting of function definitions.
- I remember nested functions being quite useful in the past.
- If there had been extra credit for nesting function definitions I would surely have done so.
- Pascal's nested function definitions seem to be called closures by other students and the pseudo-intellectual elite.
- The SuperPET transmits an entire line visible on the screen--trailing blanks omitted--when the enter key is pressed.
- The prompt appears as part of the input and needs to be parsed to find what the user actually typed.
- Trying to find a way around this and failing took more time than any other part of writing the program.
- The current code works without change in environments where the prompt is not echoed back to the input.
- Waterloo microPascal enforces single-entry single-exit for functions and subroutines.
- Flags had to be set for simple tasks such as smelling a wumpus, terminating the flight of an arrow and making random graphs.
- A goto statement could have been used for multiple-exit, except for losing points for lack of structure.
- Most languages in practical use have kept the single-entry constraint but allow multiple exit.
- Waterloo microPascal is an interpreted language.
- The interactive debugger was easy to use because no new syntax was needed to to examine and change variables.
- Bounds errors and uninitialized variables were automatically caught and the system didn't crash even once.
- It took from 5 to 10 minutes to generate a regular 3-valence graph at the beginning of the Hunt the Wumpus game.
Last edited by ejolson on Wed Oct 14, 2020 4:18 am, edited 9 times in total.
Re: A Birthday Present for Fido
Interestingly the new kids on the programming language design block are intent on fixing that constraint of the structured programming idea. They have been busy adding "generators" to every possible language recently. Generators allow multiple entry points to a function depending on what state it's internals are in. Alternatively known as coroutines:
Python:https://medium.com/@chandansingh_99754/ ... 4ed9c343ae
C++ https://en.cppreference.com/w/cpp/language/coroutines
Javascript: https://developer.mozilla.org/en-US/doc ... Generators
C#: https://devblogs.microsoft.com/dotnet/i ... enerators/
Rust: https://doc.rust-lang.org/beta/unstable ... ators.html
It seems to me that for every constraint imposed by the ideals of "structured programming", that were intended to ensure one writes clear, well organized, understandable code, high level language builders have found a way to circumvent it so as to allow us to write "spaghetti".
Can't have "goto", OK we'll put exceptions in the language.
Can't have multiple entry points to a function. OK we'll put coroutines in there.
Etc, etc.
Memory in C++ is a leaky abstraction .
Re: A Birthday Present for Fido
coroutines were always implemented in languages like B and C by using longjmp().
A decent compiler might be said to should implement multiple entry points (sort of!) by "partial inlining".
That is, it will inline only that part of the function which is actually used.
It only works when it can deduce the argument value somehow.
A decent compiler might be said to should implement multiple entry points (sort of!) by "partial inlining".
That is, it will inline only that part of the function which is actually used.
It only works when it can deduce the argument value somehow.
Pi4 8GB (Raspberry Pi OS 64-bit), Pi4 4GB, Pi1 Rev 1 256MB, Pi Zero
Re: A Birthday Present for Fido
I guess that counts.
Otherwise known as "evil hackery": https://fanf.livejournal.com/105413.html
Indeed.
Compilers can do all kind of "evil hackery" under the hood. That's rather a different thing to the surface syntax and semantics that is the language itself.
Memory in C++ is a leaky abstraction .
Re: A Birthday Present for Fido
Yes of course.
Language defined multiple entry points always count as evil in my book.
Imagine the problems the linker has.
There is also the problem of initialization being bypassed etc.
In my experience (from long ago) it was done (in assembler) in the name of efficiency.
Modern compilers can execute a jump table in a couple of instructions or so.
Pi4 8GB (Raspberry Pi OS 64-bit), Pi4 4GB, Pi1 Rev 1 256MB, Pi Zero
Re: A Birthday Present for Fido
Guilty. Jumping into the middle of functions is a natural way to save code space.
Memory in C++ is a leaky abstraction .
Re: A Birthday Present for Fido
I'm not sure I understand how a generator works. Is it reentrant? Is it thread safe? What happens if the same generator is simultaneously called from two different threads? What happens if it is called again from a signal handler after having been interrupted before returning one of the generated sequence of return values?
Re: A Birthday Present for Fido
I used multiple entry for the push and pop routines of the recursive Karatsuba multiplication algorithm that appears in the classic line-numbered Basic program for the big Fibonacci challenge. While that saved one line, having multiple entry points but fewer routines made it less difficult to keep the code consistent.
In Hunt the Wumpus it would have been natural to use multiple entry to play a sequence of games without changing the maze. While it wasn't too difficult to code this functionality by passing a flag back and forth, it's not clear how that improved code readability. Maybe that's the point behind the goto madness in the Wumpus code Ken wrote for Unix.
Re: A Birthday Present for Fido
With nothing to do on a rainy Covid Monday and as an exercise in futility I tackled this very problem. The code can be de-spaghettied easily using a state machine. Arbitrary code segment reentry is done without resorting to GOTOs. No need for exotic features.ejolson wrote: ↑Tue Oct 13, 2020 3:12 pmIn Hunt the Wumpus it would have been natural to use multiple entry to play a sequence of games without changing the maze. While it wasn't too difficult to code this functionality by passing a flag back and forth, it's not clear how that improved code readability. Maybe that's the point behind the goto madness in the Wumpus code Ken wrote for Unix.
Re: A Birthday Present for Fido
I thought if a multiple-entry subroutine was the same as a coroutine, the same as a generator and nothing other than a longjmp, then surely my turbo encabutor based quantum tunneling composable Wumpus generator could be improved using closures.
Before embarking upon a study of the legacy programming environments on purpose-built educational computing devices, I wonder what pseudo-random number algorithm did BASIC on the PDP-8 use and whether the correct way to safely calculate the same sequence of numbers in Rust is with the strong data ownership of a generating coroutine.