This program is a bowling average tracker for a team. It maintains a season’s worth of scores for multiple players across multiple weeks, storing three games per week per player in a three-dimensional array S(PLAYERS,WEEKS,3). The menu-driven interface uses inverse-video characters throughout for highlighted display, and navigation is handled by reading INKEY$ keycodes (29–32 correspond to ZX81 digit characters 1–4) to branch via GOTO VAL Y$*1000. Player statistics including high game, high series, and a rounded average are calculated on demand, with an optional COPY command to print the display. Data can be saved to tape under a user-supplied filename.
Program Analysis
Program Structure
The program is organized as a menu-driven application with five functional modules, each beginning at a round-thousand line number. The main menu loop lives at lines 100–250, and each menu option jumps to its module via GOTO VAL Y$*1000. All modules return to the main menu at line 100 when finished.
| Line range | Module | Function |
|---|---|---|
| 100–250 | Main menu | Display options, read keypress, dispatch |
| 1000–1260 | Initialize | Set up season dimensions and player names |
| 2000–2250 | Enter scores | Input three games per player per week |
| 3000–3420 | Display player data | Show high game, high series, average |
| 4000–4920 | Edit data | Change scores or player name |
| 5000–5050 | Save to tape | SAVE under user-supplied filename |
| 9997–9999 | Bootstrap | Initial SAVE of the program itself, then GO TO 1 |
Data Storage
Three arrays are allocated dynamically after the user supplies season parameters. The core score store is a three-dimensional numeric array S(PLAYERS,WEEKS,3), holding all three games for every player and every week. Player names are held in the string array P$(PLAYERS,32), and weekly series totals in T(WEEKS). The variable R1, initialized to 0 at line 10 and incremented at line 2010, serves as the current-week counter and is tested at lines 3000 and 2020 as a guard against accessing uninitialized data.
Menu Dispatch Idiom
The main menu reads a single keypress into Y$ at line 200. Line 220 validates it by checking CODE Y$ against the range 29–32, which are the ZX81 internal codes for the digit characters “1” through “4” (not ASCII). The dispatch at line 250 uses GOTO VAL Y$*1000: VAL Y$ converts the character to its numeric value (1–4), multiplied by 1000 to reach the correct module entry point. Option “5” (save) is listed on the menu but the code range check excludes code 33 (“5”), so saving can only be reached if the validation is relaxed — this is a latent bug: the guard at line 220 allows codes 29–32 only, excluding the “5” option shown on screen.
Player Name Matching
Both the display (line 3040) and edit (line 4050) modules search for a player by comparing the user’s input N$ against a leading substring of each stored name: IF N$=P$(A, TO LEN N$). This allows partial-name lookup, so entering just the first few letters is sufficient to identify a player.
Statistics Calculation
The display module (lines 3130–3340) makes a single pass through all recorded weeks for the selected player. It tracks high single game (HIGAME), high three-game series (HISERIES), total pins (TPINS), and total games played (TGAMES). The average is computed as TPINS/TGAMES and rounded to two decimal places using the expression INT(100*AVERAGE+.05)/100 at line 3330, which implements standard rounding by adding half a unit before truncating.
Notable Techniques
- FAST/SLOW bracketing: Computationally intensive sections (screen build, array allocation) are wrapped in
FAST/SLOWpairs to suppress display flicker during processing while still accepting input in SLOW mode. - PAUSE 40000 as a display hold: Used after showing statistics and series totals, giving the user time to read before the program continues. The value 40000 is close to the maximum (65535 would be the absolute limit) and provides a very long wait.
- Optional COPY at line 3410: After the statistics pause, pressing “Z” triggers a
COPYto print the screen contents, allowing a paper record of a player’s data. - VAL Y$*1000 dispatch: A compact idiom avoiding a chain of IF statements for menu routing.
- Bootstrap lines 9997–9999: Line 9998 saves the program under the name “BOWLIN
%G” (the%Grenders as inverse “G” on screen), and line 9999GOTO 1— since line 1 does not exist, this is the well-known technique of jumping to a non-existent line, which in practice falls through to the next available line (line 10), effectively auto-starting after the save.
Content
Source Code
0 % % % %B%O%W%L%I%N%G% % % % %W%R%I%T%T%E%N% % %B%Y% % % %G%E%N%E% %B%U%Z%A% %
10 LET R1=0
100 FAST
110 CLS
120 PRINT AT 1,7;"% %B%O%W%L%I%N%G% %A%V%E%R%A%G%E% "
130 PRINT AT 4,0;"% %T%O% %I%N%I%T%I%A%L%I%Z%E% ";TAB 31;"%1"
140 PRINT AT 6,0;"% %T%O% %E%N%T%E%R% %S%C%O%R%E%S% ";TAB 31;"%2"
150 PRINT AT 8,0;"% %T%O% %D%I%S%P%L%A%Y% %P%L%A%Y%E%R% %D%A%T%A% ";TAB 31;"%3"
160 PRINT AT 10,0;"% %T%O% %E%D%I%T% %D%A%T%A% ";TAB 31;"%4"
170 PRINT AT 12,0;"% %T%O% %S%A%V%E% %O%N% %T%A%P%E% ";TAB 31;"%5"
190 SLOW
200 LET Y$=INKEY$
210 PRINT AT 21,4;"ENTER ONE OF ABOVE ::";AT 21,4;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% %:%:"
220 IF CODE Y$<29 OR CODE Y$>32 THEN GOTO 200
230 FAST
240 CLS
250 GOTO VAL Y$*1000
1000 PRINT "HOW MANY WEEKS IS THE SEASON? ";
1010 SLOW
1020 INPUT WEEKS
1030 PRINT WEEKS
1040 PRINT ,,"HOW MANY PLAYERS ON THE TEAM? ";
1050 INPUT PLAYERS
1060 PRINT PLAYERS
1100 DIM S(PLAYERS,WEEKS,3)
1110 DIM P$(PLAYERS,32)
1120 DIM T(WEEKS)
1190 CLS
1200 FOR N=1 TO PLAYERS
1210 PRINT "NAME OF PLAYER NO.";N
1220 INPUT P$(N)
1230 PRINT P$(N)
1240 PRINT
1250 NEXT N
1260 GOTO 100
2000 SLOW
2010 LET R1=R1+1
2020 IF R1=WEEKS THEN GOTO 2500
2100 FOR N=1 TO PLAYERS
2110 CLS
2120 PRINT "SCORE FOR WEEK NO.";R1;" FOR"
2130 PRINT P$(N)
2140 FOR I=1 TO 3
2150 PRINT "GAME NO.";I;
2160 INPUT S(N,R1,I)
2170 PRINT TAB 29;S(N,R1,I)
2180 PRINT
2190 NEXT I
2200 LET T(R1)=S(N,R1,1)+S(N,R1,2)+S(N,R1,3)
2210 PRINT "SERIES =";TAB 29;T(R1)
2220 PAUSE 40000
2230 CLS
2240 NEXT N
2250 GOTO 100
3000 IF R1=0 THEN GOTO 100
3010 PRINT AT 1,2;"% %W%H%A%T% %I%S% %T%H%E% %P%L%A%Y%E%R:.%S% %N%A%M%E% "
3015 SLOW
3020 INPUT N$
3025 FAST
3030 FOR A=1 TO PLAYERS
3040 IF N$=P$(A, TO LEN N$) THEN GOTO 3100
3050 NEXT A
3060 PRINT ,,N$;" NOT IN FILE."
3070 PAUSE 40000
3080 GOTO 100
3100 CLS
3110 PRINT "BOWLING DATA FOR :::",P$(A)
3120 FAST
3130 LET HIGAME=0
3135 LET TPINS=0
3136 LET TGAMES=0
3140 LET HISERIES=0
3150 FOR B=1 TO R1
3160 LET SERIES=0
3170 FOR C=1 TO 3
3175 LET TGAMES=TGAMES+1
3180 LET GAME=S(A,B,C)
3185 LET TPINS=TPINS+GAME
3190 IF GAME>HIGAME THEN LET HIGAME=GAME
3200 LET SERIES=SERIES+GAME
3210 NEXT C
3220 IF SERIES>HISERIES THEN LET HISERIES=SERIES
3230 NEXT B
3300 PRINT ,,"% %H%I%G%H% %G%A%M%E% %=% ",HIGAME
3310 PRINT ,,"% %H%I%G%H% %S%E%R%I%E%S% %=",HISERIES
3320 LET AVERAGE=TPINS/TGAMES
3330 LET AVERAGE=INT (100*AVERAGE+.05)/100
3340 PRINT ,,"% %A%V%E%R%A%G%E% %=% ",AVERAGE
3400 PAUSE 40000
3410 IF INKEY$="Z" THEN COPY
3420 GOTO 100
4000 PRINT ,,"% %W%H%A%T% %I%S% %T%H%E% %P%L%A%Y%E%R%S% %N%A%M%E%?% "
4010 SLOW
4020 INPUT N$
4030 FAST
4040 FOR A=1 TO PLAYERS
4050 IF N$=P$(A, TO LEN N$) THEN GOTO 4100
4060 NEXT A
4070 GOTO 3060
4100 CLS
4110 PRINT ,,P$(A)
4120 PRINT ,,"% %C%H%A%N%G%E% %N%A%M%E%?% "
4130 PAUSE 40000
4140 IF INKEY$="Y" THEN GOTO 4900
4150 CLS
4160 PRINT ,,"WHAT WEEK?"
4170 SLOW
4180 INPUT WW
4190 FAST
4220 PRINT
4230 FOR N=1 TO 3
4240 PRINT N,S(A,WW,N)
4250 NEXT N
4260 PRINT ,,"WHICH GAME (1, 2,3 OR 0 TO EXIT)DO YOU WANT TO CHANGE?"
4265 SLOW
4270 LET W$=INKEY$
4271 IF CODE W$<28 OR CODE W$>31 THEN GOTO 4270
4272 IF W$="0" THEN GOTO 100
4275 FAST
4276 LET WG=VAL W$
4280 IF WG>3 OR WG<1 THEN GOTO 4270
4290 PRINT ,,"NEW GAME TOTAL?"
4295 SLOW
4300 INPUT NG
4305 FAST
4310 IF NG<0 OR NG>300 THEN GOTO 4295
4320 LET S(A,WW,WG)=NG
4330 GOTO 100
4900 PRINT ,,"WHAT IS THE NEW NAME?"
4905 SLOW
4910 INPUT P$(A)
4920 GOTO 100
5000 PRINT ,,"ENTER THE FILE NAME, PEPARE THE RECORDER AND PRESS ENTER :::"
5010 SLOW
5020 INPUT F$
5030 FAST
5040 SAVE F$
5050 GOTO 100
9997 STOP
9998 SAVE "BOWLIN%G"
9999 GOTO 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
