--- title: "Spin The Bottle" id: 55210 type: "computer_media" slug: "spin-the-bottle" url: "http://localhost/computer_media/spin-the-bottle/" markdown_url: "http://localhost/computer_media/spin-the-bottle.md" published_at: "2024-06-20T11:49:58+00:00" modified_at: "2026-03-31T22:09:49+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2019/02/20230809-041332.jpg" excerpt: "A party game simulation for up to 20 players that spins a virtual bottle, pairs opposite-sex players for forfeits, and removes eliminated players by compacting its own arrays." 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/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 55220 title: "Long Island Sinclair Timex (LIST) User Group Library Tape #7" type: "computer_media" url: "http://localhost/computer_media/long-island-sinclair-timex-list-user-group-library-tape-7/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Spin%20The%20Bottle%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/06/spin-the-bottle-1.png" - url: "http://localhost/wp-content/uploads/2024/06/spin-the-bottle-2.png" media_type_tags: "Game" --- # Spin The Bottle Spin The Bottle is a party game simulation that manages up to 20 players, recording each player’s name and gender, then randomly selects pairs of opposite-sex players to perform clothing-removal forfeits. Player data is stored in two parallel arrays: a two-dimensional string array `N$(20,10)` for names and a one-dimensional array `S$(20)` for gender codes. When a player is eliminated from the game (after being selected for the bedroom sequence), the program shifts all subsequent array entries down by one index using subroutines at lines 890 and 940, effectively maintaining a compact active-player list. The random bottle spin uses `RND` to generate a target index, re-rolling if the result is out of range or matches the current player’s gender. A brief BEEP melody at line 2000 plays on exit. *** ## Program Analysis ### Program Structure The program divides into four logical phases: 1. **Initialization and player entry** (lines 10–280): Collects names and gender codes into parallel arrays, terminating on the sentinel input `"S"` or `"STOP"`. 2. **Main game loop** (lines 290–580): Iterates over the active player list, spinning the bottle and handling forfeits. 3. **Bedroom sequence** (lines 590–780): Triggered when a player is found fully undressed; removes both players from the arrays and continues or ends the round. 4. **Subroutines** (lines 890–980, 2000): Array compaction routines and a short exit melody. ### Data Storage Two parallel arrays hold all player state. `N$(20,10)` stores up to 20 names of up to 10 characters each. `S$(20)` stores single-character gender codes (`"M"` or `"F"`). The variable `T` tracks the current count of active players and is decremented as players are removed. `POKE 23658,8` at line 20 enables the caps-lock mode so that keyboard input is automatically uppercased, which is important since all gender and control comparisons expect uppercase letters. ### Player Entry Validation The entry loop at lines 90–240 validates the gender field on each iteration. If the entered gender is neither `"M"`, `"F"`, nor `"S"` (stop), the program beeps a descending tone and prompts the user to re-enter the entire record from line 100. The check at line 230 handles the edge case where the maximum of 20 players is reached without a stop sentinel, jumping directly to line 280. ### Bottle Spin and Pair Selection Lines 400–430 implement the spin. A random integer from 1 to 9 is generated with `INT (RND*9)+1`. The result is rejected and re-rolled if it falls outside the range `1` to `T`, or if the selected player shares the same gender code as the current player (`S$(Q)=S$(X)`). This guarantees an opposite-sex pairing but has a subtle bug: the upper bound of the random range is hard-coded as 9 rather than `T`, so with more than 9 active players the re-roll loop at line 420 will discard many valid results, and with exactly 1 player remaining it can loop forever. ### Array Compaction Subroutines When a pair enters the bedroom sequence, both players must be removed from the active arrays. Two subroutines handle this: - **Lines 890–930**: Shifts entries from index `Q` upward down by one, then decrements `T`. Used to remove the current player (the spinner). - **Lines 940–980**: Shifts entries from index `X` upward down by one, then decrements `T`. Used to remove the selected player (the target). Lines 720–750 call these subroutines in a specific order depending on which index is larger. By removing the higher-indexed player first, the lower index remains valid for the second removal. However, the logic at lines 720–750 is redundant and potentially incorrect: lines 720 and 730 call one subroutine each based on relative order, and then lines 740 and 750 repeat the same conditions and call the opposite subroutines — meaning both subroutines are always called regardless of order, which is the correct intent, but the conditional structure is unnecessarily convoluted. ### Timing Calculation Anomaly At line 640, the bedroom time is calculated as `INT (A*RND)*100` minutes, where `A` is a digit entered by the selected player. Because `INT` is applied before multiplying by 100, the result is always a multiple of 100 minutes (or zero). The likely intent was `INT (A*RND*100)`, which would give a finer-grained result. ### Game Termination When only one player remains (`T<2` at line 760) or the outer `NEXT Q` loop completes, the program offers to play again. Answering `"Y"` executes `RUN 10`, which resets all variables and restarts cleanly. Answering `"N"` prints `"***CHICKEN***"`, calls the melody subroutine at line 2000, and halts. Line 9997 is an unreachable `STOP` acting as a program end marker. ### Key BASIC Idioms - Double apostrophe (`''`) in `PRINT` statements inserts two blank lines efficiently. - `INPUT A$` with a preceding semicolon at line 460 keeps the cursor on the same line as the prompt. - `SAVE "SPIN T BOT" LINE 1` at line 9998 saves the program with an auto-run start line. - The FOR loop at line 435 uses `INT 10+((RND*10)+1)` as its upper bound to generate a variable-length spin sound effect — a creative misuse of the loop counter purely for its side-effect of iterating a random number of times. ## Source Code ``` 10 REM spin the bottle: RANDOMIZE 20 DIM N$(20,10): DIM S$(20): POKE 23658,8 60 PRINT ''TAB 3;"WELCOME TO SPIN THE BOTTLE" 70 PRINT 'TAB 3;"**************************"'' 80 PRINT "ENTER THE NAMES OF THE PLAYERS"'"AS FOLLOWS:"''"A MAXIMUM OF 20 PLAYERS ALLOWED"''"ENTER S,S AFTER LAST PLAYER" 90 FOR Q=1 TO 20 100 BEEP .05,5: BEEP .05,10: INPUT "PLAYER NAME";N$(Q)'"ARE YOU (M)ALE OR (F)EMALE?";S$(Q) 200 IF N$(Q)="STOP" OR N$(Q)="S" OR S$(Q)="S" THEN GO TO 280 210 IF S$(Q)="F" OR S$(Q)="M" THEN NEXT Q 230 IF Q=20 THEN GO TO 280 240 BEEP .05,-10: BEEP .05,-20: PRINT '"SEX MUST BE (M)ALE,(F)EMALE OR (S)TOP"'"TRY ENTIRE ENTRY AGAIN": GO TO 100 280 IF S$(Q)="S" THEN LET Q=Q-1: BEEP .05,10: BEEP .05,10: BEEP .05,10 290 LET T=Q 300 LET Q=1 310 LET X=0 320 FOR Q=Q TO T 330 IF S$(Q)="S" THEN LET Q=1 340 CLS 350 PRINT ''TAB 5;N$(Q)'"PRESS TO SPIN THE BOTTLE"'"********************************": BEEP .05,10: BEEP .05,5 380 INPUT A$ 400 LET X=INT (RND*9)+1 420 IF X>T OR X<1 THEN GO TO 400 430 IF S$(Q)=S$(X) THEN GO TO 400 435 FOR I=10 TO INT 10+((RND*10)+1): BEEP .05,20: BEEP .05,10: NEXT I 440 PRINT "THE BOTTLE HAS STOPPED AT"'N$(X) 460 PRINT '"IS ";N$(X)'" TOTALY NUDE YET? JUST Y OR N"; 470 INPUT A$: PRINT A$''' 490 IF A$="Y" THEN PRINT '''TAB 9;"OH GOODY!!!": PAUSE 200: GO TO 590 500 IF S$(X)="F" THEN LET H$="HER" 505 IF S$(X)<>"F" THEN LET H$="HIS" 510 BEEP .05,5: BEEP .05,10: BEEP .05,20: PRINT N$(X); " MUST ALLOW "'N$(Q);" TO REMOVE AN"'" ARTICLE OF ";H$;" CLOTHING"'''TAB 5;"PRESS ENTER WHEN DONE" 560 INPUT A$ 570 NEXT Q 580 LET Q=Q-1: GO TO 290 590 CLS 600 PRINT '''N$(X);" SELECT A NUMBER"'" BETWEEN 0 & 9"''' 610 INPUT A$ 620 LET A=VAL A$ 640 PRINT "OK ";N$(Q);" YOU MAY TAKE"'N$(X);" INTO THE BEDROOM "'"WHERE YOU MAY DO AS YOU PLEASE"'"FOR THE NEXT ";INT (A*RND)*100;" MINUTES"''''TAB 9;"*** GOOD LUCK ***" 700 PRINT '''TAB 4;"PRESS TO CONTINUE" 710 INPUT A$ 720 IF Q>X THEN GO SUB 890 730 IF X>Q THEN GO SUB 940 740 IF Q>X THEN GO SUB 940 750 IF X>Q THEN GO SUB 890 760 IF T<2 THEN GO TO 790 770 IF Q=T THEN LET Q=1 780 GO TO 320 790 CLS : PRINT '''TAB 3;"DO YOU WISH TO PLAY AGAIN"'" OR IS ONCE A NIGHT ENOUGH? " 820 INPUT A$ 830 IF A$="N" THEN PRINT ''TAB 5;"NO";: GO TO 870 840 IF A$="Y" THEN PRINT ''TAB 10;"YES": PAUSE 200: RUN 10 870 PRINT " ***CHICKEN***": GO SUB 2000: STOP 890 FOR J=Q TO T 900 LET N$(J)=N$(J+1): LET S$(J)=S$(J+1) 910 NEXT J 920 LET T=T-1 930 RETURN 940 FOR K=X TO T 950 LET N$(K)=N$(K+1): LET S$(K)=S$(K+1) 960 NEXT K 970 LET T=T-1 980 RETURN 2000 BEEP .20,17: BEEP .20,17: BEEP .20,17: BEEP .15,5: BEEP .20,14: BEEP .20,10: RETURN 9997 STOP 9998 SAVE "SPIN T BOT" LINE 1 ```