--- title: "Bowling" id: 56826 type: "computer_media" slug: "bowling" url: "http://localhost/computer_media/bowling/" markdown_url: "http://localhost/computer_media/bowling.md" published_at: "2024-09-29T07:26:01+00:00" modified_at: "2026-03-30T21:20:48+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/315_Bowl.png" excerpt: "A randomised ten-pin bowling simulator that tracks frame scores, detects strikes, and keeps a running high score across multiple games — all in under 50 lines of BASIC." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 56738 title: "Timex Sinclair Public Domain Library Tape 1007" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1007/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/09/315_Bowl.png" media_type_tags: "Game" --- 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 `Y` survives across games because the restart path is `GOTO 30` (which skips line 20 where `Y` is initialised) rather than `RUN`. - `GOSUB 500` at line 235 is only reached when `Z>9`, so the `STRIKE` message 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 not `52`, no re-knock occurs — this is correct behaviour, though slightly redundant. - Line 240 adds `Z` to `S` only when `E=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 means `Z` on 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. ## 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