--- title: "Hanshan" id: 70791 type: "computer_media" slug: "hanshan" url: "http://localhost/computer_media/hanshan/" markdown_url: "http://localhost/computer_media/hanshan.md" published_at: "2026-08-23T15:08:09+00:00" modified_at: "2026-08-23T19:40:23+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/hansan.png" alt: "Hanshan screen" excerpt: "A poetry generator that randomly assembles Tang Dynasty-inspired verse from word and phrase arrays, with probabilistic sound effects between each stanza." 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 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Tim Hartnell" slug: "tim-hartnell" taxonomy: "indiv" url: "http://localhost/indiv/tim-hartnell/" genre: - name: "Art" slug: "art" taxonomy: "genre" url: "http://localhost/type/art/" media_type: "Program" programmers: - name: "Tim Hartnell" slug: "tim-hartnell" taxonomy: "indiv" url: "http://localhost/indiv/tim-hartnell/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Hanshan%20%281984%29%28Hartnell%2C%20Tim%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "1984" images: - url: "http://localhost/wp-content/uploads/2026/08/hansan.png" alt: "Hanshan screen" media_type_tags: "Art" --- # Hanshan Hanshan generates pseudo-haiku poetry in the style of the Tang Dynasty Buddhist hermit poet Hanshan (Cold Mountain), combining randomly selected single words and short phrases from built-in DATA statements. The program uses three distinct print patterns, each with varying TAB indentation, to create staggered verse layouts that mimic the visual structure of translated Chinese poetry. Sound effects are triggered probabilistically using RND comparisons, producing three different BEEP sequences at random intervals between verses. Two string arrays, W$(20,12) for single words and S$(20,26) for short phrases, are dimensioned and populated from DATA at initialization. The main loop runs indefinitely via GO TO 40, calculating the subroutine address as R*50+40 to dispatch to one of three pattern routines. *** ### Program Structure The program is organized into clearly delineated sections separated by REM comments. Execution begins at line 15 with display setup, then calls the initialization subroutine at line 250 before entering an infinite loop at line 40. The loop picks a random pattern number and dispatches to one of three poetry-formatting subroutines, optionally triggers sound, then repeats. | Lines | Purpose | | --- | --- | | 10–15 | Title REMs and display attribute setup | | 20–80 | Main control loop | | 100–130 | Pattern One subroutine | | 150–180 | Pattern Two subroutine | | 200–230 | Pattern Three subroutine | | 250–350 | Initialization: arrays and DATA loading | | 360–620 | DATA: 20 single words, 20 short phrases | ### Subroutine Dispatch via Arithmetic Line 50 uses the expression `GO SUB R*50+40` where `R` is 1, 2, or 3, yielding target lines 90, 140, or 190 respectively. Since those line numbers do not actually exist, the interpreter jumps to the next available line in each case: 100, 150, and 200. This is a well-known technique for computed subroutine dispatch without requiring an explicit `IF` chain. ### Array Design Two fixed-length string arrays are declared at line 280: `W$(20,12)` holds 20 single words each up to 12 characters, and `S$(20,26)` holds 20 short phrases each up to 26 characters. Both are filled sequentially from DATA at lines 290–340. Random selection from either array uses the idiom `INT(RND*20)+1` to produce a uniform integer in the range 1–20. ### Poetry Output Patterns Each of the three subroutines applies a distinct TAB indentation scheme to simulate the staggered visual layout of translated classical verse: - **Pattern One (lines 100–130):** Two words joined by `"..."` on the first line, a tabbed word with leading dots on the second, and a tabbed phrase on the third. - **Pattern Two (lines 150–180):** A phrase at column 0, a phrase with trailing `"..."` at column 3, and a phrase at column 6 — a simple stepped indent. - **Pattern Three (lines 200–230):** A word at column 3, a phrase at column 0, then a combined word and phrase joined by `", "` at column 3. ### Sound Generation Lines 60–68 implement three independent probabilistic BEEP sequences, each governed by a separate RND threshold: - Line 60: Triggered when `KK > 0.65` (35% probability); plays a four-note ascending motif with a randomly offset pitch range using `DD=RND*20-5`. - Line 65: Triggered when `KK < 0.4` (40% probability); plays a five-iteration descending/ascending pattern. Note that when `0.4 ≤ KK ≤ 0.65`, neither of these fires. - Line 68: An independent check (`RND < 0.7`, 70% probability) plays a simple chromatic run from −5 to 5 semitones. The variable `KK` is sampled once at line 60 and reused at line 65, meaning lines 60 and 65 are mutually exclusive only within the `0.4–0.65` band; below 0.4, both could fire (KK < 0.4 also satisfies the complement of KK > 0.65). In practice, when `KK < 0.4`, line 60’s condition is false, so only line 65 fires. ### Display Initialization Line 15 sets up the display using `BRIGHT 1`, `FLASH 0`, `INK 7`, `PAPER 1`, and `BORDER 1` — a white-on-blue color scheme. `BRIGHT` is set to 1 then immediately reset to 0, which has no lasting visual effect. `CLS` and `CLEAR` prepare the screen and memory before initialization. ### Notable Anomalies - The DATA at line 400 contains `"WINDING"` twice, so that word has a doubled probability of selection — likely a copy-paste oversight. - Line 70 uses `PRINT ''` (two apostrophes) to emit two blank lines between stanzas, creating visual breathing room. - The `RANDOMIZE` call at line 270 seeds the random number generator without an argument, using the system clock for a fresh seed each run. ## Source Code ``` 10 REM "HANSHAN" by Tim Hartnell 12 REM RESET 1984 15 CLS : CLEAR : BRIGHT 1: FLASH 0: INK 7: PAPER 1: BRIGHT 0: BORDER 1 20 GO SUB 250: REM Initialize 30 REM Choose pattern 40 LET R=INT (RND*3)+1 50 GO SUB R*50+40 60 LET KK=RND: IF KK>.65 THEN LET DD=RND*20-5: FOR G=DD TO DD+5: BEEP .1,3: BEEP .1,7: BEEP .1,-4: BEEP .1,G/2: NEXT G 65 IF KK<.4 THEN FOR G=1 TO 5: BEEP .1,-7: BEEP .1,G*3: BEEP .2,-2: BEEP .5,3: NEXT G 68 IF RND<.7 THEN FOR G=-5 TO 5: BEEP .1,G: NEXT G 70 PRINT '' 80 GO TO 40 90 REM *** Pattern One *** 100 PRINT W$(INT (RND*20)+1);"...";W$(INT (RND*20)+1) 110 PRINT TAB 5;"....";W$(INT (RND*20)+1) 120 PRINT TAB 8;S$(INT (RND*20)+1) 130 RETURN 140 REM ** Pattern Two ** 150 PRINT S$(INT (RND*20)+1) 160 PRINT TAB 3;S$(INT (RND*20)+1);"..." 170 PRINT TAB 6;S$(INT (RND*20)+1) 180 RETURN 190 REM *** Pattern Three *** 200 PRINT TAB 3;W$(INT (RND*20)+1) 210 PRINT S$(INT (RND*20)+1) 220 PRINT TAB 3;W$(INT (RND*20)+1);", ";S$(INT (RND*20)+1) 230 RETURN 240 REM ****************** 250 REM * INITIALIZATION * 260 CLS 270 RANDOMIZE 280 DIM W$(20,12): DIM S$(20,26) 290 FOR J=1 TO 20 300 READ W$(J) 310 NEXT J 320 FOR J=1 TO 20 330 READ S$(J) 340 NEXT J 350 RETURN 360 REM ***** DATA ***** 370 REM * SINGLE WORDS * 380 DATA "SCURRYING","TREADING","GRAZING","WITHERED","CHISELLED" 390 DATA "MUFFLED","FLANKED","WRITHED","BENDING","TWISTING" 400 DATA "HAMMERED","HANGING","WINDING","WINDING","CLEAREST" 410 DATA "EARTHWARD","CATARACT","SACRIFICIAL","SLIPPERY","ASUNDER" 420 REM * SHORT PHRASES * 430 DATA "IN THE COOL STREAM" 440 DATA "NODDED IN CLUSTERED GRACE" 450 DATA "WAVES OF COOLNESS" 460 DATA "OUT FROM THE DEEPEST" 470 DATA "SULLEN,SULLEN" 480 DATA "IN THE BLACK DARKNESS" 490 DATA "I TAKE YOUR POEMS" 500 DATA "I PUT OUT THE LAMP" 510 DATA "MY SHORT SPAN RUNS OUT" 520 DATA "THOSE THAT ARE LEFT" 530 DATA "MEN OF LEARNING" 540 DATA "MEN OF ACTION" 550 DATA "I HURRY FORWARD" 560 DATA "WHY SHOULD YOU WASTE" 570 DATA "WHEN SHALL WE MEET" 580 DATA "LITTLE SLEEPING" 590 DATA "AND MUCH GRIEVING" 600 DATA "FOR THESE FEW STEPS" 610 DATA "NOW AT DUSK" 620 DATA "I HAVE DONE WITH PROFIT" ```