Everything I Needed to Know About Programming I Learned from BASIC

Now I feel OLD. I started on a PET 2001 (it is in my basement, and may be headed for Digibarn.) I agree that there are some constructs in BASIC that are bad, but that is with any language. You could even say that Pascal was designed for academia, and never should have left, but in the end, it is the programmer, not the language.

It also surprises me how many started about the same age I did, 6. Maybe that is the real key, not the language, but getting started, and thinking logically very early.

My first was a Heathkit H-8 (Intel 8008 processor). I had to build it before I could program it. My first programs were entered in octal machine code from the front panel keypad until I could afford a serial I/O card kit. I finally got it up to a whopping 24K of memory.

I miss Heathkit. I built radios, stereos, walkie-talkies, and test equipment besides the computer. I think the company is still around, but they do continuing education now, rather than hardware.

Oh wow - flashback. I had an Atari 800 (the one with the keyboard), and my mom used to program games for me on it. I was 6 - not quite at the level to start programming myself, although I could write simple programs. At any rate, there was no way to save them (except for a tape drive you had to buy separately), so you pretty much could play with your programmed game until you had to turn off the console - then goodbye cool game!

Anyway, I always think that I had a way-cool mom for that reason. She’s not even a software engineer, so extra credit for being a marketing manager and learning to program games on an atari 800 for your kid.

Several commenters have brought up the question of how to best go about introducing a young child to computer programming in this modern day and age. Jeff, I’d love to see you address that question sometime.

And yes, a “me too”: I started programming at age 5 or 6 on an IBM PC 5150 that my Dad brought home from his job at IBM. Like the Apple, Commodore, and Atari machines of the era, it booted to a BASIC programming environment if you turned on the machine with no diskette in the A: drive!

I remember that the SAVE and LOAD commands (for saving your program to a diskette, and loading it back later) would only work if you started BASIC by booting to a DOS diskette and then running BASIC (or BASICA – both were available) from that!

At least GOTO doesn’t let you jump to a location that is outside your program or doesn’t contain an instruction. Infinitely more damage has been done by improperly used strcpy() and pointer arithmetic than by GOTO.

Sorry to dredge up the old post, but I really enjoyed your article and the images of the old school keyboard controllers. Those are crazy.

I remember the hour upon hours of programming I did on the old Apple computers (in addition to playing billions of hours of games). It is amazing to think back of the progression from playing and programming dinky little games to what we do today. I run a really old school, online text game company - http://www.ironrealms.com - but it is still the same old thing, hours of endless fun playing games, and coding games.

Wouldn’t trade it for the world.

1 Like

Well, Turbo Pascal is still alive!

And I also started with ZX Spectrum and Basic. Those were the times…

1 Like

There was a 40th anniversary edition of Basic Computer Games, which apparently was updated to use Microsoft Small Basic?

They even updated the cover :heart_eyes:

Here’s an updated classic game from the book:

Civil War was written in 1968 by three Students at Lexington High School, Massachusetts: L Cram, L. Goodie, and D. Hibbard. It was modified into a 2-player game by G. Paul and R. Hess of TIES, St. Paul, Minnesota. It was ported to Microsoft Small Basic by BIBLEBYTE BOOKS in 2010.

On the left, the updated 2010 version, on the right, the 1973 original:

I have to say the rewrite is … kinda worse… than the original? Judge for yourself:

As I guessed, MS Small Basic is basically a re-skinned vb.net?

As you’d expect, most of it is public on GitHub.

1 Like

Turns out, Phil Conrod ported Hunt the Wumpus to MS Small Basic – I didn’t even realize I had this in my email from 10 years ago!

' *** HUNT THE WUMPUS ***
' By Gregory Yob
' Ported to Microsoft Small Basic by ComputerScienceForKids.com
'
TextWindow
.Write("INSTRUCTIONS (Y-N)? ")
IS = TextWindow.Read()
If
IS="N" Or IS="n" Then
GOTO LN35
EndIf
Sub375()
LN35:
' *** SET UP CAVE (DODECAHEDRAL NODE LIST) ***
SA[1][1] = 2
SA[1][2] = 5
SA[1][3] = 8
SA[2][1] = 1
SA[2][2] = 3
SA[2][3] = 10
SA[3][1] = 2
SA[3][2] = 4
SA[3][3] = 12
SA[4][1] = 3
SA[4][2] = 5
SA[4][3] = 14
SA[5][1] = 1
SA[5][2] = 4
SA[5][3] = 6
SA[6][1] = 5
SA[6][2] = 7
SA[6][3] = 15
SA[7][1] = 6
SA[7][2] = 8
SA[7][3] = 17
SA[8][1] = 1
SA[8][2] = 7
SA[8][3] = 9
SA[9][1] = 8
SA[9][2] = 10
SA[9][3] = 18
SA[10][1] = 2
SA[10][2] = 9
SA[10][3] = 11
SA[11][1] = 10
SA[11][2] = 12
SA[11][3] = 19
SA[12][1] = 3
SA[12][2] = 11
SA[12][3] = 13
SA[13][1] = 12
SA[13][2] = 14
SA[13][3] = 20
SA[14][1] = 4
SA[14][2] = 13
SA[14][3] = 15
SA[15][1] = 6
SA[15][2] = 14
SA[15][3] = 16
SA[16][1] = 15
SA[16][2] = 17
SA[16][3] = 20
SA[17][1] = 7
SA[17][2] = 16
SA[17][3] = 18
SA[18][1] = 9
SA[18][2] = 17
SA[18][3] = 19
SA[19][1] = 11
SA[19][2] = 18
SA[19][3] = 20
SA[20][1] = 13
SA[20][2] = 16
SA[20][3] = 19
' *** LOCATE LA ARRAY ITEMS ***
' *** 1-YOU, 2-WUMPUS, 3&4-PITS, 5&6-BATS ***
LN170:
TextWindow
.WriteLine("")
TextWindow
.WriteLine("SETTING UP MAZE. PLEASE WAIT.")
LN171:
For
J=1 To 6
LA[J]=Math.GetRandomNumber(20)
MA[J]=LA[J]
EndFor
' *** CHECK FOR CROSSOVERS (IE LA[1]=LA[2], ETC) ***
For
J=1 To 6
For
K=1 To 6
If
J=K Then
GOTO LN215
EndIf
If
LA[J]=LA[K] Then
GOTO LN171
EndIf
LN215:
EndFor
EndFor
' *** SET NO. OF ARROWS ***
LN230:
A=5
L=LA[1]
' *** RUN THE GAME ***
TextWindow
.WriteLine("")
TextWindow
.WriteLine("HUNT THE WUMPUS")
' *** HAZARD WARNING AND LOCATION ***
LN255:
Sub585()
' *** MOVE OR SHOOT ***
Sub670()
If
O=1 Then
GOTO LN280
EndIf
If
O=2 Then
GOTO LN300
EndIf
' *** SHOOT ***
LN280:
Sub715()
If
F=0 Then
GOTO LN255
EndIf
Goto
LN310
' *** MOVE ***
LN300:
Sub975()
If
F=0 Then
GOTO LN255
EndIf
LN310:
If
F>0 Then
GOTO LN335
EndIf
' *** LOSE ***
TextWindow
.WriteLine("HA HA HA - YOU LOSE!")
Goto
LN340
' *** MOVE ***
LN335:
TextWindow
.WriteLine("HEE HEE HEE - THE WUMPUS`LL GET YOU NEXT TIME!!")
LN340:
For
J=1 To 6
LA[J]=MA[J]
EndFor
TextWindow
.Write("SAME SETUP (Y-N)? ")
IS = TextWindow.Read()
If
IS <> "Y" And IS <> "y" Then
GOTO LN170
EndIf
Goto
LN230
Sub
Sub375
' *** INSTRUCTIONS ***
TextWindow
.Clear()
TextWindow
.WriteLine("WELCOME TO HUNT THE WUMPUS")
TextWindow
.WriteLine("")
TextWindow
.WriteLine("THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM")
TextWindow
.WriteLine("HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A")
TextWindow
.WriteLine("DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DONT KNOW")
TextWindow
.WriteLine("WHAT A DODECAHEDRON IS, ASK SOMEONE)")
TextWindow
.WriteLine("")
TextWindow
.WriteLine("HAZARDS:")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM")
TextWindow
.WriteLine(" IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU")
TextWindow
.WriteLine(" GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER")
TextWindow
.WriteLine(" ROOM AT RANDOM. (WHICH MAY BE TROUBLESOME)")
TextWindow
.WriteLine("")
TextWindow
.Pause()
TextWindow
.Clear()
TextWindow
.WriteLine("WUMPUS:")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" THE WUMPUS IS NOT BOTHERED BY HAZARDS (HE HAS SUCKER")
TextWindow
.WriteLine(" FEET AND IS TOO BIG FOR A BAT TOO LIFT). USUALLY")
TextWindow
.WriteLine(" HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOU SHOOTING AN")
TextWindow
.WriteLine(" ARROW OR YOU ENTERING HIS ROOM.")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" IF THE WUMPUS WAKES HE MOVES (P=.75) ONE ROOM")
TextWindow
.WriteLine(" OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU")
TextWindow
.WriteLine(" ARE, HE EATS YOU UP AND YOU LOSE!")
TextWindow
.WriteLine("")
TextWindow
.Pause()
TextWindow
.Clear()
TextWindow
.WriteLine("YOU:")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW.")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" MOVING: YOU CAN MOVE ONE ROOM (THRU ONE TUNNEL)")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT")
TextWindow
.WriteLine(" EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING")
TextWindow
.WriteLine(" THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO.")
TextWindow
.WriteLine(" IF THE ARROW CANT GO THAT WAY (IF NO TUNNEL) IT MOVES")
TextWindow
.WriteLine(" AT RANDOM TO THE NEXT ROOM.")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" IF THE ARROW HITS THE WUMPUS, YOU WIN.")
TextWindow
.WriteLine(" IF THE ARROW HITS YOU, YOU LOSE.")
TextWindow
.WriteLine("")
TextWindow
.Pause()
TextWindow
.Clear()
TextWindow
.WriteLine("WARNINGS:")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" WHEN YOU ARE ONE ROOM AWAY FROM A WUMPUS OR HAZARD,")
TextWindow
.WriteLine(" THE COMPUTER SAYS:")
TextWindow
.WriteLine("")
TextWindow
.WriteLine(" WUMPUS: I SMELL A WUMPUS")
TextWindow
.WriteLine(" BAT: BATS NEARBY")
TextWindow
.WriteLine(" PIT: I FEEL A DRAFT")
TextWindow
.WriteLine("")
EndSub
Sub
Sub585
'** PRINT LOCATION & HAZARD WARNINGS ***
TextWindow
.WriteLine("")
For
J=2 To 6
For
K=1 To 3
If
SA[LA[1]][K] <> LA[J] Then
GOTO LN640
EndIf
If
J-1=1 Then
GOTO LN615
EndIf
If
J-1=2 Then
GOTO LN625
EndIf
If
J-1=3 Then
GOTO LN625
EndIf
If
J-1=4 Then
GOTO LN635
EndIf
If
J-1=5 Then
GOTO LN635
EndIf
LN615:
TextWindow
.WriteLine("I SMELL A WUMPUS! ")
Goto
LN640
LN625:
TextWindow
.WriteLine("I FEEL A DRAFT ")
Goto
LN640
LN635:
TextWindow
.WriteLine("BATS NEARBY! ")
LN640:
EndFor
EndFor
TextWindow
.Write("YOU ARE IN ROOM ")
TextWindow
.WriteLine(LA[1])
TextWindow
.Write("TUNNELS LEAD TO ")
TextWindow
.Write(SA[L][1])
TextWindow
.Write(" ")
TextWindow
.Write(SA[L][2])
TextWindow
.Write(" ")
TextWindow
.WriteLine(SA[L][3])
TextWindow
.WriteLine("")
EndSub
Sub
Sub670
' *** CHOOSE OPTION ***
LN675:
TextWindow
.Write("SHOOT OR MOVE (S-M)? ")
IS = TextWindow.Read()
If
IS <> "S" And IS <> "s" Then
GOTO LN700
EndIf
O=1
Goto
ExitSub670
LN700:
If
IS <> "M" And IS <> "m" Then
GOTO LN675
EndIf
O=2
ExitSub670:
EndSub
Sub
Sub715
' *** ARROW ROUTINE ***
F=0
' *** PATH OF ARROW ***
LN735:
TextWindow
.Write("NO. OF ROOMS (1-5)? ")
J9 = TextWindow.ReadNumber()
If
J9<1 Then
GOTO LN735
EndIf
If
J9>5 Then
GOTO LN735
EndIf
For
K=1 To J9
LN760:
TextWindow
.Write("ROOM NUMBER? ")
P[K] = TextWindow.ReadNumber()
If
K<=2 Then
GOTO LN790
EndIf
If
P[K] <> P[K-2] Then
GOTO LN790
EndIf
TextWindow
.WriteLine("ARROWS ARENT THAT CROOKED - TRY ANOTHER ROOM")
Goto
LN760
LN790:
EndFor
' *** SHOOT ARROW ***
L=LA[1]
For
K=1 To J9
For
K1=1 To 3
If
SA[L][K1]=P[K] Then
GOTO LN895
EndIf
EndFor
' *** NO TUNNEL FOR ARROW ***
L=SA[L][Math.GetRandomNumber(3)]
Goto
LN900
LN840:
EndFor
TextWindow
.WriteLine("MISSED")
L=LA[1]
' *** MOVE WUMPUS ***
Sub935()
' *** AMMO CHECK ***
A=A-1
If
A>0 Then
GOTO LN885
EndIf
LN880:
F=-1
LN885:
Goto
ExitSub715
' *** SEE IF ARROW IS AT LA[1] OR AT LA[2]
LN895:
L=P[K]
LN900:
If
L <> LA[2] Then
GOTO LN920
EndIf
TextWindow
.WriteLine("AHA! YOU GOT THE WUMPUS!")
F=1
Goto
ExitSub715
LN920:
If
L <> LA[1] Then
GOTO LN840
EndIf
TextWindow
.WriteLine("OUCH! ARROW GOT YOU!")
Goto
LN880
ExitSub715:
EndSub
Sub
Sub935
' *** MOVE WUMPUS ROUTINE ***
K=Math.GetRandomNumber(4)
If
K=4 Then
GOTO LN955
EndIf
LA[2]=SA[LA[2]][K]
LN955:
If
LA[2] <> L Then
GOTO LN970
EndIf
TextWindow
.WriteLine("TSK TSK TSK - WUMPUS GOT YOU!")
F=-1
LN970:
EndSub
Sub
Sub975
' *** MOVE ROUTINE ***
F=0
LN985:
TextWindow
.Write("WHERE TO? ")
L = TextWindow.ReadNumber()
If
L<1 Then
GOTO LN985
EndIf
If
L>20 Then
GOTO LN985
EndIf
For
K=1 To 3
' *** CHECK IF LEGAL MOVE ***
If
SA[LA[1]][K]=L Then
GOTO LN1045
EndIf
EndFor
If
L=LA[1] Then
GOTO LN1045
EndIf
TextWindow
.Write("NOT POSSIBLE -")
Goto
LN985
' *** CHECK FOR HAZARDS ***
LN1045:
LA[1]=L
' *** WUMPUS ***
If
L <> LA[2] Then
GOTO LN1090
EndIf
TextWindow
.WriteLine("... OOPS! BUMPED A WUMPUS!")
' *** MOVE WUMPUS ***
Sub935()
If
F=0 Then
GOTO LN1090
EndIf
GOTO
LN1145
' *** PIT ***
LN1090:
If
L=LA[3] Then
GOTO LN1100
EndIf
If
L <> LA[4] Then
GOTO LN1120
EndIf
LN1100:
TextWindow
.WriteLine("YYYYIIIIEEEE . . . FELL IN PIT")
F=-1
GOTO
LN1145
' *** BATS ***
LN1120:
If
L=LA[5] Then
GOTO LN1130
EndIf
If
L <> LA[6] Then
GOTO LN1145
EndIf
LN1130:
TextWindow
.WriteLine("ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!")
L=Math.GetRandomNumber(20)
Goto
LN1045
LN1145:
EndSub
1 Like

Many of the things that people complain about with old line numbered BASIC simply aren’t a problem anymore. Modern BASIC language support structured programming, recursion, long variable and subroutine names, modules, etc. It is still an easy to learn language for the beginner, and if you want to write more serious programs with it, you can.

2 Likes