--- title: "Crash" id: 57501 type: "computer_media" slug: "crash" url: "http://localhost/computer_media/crash/" markdown_url: "http://localhost/computer_media/crash.md" published_at: "2024-10-05T21:08:05+00:00" modified_at: "2026-04-03T07:58:27+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/256_Cras.png" excerpt: "Guide a falling pixel left and right with Z and M to knock it into one of three targets, deflect it back, and rack up points before your lives run out." 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: 56737 title: "Timex Sinclair Public Domain Library Tape 1006" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1006/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/256_Cras.png" media_type_tags: "Game" --- This program implements a three-lane ball-catching game in Sinclair BASIC. The player controls a moving catch zone using the Z and M keys to deflect a falling ball, which travels downward across the screen in a FOR loop from row 40 to row 2. Three targets (lanes at pixel columns 6, 26, and 46) each have a hit counter represented by a string of block-graphic characters; a successful deflection triggers a second upward ball trajectory, and scoring occurs when that ball lands at column 30. Lives are tracked in variable T (starting at 2, incremented at each round start), and the display uses inverse-video characters for the score header and lane markers. The SAVE command at line 1070 uses an inverse digit in the filename as an auto-run flag. *** ## Program Analysis ### Program Structure The program flows through a main game loop anchored at line `125` (CLS and redraw), with two inner FOR loops handling ball movement. Lines `10`–`120` perform initialisation, and line `30` is the round-start target where lives (`T`) are incremented each time all three lanes are cleared. The end-of-game sequence begins at line `325`, with a replay prompt at line `1000`. ### Game Mechanics A ball falls from pixel row 40 to row 2 (line `170`–`210`), plotted one pixel per iteration. The player steers its horizontal position `E` using Z (decrement) and M (increment) via `INKEY$`. If the ball lands at column 6, 26, or 46, the corresponding lane counter (`B`, `C`, or `D`) is decremented, and a second ball travels upward from row 2 to row 40 (lines `263`–`295`), steered by variable `G`. A score point is awarded only if this return ball reaches column 30 exactly (line `300`). ### Display Layout The screen uses a mixture of `PRINT AT`, `TAB`, and string slicing to render lane indicators. The lane hit-counters are displayed as substrings of `B$`, `C$`, `D$` sliced to lengths `B`, `C`, `D` respectively (line `150`), each initialised to `"% % % % "` (eight characters of alternating inverse-space and space). As a lane is hit, its substring shortens visually. The header line (line `135`) prints the lives counter `T` and score `X`, with an inverse-video block-graphic separator. ### Variable Reference | Variable | Purpose | | --- | --- | | `T` | Lives remaining (starts at 2, incremented each new round at line 30) | | `X` | Player score | | `B`, `C`, `D` | Hit counters for the three lanes (initially 4 each) | | `E` | Horizontal position of the falling ball | | `G` | Horizontal position of the return ball | | `F$` | Block-graphic string used for lane markers (`"\. "`) | | `B$`, `C$`, `D$` | Lane indicator strings, sliced to length of remaining hits | | `Z`, `Y` | FOR loop counters for ball row positions | | `P` | Delay loop counter at crash display | | `Q$` | Replay prompt keypress | ### Key BASIC Idioms - String slicing with `( TO B)` etc. (line `150`) shortens the displayed lane marker as hits accumulate — a compact visual depletion bar. - `INT (RND*50)+1` is used at lines `165` and `263` to randomise the starting horizontal position of each ball. - A short FOR/NEXT loop (`P=1 TO 50`, lines `343`–`344`) provides a crude delay after “CRASH” is displayed. - Lines `325`–`327` clamp lane counters from `-1` back to `0` to prevent string-slice errors on the next redraw. ### Notable Techniques and Anomalies The lives variable `T` is initialised to 2 at line `10` but is incremented at line `30` before any display, so the player effectively starts with 3 lives. Each crash decrements `T` at line `341`; when `T` reaches 0 the game ends. The condition at line `130` checks `T>0`, meaning once all lives are consumed the loop to line `30` is skipped and play falls through to the crash/end sequence on the next iteration. The ball’s horizontal position is never bounds-checked, so holding Z or M for extended periods during the fall loop can push `E` or `G` outside the valid pixel range (0–255), which would cause a BASIC error on the `PLOT` statement. There is also no check that the return ball’s column `G` stays within screen bounds. Line `1060` (`CLEAR`) and lines `1070`–`1080` are unreachable during normal play, as line `1050` (`RUN`) restarts the program before they are reached. They appear to be development/save remnants left in the listing. ## Source Code ``` 10 LET T=2 20 LET X=0 30 LET T=T+1 40 LET G=25 50 LET B=4 60 LET C=B 70 LET D=C 80 LET F$=". " 90 LET E=25 100 LET B$="% % % % " 110 LET C$=B$ 120 LET D$=B$ 125 CLS 130 IF B=0 AND C=0 AND D=0 AND T>0 THEN GOTO 30 135 PRINT TAB 0;T;TAB 14;" :% ";TAB 25;X 140 PRINT AT 1,15;F$;AT 20,3;F$;AT 20,13;F$;AT 20,23;F$ 150 PRINT AT 21,3;B$( TO B);AT 21,13;C$( TO C);AT 21,23;D$( TO D) 165 LET E=INT (RND*50)+1 170 FOR Z=40 TO 2 STEP -1 180 IF INKEY$="Z" THEN LET E=E-1 190 IF INKEY$="M" THEN LET E=E+1 200 PLOT E,Z 210 NEXT Z 230 IF E=6 THEN LET B=B-1 240 IF E=26 THEN LET C=C-1 250 IF E=46 THEN LET D=D-1 255 IF B=-1 OR C=-1 OR D=-1 THEN GOTO 325 260 IF E=6 OR E=26 OR E=46 THEN GOTO 263 262 GOTO 330 263 LET G=INT (RND*50)+1 265 FOR Y=2 TO 40 270 IF INKEY$="Z" THEN LET G=G-1 280 IF INKEY$="M" THEN LET G=G+1 290 PLOT G,Y 295 NEXT Y 300 IF G=30 THEN GOTO 315 310 GOTO 330 315 LET X=X+1 320 GOTO 125 325 IF B=-1 THEN LET B=0 326 IF C=-1 THEN LET C=0 327 IF D=-1 THEN LET D=0 330 PRINT AT 10,16;"CRASH" 341 LET T=T-1 343 FOR P=1 TO 50 344 NEXT P 346 IF T=0 THEN CLS 351 IF T=0 THEN PRINT "GAME ENDED. SCORE= ";X 353 IF T=0 THEN GOTO 1000 360 GOTO 125 1000 PRINT "AGAIN (Y/N)" 1020 LET Q$=INKEY$ 1030 IF Q$="N" THEN STOP 1040 IF Q$="" THEN GOTO 1020 1050 RUN 1060 CLEAR 1070 SAVE "1025%6" 1080 RUN ```