This program simulates a ten-pin bowling scoring display across ten frames, using two balls per frame. Pin states are tracked in a 10-element array where character code 52 represents a standing pin and code 61 represents a knocked-down pin, with knockdowns determined randomly via RND. The pins are displayed in the classic triangular arrangement (4-3-2-1) using CHR$ to render the pin characters. A strike (all ten pins on the first ball) branches to a subroutine that awards 15 bonus points and skips the second ball. The program maintains a running high score across multiple games using variable Y, looping back via GOTO 30 rather than restarting with RUN.
Program Analysis
Program Structure
The program is organised into three broad sections: a main game loop (lines 20–360), a strike-handling block (lines 370–440), and a strike subroutine (lines 500–510). The outer loop at line 40 iterates over 10 frames; the inner loop at line 50 iterates over 2 balls per frame. Variables Y (high score, initialised once at line 20) and S (current game score, reset at line 30) persist across game restarts because GOTO 30 is used rather than RUN, preserving Y.
Pin Representation
The 10-element array A holds the state of each pin as a character code: 52 (the character 4) for a standing pin and 61 (the character =) for a knocked-down pin. On ball 1 (when E=1), all pins are reset to 52 at line 110. On ball 2 the reset is skipped, so only pins that were left standing can be knocked down. Knockdowns are random: if a pin is standing (A(C)=52) and RND>0.5, it is set to 61.
Pin Display Layout
Lines 150–180 print the pins in the traditional triangular arrangement, with array indices mapping as follows:
| Row | Pins (array indices) |
|---|---|
| Back row (4 pins) | A(10), A(9), A(8), A(7) |
| Third row (3 pins) | A(6), A(5), A(4) |
| Second row (2 pins) | A(3), A(2) |
| Head pin (1 pin) | A(1) |
Each pin character is rendered with CHR$ (A(C)), so standing pins display as 4 and knocked-down pins as =.
Ball Label Display
Line 70 prints BALL followed by CHR$ (E+156). Since the inner loop variable E is 1 or 2, this produces characters with codes 157 and 158 — UDG characters \n and \o in TS2068 notation. These UDGs would need to be defined elsewhere for meaningful display; if undefined they show as blank or arbitrary graphics.
Scoring Logic
The count of knocked-down pins for the current ball is accumulated in Z at line 130. Strike detection occurs at line 220: if it is ball 1 and all 10 pins are down, execution jumps to line 370. The strike block awards 15 bonus points (line 410), forces E=2 (line 420) to skip the second ball’s reset, and rejoins the normal flow at line 230. For non-strike frames, if Z>9 (a spare or strike on ball 2) the score is set to 15 and the STRIKE subroutine at line 500 is called before adding to S.
Key BASIC Idioms and Techniques
PRINT AT 0,0;at line 60 resets the cursor to the top-left before each redraw, giving a simple in-place update effect without clearing the screen.INPUT U$at lines 260 and 340 is used purely as a pause/keypress wait.- The high-score variable
Ysurvives across games because the restart path isGOTO 30(which skips line 20 whereYis initialised) rather thanRUN. GOSUB 500at line 235 is only reached whenZ>9, so theSTRIKEmessage doubles as a spare/bonus notification in certain situations.
Bugs and Anomalies
- The program does not implement standard bowling scoring (carry-over of strike/spare bonus pins); instead it uses a flat 15-point bonus for strikes and spares, which simplifies but diverges from real bowling rules.
- On ball 2, the condition at line 120 still allows previously knocked-down pins (
A(C)=61) to be tested, but since they are not52, no re-knock occurs — this is correct behaviour, though slightly redundant. - Line 240 adds
ZtoSonly whenE=2, meaning ball 1 pins that are not part of a strike are never directly scored — the cumulative total across both balls is added at the end of frame 2, which is correct for a simplified model but meansZon ball 2 represents only that ball’s knockdowns, not the frame total. - Lines 520–540 (
CLEAR,SAVE,RUN) are unreachable during normal execution as no path leads there; they appear to be a save block appended outside the program flow.
Content
Source Code
10 DIM A(10)
20 LET Y=0
30 LET S=0
40 FOR B=1 TO 10
50 FOR E=1 TO 2
60 PRINT AT 0,0;
70 PRINT "FRAME ";B,"BALL ";CHR$ (E+156)
80 LET Z=0
90 FOR C=1 TO 10
100 IF E=2 THEN GOTO 120
110 LET A(C)=52
120 IF A(C)=52 AND RND>.5 THEN LET A(C)=61
130 IF A(C)=61 THEN LET Z=Z+1
140 NEXT C
150 PRINT CHR$ (A(10));" ";CHR$ (A(9));" ";CHR$ (A(8));" ";CHR$ (A(7))
160 PRINT " ";CHR$ (A(6));" ";CHR$ (A(5));" ";CHR$ (A(4))
170 PRINT " ";CHR$ (A(3));" ";CHR$ (A(2))
180 PRINT " ";CHR$ (A(1))
190 PRINT
200 PRINT
210 PRINT "SCORE THIS FRAME ";Z
220 IF E=1 AND Z=10 THEN GOTO 370
230 IF Z>9 THEN LET Z=15
235 IF Z>9 THEN GOSUB 500
240 IF E=2 THEN LET S=S+Z
250 PRINT "SCORE SO FAR ";S
260 INPUT U$
280 NEXT E
290 NEXT B
300 PRINT "SCORE FOR THAT GAME WAS ";S
310 IF S<Y THEN GOTO 330
320 LET Y=S
330 PRINT "HIGHEST SCORE SO FAR ";Y
340 INPUT U$
350 CLS
360 GOTO 30
370 CLS
390 FOR R=1 TO 200
400 NEXT R
410 LET S=S+15
420 LET E=2
430 CLS
440 GOTO 230
500 PRINT "STRIKE"
510 RETURN
520 CLEAR
530 SAVE "1031%5"
540 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
