# BASIC Computer Games

In 1981, I was 13 years old and teaching myself BASIC on my TRS-80 Model III from official Radio Shack manuals – accurate, comprehensive, and terminally bland.

Into that gray scene came the book *Basic Computer Games: Microcomputer Edition* (edited by David Ahl of Creative Computing magazine). It changed my life.

I can’t remember now where it came from. Neither my parents, nor my friends, nor my teachers knew much about the home computer scene. It’s possible that I found out about it in *Creative Computing* magazine and ordered it by mail, or “borrowed” it from somewhere and forgot to return it.

The book, subtitled “101 great games to play on your home computer,” was 8-bit-nerd heaven. Pages and pages of program listings in tiny, all-caps, dot matrix type, with brief introductory paragraphs. Plus, funny illustrations of strangely plausible robots. Don’t underestimate the appeal of the robots.

I spent many, many hours typing in programs from that book. Many of the games inspired variants of my own. For better or worse I became a prolific teenage BASIC programmer. I played some with Z-80 assembly and Logo and Pascal too, but the evidence of the book told me that BASIC was where the fun was at.

Fast forward to 2005. My copy of the book has long since disappeared. David Ahl has more or less retired from the computer scene, but he still has a website where he is clearing out old copies of his books and magazines. But no more copies of *Basic Computer Games* – my hopes are dashed. I email him anyway to ask about something else; he writes back and says that he does have one copy left. Cheap, too.

It arrived last week. The illustrations alone take me right back to those 8-bit days. The notes on the individual programs mean more to me now, as I can see where they connect with various threads of computing history (the original, pre-microcomputer edition of the book came out in 1973). The coding style is, well, mostly horrible by modern standards, but there’s an inspiring bright spark of fun and creativity there. And many of these programs are *classics*.

```
290 PRINT "TURN NO.";T;"WHAT IS YOUR GUESS";
300 INPUT M,N
310 FOR I=1 TO 4
320 IF P(I,1)=-1 THEN 400
330 IF P(I,1)<>M THEN 380
340 IF P(I,2)<>M THEN 380
350 P(I,1)=-1
360 PRINT "YOU HAVE FOUND MUGWUMP";I
370 GOTO 400
380 D=SQR((P(I,1)-M)^2+(P(I,2)-N)^2)
390 PRINT "YOU ARE";(INT(D*10))/10;"UNITS FROM MUGWUMP";I
400 NEXT I
```

Looking at certain pages gives me an almost physical pang. I suspect the severity of each pang is directly proportional to the number of hours I spent typing, debugging, and possibly even playing the game in question.

In a way, this book was my first open-source experience. It’s not at all clear what the licensing terms of the programs are, beyond the obvious fact that the whole book is copyrighted by Creative Computing. But redistribution was not my concern then. I wanted to see real, working code that *did* something. Something real. And what’s more real than a game of Mugwump?

My copy of the book is inscribed in the front by Ahl: “Hi Paul – Learn from the past, live for the future.” That’s a deal.

###### Update: I re-wrote one of these old games in a handful of other languages, and readers have contributed versions as well.

Jim Storch commented on Thu Jan 19 09:50:44 2006:

I remember checking out of copy of that book from the libray and typing games into an Apple II, making minor adjustments so Applebasic would be happy.

Sometimes, I still think of Eliza when chatting on an IM client: “Come come, elucidate your thoughts.”

Or those darn wild berbers, hidden in the sand…

regeya commented on Tue Jan 24 23:03:15 2006:

I have Volume 2 on my bookshelf, but not the first. I also wasted far too much time typing from that. :-)

José Santos commented on Wed Mar 1 18:55:06 2006:

Hi Paul!

I also had a BASIC book, back in the days, don’t remember the title anymore. Those were fun times. I hope to eventually locate it.

I’ve found “BASIC Computer Games” online (scanned), as well as volume 2 and lots of others. I suppose you knew about it, cause its the first hit on “basic computer games” on Google. Anyway here it is: http://www.atariarchives.org/basicgames/ , great site.

Now i’m going to have fun writing some of those good old games in Lisp. Sweet! :)

Greg Brondo commented on Fri Jan 26 00:29:00 2007:

I’ve got the same book (around the same time). It’s on my bookshelf at the office.

It’s Priceless!

M.L. commented :

I had a similar book in german discovering how to program a little text adventure. Don’t remember the name. But it was the starting point to program bigger programs and games - not just number guess. ;-)

George Beker commented :

I am indeed the guy who did the original “BekerBot” drawings - and went on to run a major PR/media firm (all Fortune 50 clients). I am now putzing with a new version of the vintage book and some new (archly cynical) drawings. Want to stay in touch? Also check me out at http://www.bekers.org

george beker commented :

This is Beker again - now there is a robot site - http://www.bekerbots.com

Phil Conrod commented :

Like you Paul, the first computer program I wrote was from the classic programming book edited by David H. Ahl on an HP 1000. Call me a little nostalgic but I also tracked down David H. Ahl to thank him for inspiring me to become a computer programmer when I was a kid. Then I did something really crazy. I asked David if I could have his permission to republish his classic programming book in a modern computer programming language so a whole new generation of kids could also be inspired by his classic book. He said yes and David then volunteered to write an updated 2010 introduction to the new book. George Beker, who illustrated several of the original books, also came out of retirement and added a few more Robot illustrations to a new Special Illustrated edition of the new 2010 book. You can now relive all those classic games like Super Star Trek, MUGWUP and Lunar LEM Rocket. The 2010 Small Basic Edition includes almost all the classic BASIC games that inspired a generation of programmers but now in Microsoft Small Basic for a new generation of kids. It was published as an E-Book so you can easily cut and paste the Small Basic Source Code right into your Small Basic Compiler. You can find out more about this new edition at http://computerscienceforkids.com/SmallBasicComputerGames.aspx. You can also find out more about Microsoft’s new Small Basic Development environment for Kids at http://www.smallbasic.com.

mr small genius commented :

well im a genius at small basic ive got a cool thing il show you now… GraphicsWindow.Hide()

gw = 800

gh = 600

GraphicsWindow.CanResize = “False”

GraphicsWindow.Top = (Desktop.Height-gh)/2

GraphicsWindow.Left = (Desktop.Width-gw)/2

GraphicsWindow.Title = “Bouncing balls with realistic collision physics”

GraphicsWindow.Width = gw

GraphicsWindow.Height = gh

GraphicsWindow.BackgroundColor = “LightBlue”

‘Reduce gw for options

gw = gw-200

GraphicsWindow.MouseDown = OnMouseDown

Start:

' Gravity, friction and attraction to mouse

grav = 0.0 ' 0 for none

fric = 0 ' 0 for none

follow = 0 ‘attract to mouse

attract = 0 ‘attract balls to each other

dt = 1 ‘timestep (speed)

shape = 0 ‘0:ball,1 square

elastic = 1 ‘1 fully elastic collisions

Colour = “Yellow”

‘Initialise some balls

radius = 20

diam = 2*radius

nball = Math.Floor(gw/diam)

istart = “True”

reset()

ireset = “False”

istart = “False”

iend = “False”

iselect = “False”

ioptions = “False”

‘Show window - an MS comment

GraphicsWindow.Show()

‘Main loop

While (“True”)

If (ioptions) Then

options()

ioptions = “False”

EndIf

energy = 0.0

isCollision = “False”

If (iselect) Then

For i = 1 To nball

```
x = Xpos[i]
y = Ypos[i]
dist = (xm-x)*(xm-x)+(ym-y)*(ym-y)
If (dist < radius*radius) Then
u = 0
v = 0
Xvel[i] = u
Yvel[i] = v
EndIf
```

EndFor

iselect = “False”

EndIf

For i = 1 To nball

update()

move()

u = Xvel[i]

v = Yvel[i]

energy = energy+(u*u+v*v)

EndFor

energy = dt*dt*energy

energy = Math.Floor(energy)

GraphicsWindow.BrushColor = “LightBlue”

GraphicsWindow.FillRectangle(gw+15,560,190,20)

GraphicsWindow.BrushColor = “Black”

GraphicsWindow.DrawText(gw+65,560,“Energy “+energy)

If (ireset) Then

reset()

ireset = “False”

EndIf

If (istart) Then

Goto Start

EndIf

If (iend) Then

Program.End()

EndIf

' If (isCollision) Then

' Sound.PlayClick()

' EndIf

Program.Delay(10)

EndWhile

‘Update ball positions

Sub update

u = Xvel[i]

v = Yvel[i]

u = Math.Min(100,Math.Max(u,-100))

v = Math.Min(100,Math.Max(v,-100))

x = Xpos[i]+dt*u

y = Ypos[i]+dt*v

bounce()

gravity()

collision()

attraction()

Xpos[i] = x

Ypos[i] = y

EndSub

‘Check for edge bounces

Sub bounce

If (x < radius) Then

Xvel[i] = -Xvel[i]

x = radius

EndIf

If (x > gw-radius) Then

Xvel[i] = -Xvel[i]

x = gw-radius

EndIf

If (y < radius) Then

Yvel[i] = -Yvel[i]

y = radius

EndIf

If (y > gh-radius) Then

Yvel[i] = -Yvel[i]

y = gh-radius

EndIf

EndSub

‘Check for collisions

Sub collision

‘Only check each pair once

For j = i+1 To nball

xi = x

yi = y

xj = Xpos[j]

yj = Ypos[j]

dx = xi-xj

dy = yi-yj

dist = Math.SquareRoot(dx*dx+dy*dy)

If (dist < diam) Then

```
isCollision = "True"
'Get ball vectors
ui = Xvel[i]
vi = Yvel[i]
uj = Xvel[j]
vj = Yvel[j]
'Move backwards (forwards if dt < 0) in time until balls are just touching
CoefA = (ui-uj)*(ui-uj)+(vi-vj)*(vi-vj)
CoefB = 2*((ui-uj)*(xi-xj)+(vi-vj)*(yi-yj))
CoefC = (xi-xj)*(xi-xj)+(yi-yj)*(yi-yj)-diam*diam
If (CoefA = 0) Then
t = -CoefC/CoefB
Else
If (dt >= 0) Then
t = (-CoefB-Math.SquareRoot(CoefB*CoefB-4*CoefA*CoefC))/(2*CoefA)
Else
t = (-CoefB+Math.SquareRoot(CoefB*CoefB-4*CoefA*CoefC))/(2*CoefA)
EndIf
EndIF
xi = xi+t*ui
yi = yi+t*vi
xj = xj+t*uj
yj = yj+t*vj
'Centre of momentum coordinates
mx = (ui+uj)/2
my = (vi+vj)/2
ui = ui-mx
vi = vi-my
uj = uj-mx
vj = vj-my
'New centre to centre line
dx = xi-xj
dy = yi-yj
dist = Math.SquareRoot(dx*dx+dy*dy)
dx = dx/dist
dy = dy/dist
'Reflect balls velocity vectors in centre to centre line
OB = -(dx*ui+dy*vi)
ui = ui+2*OB*dx
vi = vi+2*OB*dy
OB = -(dx*uj+dy*vj)
uj = uj+2*OB*dx
vj = vj+2*OB*dy
'Back to moving coordinates with elastic velocity change
e = Math.SquareRoot(elastic)
ui = e*(ui+mx)
vi = e*(vi+my)
uj = e*(uj+mx)
vj = e*(vj+my)
'Move to new bounced position
xi = xi-t*ui
yi = yi-t*vi
xj = xj-t*uj
yj = yj-t*vj
'Set velocities
Xvel[i] = ui
Yvel[i] = vi
Xvel[j] = uj
Yvel[j] = vj
'Set position
Xpos[j] = xj
Ypos[j] = yj
x = xi
y = yi
```

EndIf

EndFor

EndSub

‘Gravity and friction and follow mouse

Sub gravity

xm = GraphicsWindow.MouseX-x

ym = GraphicsWindow.MouseY-y

dist = xm*xm+ym*ym

dist = Math.Max(dist,radius*radius)

‘dist = dist*Math.SquareRoot(dist)

u = Xvel[i]

v = Yvel[i]

fricscale = (1-fric/Math.SquareRoot(1+u*u+v*v))

Xvel[i] = follow*xm/dist+fricscale*u

Yvel[i] = follow*ym/dist+fricscale*v+grav

EndSub

‘Attract-repell balls to each other

Sub attraction

If (attract <> 0) Then

For j = i+1 To nball

```
xm = Xpos[j]-x
ym = Ypos[j]-y
dist = xm*xm+ym*ym
dist = Math.Max(dist,radius*radius)
'dist = dist*Math.SquareRoot(dist)
Xvel[i] = attract*xm/dist+Xvel[i]
Yvel[i] = attract*ym/dist+Yvel[i]
Xvel[j] = attract*xm/dist+Xvel[j]
Yvel[j] = -attract*ym/dist+Yvel[j]
```

EndFor

EndIf

EndSub

‘Move ball

Sub move

ball = balls[i]

Shapes.Move(ball,x-radius,y-radius)

EndSub

‘Update options display

Sub options

GraphicsWindow.PenColor = “Black”

GraphicsWindow.DrawLine(gw,0,gw,gh)

GraphicsWindow.BrushColor = “LightBlue”

GraphicsWindow.FillRectangle(gw+10,10,190,gh-20)

For i = 0 To 5

GraphicsWindow.DrawLine(gw+10,100*i+10,gw+190,100*i+10)

EndFor

GraphicsWindow.DrawLine(gw+100,10,gw+100,510)

GraphicsWindow.BrushColor = “Black”

GraphicsWindow.DrawBoundText(gw+15,20,70,“Gravity”)

GraphicsWindow.DrawBoundText(gw+15,40,70,grav)

GraphicsWindow.DrawBoundText(gw+15,120,70,“Friction”)

GraphicsWindow.DrawBoundText(gw+15,140,70,fric)

GraphicsWindow.DrawBoundText(gw+15,220,70,“Follow”)

GraphicsWindow.DrawBoundText(gw+15,240,70,follow)

GraphicsWindow.DrawBoundText(gw+15,320,70,“Size”)

GraphicsWindow.DrawBoundText(gw+15,340,70,radius)

GraphicsWindow.DrawBoundText(gw+15,420,70,“Count”)

GraphicsWindow.DrawBoundText(gw+15,440,70,nball)

GraphicsWindow.DrawBoundText(gw+15,520,170,“Click coloured options or a ball to stop it”)

GraphicsWindow.BrushColor = “Red”

GraphicsWindow.DrawBoundText(gw+15,580,50,“RESET”)

GraphicsWindow.DrawBoundText(gw+115,580,50,“QUIT”)

GraphicsWindow.DrawBoundText(gw+15,60,70,“More”)

GraphicsWindow.DrawBoundText(gw+15,160,70,“More”)

GraphicsWindow.DrawBoundText(gw+15,260,70,“More”)

GraphicsWindow.DrawBoundText(gw+15,360,70,“More”)

GraphicsWindow.DrawBoundText(gw+15,460,70,“More”)

GraphicsWindow.BrushColor = “Blue”

GraphicsWindow.DrawBoundText(gw+15,80,70,“Less”)

GraphicsWindow.DrawBoundText(gw+15,180,70,“Less”)

GraphicsWindow.DrawBoundText(gw+15,280,70,“Less”)

GraphicsWindow.DrawBoundText(gw+15,380,70,“Less”)

GraphicsWindow.DrawBoundText(gw+15,480,70,“Less”)

GraphicsWindow.BrushColor = “Black”

GraphicsWindow.DrawBoundText(gw+115,20,70,“Speed”)

GraphicsWindow.DrawBoundText(gw+115,40,70,dt)

GraphicsWindow.DrawBoundText(gw+115,120,70,“Attraction”)

GraphicsWindow.DrawBoundText(gw+115,140,70,attract)

GraphicsWindow.DrawBoundText(gw+115,220,70,“Elastic”)

GraphicsWindow.DrawBoundText(gw+115,240,70,elastic)

GraphicsWindow.DrawBoundText(gw+115,320,70,“Colour”)

GraphicsWindow.BrushColor = “Red”

GraphicsWindow.DrawBoundText(gw+115,60,70,“More”)

GraphicsWindow.DrawBoundText(gw+115,160,70,“More”)

GraphicsWindow.DrawBoundText(gw+115,260,70,“More”)

GraphicsWindow.BrushColor = “Blue”

GraphicsWindow.DrawBoundText(gw+115,80,70,“Less”)

GraphicsWindow.DrawBoundText(gw+115,180,70,“Less”)

GraphicsWindow.DrawBoundText(gw+115,280,70,“Less”)

GraphicsWindow.BrushColor = “Red”

GraphicsWindow.DrawBoundText(gw+115,340,70,“Red”)

GraphicsWindow.BrushColor = “Blue”

GraphicsWindow.DrawBoundText(gw+115,360,70,“Blue”)

GraphicsWindow.BrushColor = “Yellow”

GraphicsWindow.DrawBoundText(gw+115,380,70,“Yellow”)

GraphicsWindow.BrushColor = “Black”

GraphicsWindow.DrawBoundText(gw+115,420,70,“Shape”)

GraphicsWindow.BrushColor = “Red”

GraphicsWindow.DrawBoundText(gw+115,440,70,“Circle”)

GraphicsWindow.DrawBoundText(gw+115,460,70,“Square”)

EndSub

‘Change settings

Sub OnMouseDown

xm = GraphicsWindow.MouseX

ym = GraphicsWindow.MouseY

‘Left column settings

If (xm > gw+15 And xm < gw+85) Then

If (ym > 60 And ym < 75) Then

```
grav = grav+0.01
```

EndIf

If (ym > 80 And ym < 95) Then

```
grav = grav-0.01
```

EndIf

If (ym > 160 And ym < 175) Then

```
fric = fric+0.001
```

EndIf

If (ym > 180 And ym < 195) Then

```
fric = fric-0.001
```

EndIf

If (ym > 260 And ym < 275) Then

```
follow = follow+1
```

EndIf

If (ym > 280 And ym < 295) Then

```
follow = follow-1
```

EndIf

If (ym > 360 And ym < 375) Then

```
radius = radius+1
diam = 2*radius
ireset = "True"
```

EndIf

If (ym > 380 And ym < 395) Then

```
radius = radius-1
radius = Math.Max(1,radius)
diam = 2*radius
ireset = "True"
```

EndIf

If (ym > 460 And ym < 475) Then

```
nball = nball+1
ireset = "True"
```

EndIf

If (ym > 480 And ym < 495) Then

```
nball = nball-1
nball = Math.Max(1,nball)
ireset = "True"
```

EndIf

If (ym > 580 And ym < 595) Then

```
istart = "True"
```

EndIf

EndIf

‘Right column settings

If (xm > gw+115 And xm < gw+185) Then

If (ym > 60 And ym < 75) Then

```
dt = dt+0.1
```

EndIf

If (ym > 80 And ym < 95) Then

```
dt = dt-0.1
```

EndIf

If (ym > 160 And ym < 175) Then

```
attract = attract+1
```

EndIf

If (ym > 180 And ym < 195) Then

```
attract = attract-1
```

EndIf

If (ym > 260 And ym < 275) Then

```
elastic = elastic+0.01
```

EndIf

If (ym > 280 And ym < 295) Then

```
elastic = elastic-0.01
```

EndIf

If (ym > 340 And ym < 355) Then

```
Colour = "Red"
ireset = "True"
```

EndIf

If (ym > 360 And ym < 375) Then

```
Colour = "Blue"
ireset = "True"
```

EndIf

If (ym > 380 And ym < 395) Then

```
Colour = "Yellow"
ireset = "True"
```

EndIf

If (ym > 440 And ym < 455) Then

```
Shape = 0
ireset = "True"
```

EndIf

If (ym > 460 And ym < 475) Then

```
Shape = 1
ireset = "True"
```

EndIf

If (ym > 580 And ym < 595) Then

```
iend = "True"
```

EndIf

EndIf

‘Select a ball

If (xm < gw) Then

iselect = “True”

EndIf

ioptions = “True”

EndSub

‘Reset new balls

Sub reset

mball = Array.GetItemCount(balls)

For i = 1 To mball

balls[i] = "”

If (istart Or i > nball) Then

```
Xpos[i] = ""
Ypos[i] = ""
Xvel[i] = ""
Yvel[i] = ""
```

EndIf

EndFor

GraphicsWindow.Clear()

options()

GraphicsWindow.BrushColor = Colour

For i = 1 To nball

If (shape = 0) Then

```
ball = Shapes.AddEllipse(diam,diam)
```

EndIf

If (shape = 1) Then

```
ball = Shapes.AddRectangle(diam,diam)
```

EndIf

balls[i] = ball

If (istart Or i > mball) Then

```
x = Math.GetRandomNumber(gw)
y = Math.GetRandomNumber(gh)
u = Math.GetRandomNumber(500)/100-3
v = Math.GetRandomNumber(500)/100-3
Xpos[i] = x
Ypos[i] = y
Xvel[i] = u
Yvel[i] = v
```

EndIf

EndFor

EndSub

this does work please leave a comment!!!