Conway's Game of Life in Commodore VIC-20 BASIC
By Michael Doornbos
- 7 minutes read - 1281 wordsConway’s Game of Life Explained
Conway’s Game of Life is like a simple universe with cells that are either alive (the yellow dots) or dead (empty spaces). What makes it cool is that these cells follow very basic rules, but create amazing patterns that seem to move with a mind of their own!
The Rules
Every cell follows just three simple rules in each generation:
- Survival: A living cell stays alive if it has exactly 2 or 3 living neighbors.
- Death: A living cell dies if it has fewer than 2 neighbors (loneliness) or more than 3 neighbors (overcrowding).
- Birth: A dead cell becomes alive if it has exactly 3 living neighbors.
That’s it! These rules apply to every cell on the grid at the same time.
What You’re Seeing
Our program shows a special pattern called a “glider.” It starts as a small group of 5 yellow cells. When we apply the rules:
- Some cells die because they have too many or too few neighbors
- New cells are born where exactly 3 living cells surround an empty space
- Some cells survive because they have just the right number of neighbors
The amazing thing is that after 4 generations, the pattern looks the same as it did at the start, but it has moved one space diagonally! As the generations continue, the glider “walks” across the screen.
This is why people find Conway’s Game of Life so fascinating - nobody is telling the glider to move. The movement just happens naturally from following those three simple rules. It’s like how ants build complex colonies or birds form flocks, all by following simple instructions without understanding the bigger picture.
Our VIC-20 program lets you watch this happen in real time, showing how simple rules can create things that seem alive and purposeful, even on a computer from the 1980s!
The Code
10 REM CONWAY'S GAME OF LIFE - MINIMAL VERSION
20 PRINT CHR$(147):POKE 36879,8
25 POKE 646,1:REM SET TEXT COLOR TO WHITE
30 SC=4096:CO=37888:W=15:H=10:GN=0:REM WIDER GRID WITH LESS HEIGHT
40 REM SINGLE ARRAY - CONSERVE MEMORY
50 DIM G(W,H),C(W,H)
60 FOR X=1 TO W:FOR Y=1 TO H:G(X,Y)=0:C(X,Y)=0:NEXT Y:NEXT X
70 REM SIMPLE GLIDER PATTERN
80 G(5,4)=1:G(6,5)=1:G(4,6)=1:G(5,6)=1:G(6,6)=1
90 REM DRAW INITIAL STATE
100 GOSUB 500
110 REM MAIN LOOP
115 POKE 781,0:POKE 782,0:POKE 783,0:SYS 65520:REM POSITION CURSOR AT TOP
120 PRINT"GENERATION:";GN;" ":GN=GN+1
200 REM CALCULATE NEXT STATE IN PLACE
210 FOR X=1 TO W:FOR Y=1 TO H:C(X,Y)=0:NEXT Y:NEXT X
220 FOR X=1 TO W:FOR Y=1 TO H
230 N=0
240 FOR DX=-1 TO 1:FOR DY=-1 TO 1
250 IF DX=0 AND DY=0 THEN 290
260 REM CALCULATE NEIGHBOR POSITION WITH PROPER WRAPPING
265 NX=X+DX
266 NY=Y+DY
267 REM WRAP X COORDINATE
268 IF NX<1 THEN NX=W
269 IF NX>W THEN NX=1
270 REM WRAP Y COORDINATE
275 IF NY<1 THEN NY=H
276 IF NY>H THEN NY=1
280 REM COUNT LIVE NEIGHBOR
285 IF G(NX,NY)=1 THEN N=N+1
290 NEXT DY:NEXT DX
300 C(X,Y)=0
310 IF G(X,Y)=1 AND (N=2 OR N=3) THEN C(X,Y)=1
320 IF G(X,Y)=0 AND N=3 THEN C(X,Y)=1
330 NEXT Y:NEXT X
340 REM UPDATE GRID AND DISPLAY
350 FOR X=1 TO W:FOR Y=1 TO H
360 IF G(X,Y)<>C(X,Y) THEN GOSUB 400
370 G(X,Y)=C(X,Y)
380 NEXT Y:NEXT X
390 GET K$:IF K$="Q"THEN END
395 GOTO 110
400 REM UPDATE SCREEN POSITION
410 PX=X+3:PY=Y+3:REM OFFSET TO CENTER ON SCREEN
420 LOC=SC+(PY-1)*22+(PX-1)
425 IF LOC<SC OR LOC>=SC+506 THEN RETURN
430 IF G(X,Y)=0 AND C(X,Y)=1 THEN POKE LOC,81:POKE CO+(LOC-SC),7
440 IF G(X,Y)=1 AND C(X,Y)=0 THEN POKE LOC,32:POKE CO+(LOC-SC),0
450 RETURN
500 REM DRAW FULL GRID
510 FOR X=1 TO W:FOR Y=1 TO H
520 PX=X+3:PY=Y+3:REM OFFSET TO CENTER ON SCREEN
530 LOC=SC+(PY-1)*22+(PX-1)
535 IF LOC<SC OR LOC>=SC+506 THEN 560
540 IF G(X,Y)=1 THEN POKE LOC,81:POKE CO+(LOC-SC),7
550 IF G(X,Y)=0 THEN POKE LOC,32:POKE CO+(LOC-SC),0
560 NEXT Y:NEXT X
570 RETURN
Variables Used in Conway’s Game of Life for VIC-20
Here’s a list of all the variables used in our program and their purposes:
System Variables
- SC: Screen memory starting address (4096 for expanded VIC-20)
- CO: Color memory starting address (37888 for expanded VIC-20)
- GN: Generation counter, increments with each cycle
Grid Configuration
- W: Width of the simulation grid (15 cells)
- H: Height of the simulation grid (10 cells)
- G(W,H): 2D array storing the current generation’s cell states (1=alive, 0=dead)
- C(W,H): 2D array storing the next generation’s cell states (1=alive, 0=dead)
Loop Variables
- X, Y: Loop counters for iterating through the grid
- DX, DY: Offsets for checking the 8 neighboring cells (-1, 0, or 1)
- NX, NY: Calculated neighbor coordinates with boundary wrapping applied
Display Variables
- PX, PY: Screen position coordinates (with offset for centering)
- LOC: Calculated memory location for POKEing to screen
Game Logic Variables
- N: Counter for number of live neighbors around a cell
- K$: Keyboard input variable for checking quit command
Constants
- GC: Character code for the live cell display (81, a solid block character)
Results
This is pretty calculation intensive for the VIC-20, so I’ve recorded it and sped it up. Here’s the result:
The glider pattern moves diagonally across the screen, just like it should.
How It Works
The program uses a single array to store the current state of the grid and another array to calculate the next state. This conserves memory, which is important on a system like the VIC-20 with limited resources.
The program starts with a simple glider pattern, which is a group of cells that move across the grid. It then enters a loop where it calculates the next state of the grid based on the rules of Conway’s Game of Life. It updates the grid in place, so it doesn’t need to use extra memory for a temporary array.
The program then updates the screen to show the new state of the grid.
The program continues to calculate and display new generations until you press Q
Cool, but
This is a very basic version of Conway’s Game of Life. If you want to explore more complex patterns and interactions, you can try implementing additional features like:
- Different starting patterns
- More advanced rules
- User interaction to add or remove cells
- Speed optimizations to handle larger grids
- Colorful graphics to represent different cell states
- Sound effects to accompany cell births and deaths
- Saving and loading patterns
- Running multiple simulations at once
- Parallel processing to speed up calculations
Modern Implementations
Conway’s Game of Life has been implemented in many programming languages and environments, from simple text-based versions like this one to complex graphical simulations. You can find versions that run in web browsers, on mobile devices, and even on specialized hardware like the Game of Life clock.
We’re not going to break it down, but I’ve done a more advanced version in C and put the code up on GitHub.
Here’s what it looks like running:
First 15 seconds: Random Next 15 seconds: Glider Following 15 seconds: Glider Gun
Conclusion
Conway’s Game of Life is a fascinating example of how simple rules can create complex and lifelike behavior. By following just three basic rules, cells on a grid can interact in ways that seem almost magical. Implementing the game in Commodore VIC-20 BASIC is a fun way to explore the concept and see it in action on a retro computer.
If you’re interested in learning more about Conway’s Game of Life, there are many resources available online, including tutorials, interactive simulations, and academic papers. You can also experiment with different starting patterns, rules, and optimizations to see how they affect the behavior of the system.
For more than you ever wanted to know about it, check out Stephen Wolfram’s artice: What Can We Learn about Engineering and Innovation from Half a Century of the Game of Life Cellular Automaton?.