--- title: "Keyboard" id: 57285 type: "computer_media" slug: "keyboard" url: "http://localhost/computer_media/keyboard/" markdown_url: "http://localhost/computer_media/keyboard.md" published_at: "2024-10-04T08:06:01+00:00" modified_at: "2026-03-30T21:18:38+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/173_Kbd.png" excerpt: "A ten-round typing reaction game flashes a random character on screen and waits for you to hit the matching key — how fast can you respond?" 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: "Tutorial" slug: "tutorial" taxonomy: "genre" url: "http://localhost/type/tutorial/" media_contents: - id: 56734 title: "Timex Sinclair Public Domain Library Tape 1003" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1003/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/173_Kbd.png" media_type_tags: "Tutorial" --- This program is a simple keyboard reaction trainer that challenges the player to identify and type a randomly displayed character within a short time window. On each of ten rounds, a random character from CHR$(28) to CHR$(62) is shown briefly, then cleared, and INKEY$ is used to capture the player’s single-keystroke response. A short busy-wait loop at lines 80–90 provides a fixed display window before reading input. Correct responses increment a score counter via a GOSUB subroutine, and the final score is printed after all ten rounds. *** ## Program Analysis ### Program Structure The program is organised into three logical sections: 1. **Initialisation (lines 1–10):** Clear screen and set score `N` to zero. 2. **Main game loop (lines 20–130):** Ten iterations, each showing a random character, pausing, reading a keypress, and checking for a match. 3. **End-of-game (lines 140–170):** Display final score, wait for ENTER via `INPUT I$`, then restart with `RUN`. A short subroutine at lines 200–240 handles a correct answer: it increments the score, briefly prints “YES”, waits, and returns. ### Timing Mechanism Two busy-wait loops are used for timing. The first (lines 30–40) introduces a random delay before displaying the target character, with `B` iterating from 0 to `RND*100+50`, giving a range of roughly 50–150 iterations. The second (lines 80–90) provides a fixed 30-iteration window during which the character remains visible before `INKEY$` is read at line 100. These loops are simple `FOR/NEXT` busy-waits with no body, a common idiom on this platform where a hardware timer or interrupt-driven delay is unavailable in BASIC. ### Character Generation The target character is generated at line 50 as `CHR$(28+35*RND)`. Since `RND` returns a value in [0,1), this yields character codes in the range 28–62 inclusive. This range includes several non-printable or control characters at the low end (codes 28–31) as well as printable ASCII characters from space (32) through `>` (62). This means some rounds may display invisible or oddly-behaving characters, which is a subtle bug — the intent was likely to restrict to visible printable characters. ### Input Handling `INKEY$` at line 100 reads a single keystroke without waiting. If no key is pressed at the moment of execution, `C$` remains `""` (set at line 70) and the comparison at line 110 simply fails. There is no second chance within a round; the player has only the instant the INKEY$ statement executes to have the correct key held down. ### Key BASIC Idioms - `FOR B=0 TO RND*100+50: NEXT B` — random-length busy-wait loop. - `LET C$="": ... LET C$=INKEY$` — pre-clear before reading so a missed keypress leaves an empty string. - `INPUT I$` as a “press ENTER to continue” gate before `RUN`. - `RUN` at line 170 to restart the entire program, resetting all variables. ### Score Tracking The score variable `N` is incremented only inside the subroutine at line 200, called exclusively when the typed character exactly matches the displayed one (line 110). Because `RUN` at line 170 re-executes from line 1, `N` is correctly reset to 0 at line 10 at the start of each new game. ### Bugs and Anomalies | Line | Issue | Effect | | --- | --- | --- | | 50 | `CHR$(28+35*RND)` can produce character codes 28–31 | Control characters may be displayed, making the round unwinnable or visually confusing | | 80–90 | Fixed 30-iteration busy-wait before INKEY$ | Display window is extremely short; most keypresses will be missed | | 100 | Single `INKEY$` sample with no loop | Player must hold key at exactly that moment; no polling window | ## Source Code ``` 1 REM "KEYBOARD" 5 CLS 10 LET N=0 20 FOR M=1 TO 10 30 FOR B=0 TO RND*100+50 40 NEXT B 50 LET B$=CHR$ (28+35*RND) 60 PRINT B$ 70 LET C$="" 80 FOR B=0 TO 30 90 NEXT B 100 LET C$=INKEY$ 110 IF C$=B$ THEN GOSUB 200 120 CLS 130 NEXT M 140 PRINT "SCORE= ";N 150 PRINT ,,,,"PRESS N/L" 160 INPUT I$ 170 RUN 200 LET N=N+1 210 PRINT "YES" 220 FOR B=0 TO 20 230 NEXT B 240 RETURN 250 SAVE "1017%3" 260 LIST ```