--- title: "Bank Shot" id: 57606 type: "computer_media" slug: "bank-shot" url: "http://localhost/computer_media/bank-shot/" markdown_url: "http://localhost/computer_media/bank-shot.md" published_at: "2024-10-06T00:22:28+00:00" modified_at: "2026-04-04T08:29:05+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/bank-shot.png" excerpt: "Guide falling stars into the right column by pressing 1–5, but can you predict their diagonal path before they land?" 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: 56724 title: "Synchro-Sette June 1983" type: "computer_media" url: "http://localhost/computer_media/synchro-sette-june-1983/" media_type: "Program" mediadate: "June 1983" images: - url: "http://localhost/wp-content/uploads/2024/10/bank-shot.png" - url: "http://localhost/wp-content/uploads/2024/10/number-master-1.png" media_type_tags: "Game" --- # Bank Shot This program implements a falling-star catching game where stars drop from the top and rise from the bottom of the screen toward five scoring columns. The player watches a star fall from row 2 to row 10 along a diagonal path, then a second star rises from row 11 to row 19 along another diagonal; pressing keys 1–5 attempts to predict which column the star will land in. The program tracks which of the five columns have been hit using a DIM A(5) boolean array, awarding 100 points for correct unique guesses and stopping after four columns are occupied. Display uses PRINT AT with block graphic characters (▌ and spaces) to draw vertical bars representing the five goal columns, with inverse-video digits as column labels. *** ## Program Analysis ### Program Structure The program is organised into a loose sequence of phases rather than clearly separated subroutines. Lines 10–57 handle screen setup and variable initialisation. Lines 60–130 animate a star falling diagonally from the top half of the screen (rows 2–10). Lines 650–820 animate a second star rising from the bottom half (rows 11–19), poll for a keypress, and evaluate the result. Line 820 loops unconditionally back to line 60, creating the main game loop. The single subroutine at line 850 reads and validates the player’s key choice. ### Screen Layout The display is divided horizontally at row 10. Lines 10–30 draw a row of `▌` characters (block graphic `\:`) spanning rows 7–13 at column 1, forming a vertical divider. Line 50 then draws two rows of column markers at rows 1 and 20 using inverse-video digit characters (`%1`–`%5`) separated by groups of block graphics (`\@@`), creating five labelled goal zones. The score is displayed at row 10, column 18 via line 810. ### Diagonal Path Calculation Column selection is randomised at lines 60 and 650 with `LET X=INT(RND*5+1)`, giving a value 1–5. The horizontal step per row is computed as `Y=-(X/2+.5)`, which maps X values to fixed fractional steps: | X | Y (step) | Effect | | --- | --- | --- | | 1 | −1.0 | moves left 1 per row | | 2 | −1.5 | moves left 1.5 per row | | 3 | −2.0 | moves left 2 per row | | 4 | −2.5 | moves left 2.5 per row | | 5 | −3.0 | moves left 3 per row | For the top star (lines 80–130), the starting column is `J=(X-1)*5+10` and `J` decreases by `Y` (which is negative, so `J` increases toward the left side of the screen — effectively moving rightward in screen coordinates since J is subtracted). For the bottom star (lines 670–720), `J` starts at 2 and `J=J-Y` moves it in the opposite direction. The INT function is not applied to `J`, so PRINT AT uses non-integer column values; the BASIC interpreter silently truncates these to integers, which creates the staircase diagonal effect. ### Animation Technique Each animation step in the FOR loops prints a `"*"` at the current position, then immediately overwrites it with a space at the same position (`PRINT AT I,J;"*";AT I,J;" "`). This relies on the lack of double-buffering in the display: the `*` appears briefly before being erased, creating a moving-dot effect. The speed of the animation is determined entirely by the interpreter’s execution speed rather than any explicit PAUSE. ### Input Handling Key polling at line 715 uses `IF INKEY$<>"" THEN GOSUB 850` inside the bottom-star animation loop, checking for any keypress during the star’s ascent. The subroutine at line 850 reads `INKEY$` again into `Y$`, validates it is in the range “1”–”5″, and then at line 880 checks whether `VAL Y$=X` (correct column) and `A(X)=0` (not already scored). If both conditions hold, it jumps to line 800 to add 100 to the score. Otherwise execution falls through to line 890 which returns control to line 720, continuing the animation. ### Scoring and Win/Loss Logic The array `A(5)` (line 57) acts as a set of boolean flags, one per column. When a column is successfully hit, `A(X)` is set to 1 at line 745. The miss counter `B` is incremented at line 740 whenever the star lands without a correct guess and the column has not already been claimed. When `B` reaches 4 (line 750), `STOP` is executed at line 770, ending the game. Note that `B` is never reset within the loop, so four missed unique columns end the game. ### Notable Bugs and Anomalies - The `CLEAR` at line 52 clears all variables after the screen setup in lines 10–50, wiping any variables set before it. This is intentional as a reset but means the screen drawing code at lines 10–50 runs first to set up the display, then variables are initialised cleanly. - Line 715 calls `GOSUB 850` but the subroutine at 850 does not contain a `RETURN`; line 870 jumps to `GOTO 720` and line 880 conditionally jumps to line 800 or falls to 890 which also does `GOTO 720`. This means the subroutine never returns normally — the GOSUB stack entry is abandoned each time, which will eventually cause a GOSUB stack overflow if the game runs long enough with many keypresses. - The variable `Y$` used in the subroutine at line 850 is read from `INKEY$` a second time rather than being passed from line 715’s check, so there is a race condition: the key may have been released between the check at 715 and the read at 860, causing `Y$` to be empty and the input silently discarded. - The column landing position for the bottom star is cleared at line 730 with `PRINT AT 20,(X-1)*5+10;" "`, but the correct landing column is evaluated at line 735 after this erasure, which is the correct logical order. ## Source Code ``` 10 FOR N=7 TO 13 20 PRINT AT N,1;"\: " 30 NEXT N 50 PRINT AT 10,10;"SCORE = ";AT 1,10;"%1\@@\@@\@@\@@%2\@@\@@\@@\@@%3\@@\@@\@@\@@%4\@@\@@\@@\@@%5";AT 20,10;"%1\@@\@@\@@\@@%2\@@\@@\@@\@@%3\@@\@@\@@\@@%4\@@\@@\@@\@@%5" 52 CLEAR 55 LET S=0 56 LET B=0 57 DIM A(5) 60 LET X=INT (RND*5+1) 70 LET Y=-(X/2+.5) 80 LET J=(X-1)*5+10 90 FOR I=2 TO 10 100 PRINT AT I,J;"*";AT I,J;" " 110 LET J=J+Y 130 NEXT I 650 LET X=INT (RND*5+1) 660 LET Y=-(X/2+.5) 670 LET J=2 680 FOR I=11 TO 19 690 PRINT AT I,J;"*";AT I,J;" " 710 LET J=J-Y 715 IF INKEY$<>"" THEN GOSUB 850 720 NEXT I 730 PRINT AT 20,(X-1)*5+10;" " 735 IF A(X)=1 THEN GOTO 810 740 LET B=B+1 745 LET A(X)=1 750 IF B<4 THEN GOTO 810 770 STOP 800 LET S=S+100 810 PRINT AT 10,18;S 820 GOTO 60 850 LET Y$=INKEY$ 860 IF Y$>="1" AND Y$<="5" THEN GOTO 880 870 GOTO 720 880 IF VAL Y$=X AND A(X)=0 THEN GOTO 800 890 GOTO 720 ```