Blackjack

This file is part of and CATS Library Tape 1. Download the collection to get this file.
Developer(s): Werner Kaelin
Date: 198x
Type: Program
Platform(s): TS 2068

This program implements a complete Blackjack card game for two players (human vs. computer dealer). Cards are represented using a three-dimensional string array `A$` dimensioned at 52×6×3, storing each card’s face in six rows of three characters, with suit symbols rendered via four user-defined graphics (UDGs) defined by DATA statements poked into UDG memory. The deck is tracked as a 104-character string `Z$` encoding card value and suit index pairs, from which cards are randomly selected and removed during play. Scoring handles aces flexibly using variables `G` (ace count) and `BJ` (blackjack flag), with payouts of 1×, 2×, and 3× the bet for wins, five-card tricks, and blackjack respectively.

Adapted by Werner Kaelin from a program written by Gwyn Dewey, published in 51 Game Programs for the Timex Sinclair 1000 and 1500.


Program Analysis

Program Structure

The program begins with a GO TO 3350 at line 1000, jumping immediately to the initialization block. The overall flow is:

  1. Lines 3350–3590: Initialization, UDG setup, title screen, and card array construction
  2. Lines 2310–2390: Deck/display reset loop, re-entry point for new hands
  3. Lines 1210–1270: Draw card table graphics (slot positions for two hands)
  4. Lines 1310–1610: Player’s turn — deal, score, hit/stay logic
  5. Lines 1620–1940: Dealer’s turn — draw until beating player or busting
  6. Lines 1950–1990: Bet input subroutine
  7. Lines 2000–2290: Outcome display and payout handling
  8. Lines 2480–3330: Card face construction subroutine (fills A$)
  9. Lines 4000–4190: UDG data and POKE routine
  10. Lines 5000–5210: Animated border drawing with random UDG color sequence
  11. Line 9900: SAVE/VERIFY utility

Card Representation

The deck string Z$ (line 2310) is a 104-character string encoding 52 cards as letter–digit pairs: letters A–M represent Ace through King, and digits 0–3 represent the four suits. A random card is selected by picking a random odd index D into Z$ (line 1010), reading Z$(D) for rank and Z$(D+1) for suit. The selected pair is then spliced out of Z$ (line 1070), ensuring each card is dealt only once. The variable F tracks remaining cards and triggers a reshuffle when fewer than 9 remain (line 2310).

Card Face Rendering

Card faces are stored in A$, a three-dimensional string array dimensioned 52×6×3 (52 card ranks across four suits × 6 rows × 3 characters per row). The subroutine at line 2480 populates each card’s six display rows. Number cards use combinations of the suit UDG character (F$) arranged as G$ (single centered), H$ (two side-by-side), or I$ (three), matching pip layout conventions. Court cards (J, Q, K) use block graphics characters to create simple face figures. The correct row is accessed as A$((CODE Z$(D)-64)+(VAL Z$(D+1)*13), N) at line 1040, combining rank offset and suit-group offset.

UDG Definitions

Seven UDGs are defined at lines 4000–4190 using POKE into addresses from USR "A" to USR "G"+7. Their purposes are:

UDGEscapePurpose
A\aHeart suit symbol
B\bClub suit symbol
C\cDiamond suit symbol
D\dSpade suit symbol
E\eLeft card border
F\fRight card border
G\gCard bottom border

Scoring Logic

Two parallel scoring subroutines exist: lines 1090–1130 for the player (accumulating into T) and lines 1150–1190 for the dealer (accumulating into U). Both use the same logic: ranks B–I (2–9) contribute their face value via CODE E$(I)-64; ranks J–M (10, J, Q, K) contribute 10; rank K sets the blackjack flag BJ; and rank A adds 11 while incrementing the ace counter G. Ace softening is handled at lines 1410, 1550–1560, and 1760, 1910–1920: when a hand exceeds 21 and G>0, one ace is converted from 11 to 1 by subtracting 10 from the total and decrementing G.

Card INK Color for Red Suits

At line 1020, A=2*(INT (VAL Z$(D+1)/2)) computes INK color: suits 0 and 1 yield A=0 (black), suits 2 and 3 yield A=2 (red). For court cards (rank > “J”), the color is inverted on rows 3 and 4 (line 1035, AA=2-A), swapping black↔red to create a visual contrast effect on the face figure.

Betting and Payouts

The player starts with $100 (line 3380). Bets are entered as a single character via INPUT and validated to be a digit between 1 and the current balance (lines 1955–1990). Payouts are:

  • Normal win: +1× bet (line 2110)
  • Five-card trick win: +2× bet (line 2140)
  • Blackjack win: +3× bet (line 2170)
  • Normal loss: −1× bet (line 2050)
  • Dealer five-card trick: −2× bet (line 2010)
  • Dealer blackjack: −3× bet (line 2080)

When the balance reaches zero or below (line 1310), the player is notified and the balance is reset to $100 (line 2260).

Animated Border Subroutine

The subroutine at lines 5000–5210 draws a decorative animated border by printing randomly colored UDG characters (A–D) around the screen perimeter. The helper at line 5200 picks a random UDG index 0–3, sets INK to 0 or 2 (black or red), and plays a brief tone. This subroutine is also used to trigger card face construction: the IF AA THEN guards at lines 5035, 5065, 5095, and 5130 call GO SUB 2480 for each of the four suits during the first run.

Notable Techniques

  • The deck string splice at line 1070 (Z$=Z$(TO D-1)+Z$(D+2 TO)) efficiently removes a dealt card without maintaining a separate index array.
  • The PAUSE 0 / INKEY$ idiom at lines 1470–1480 waits for a keypress and branches immediately on the next line without a loop.
  • The rotating title-screen ticker at lines 3530–3570 cycles B$ by taking B$(2 TO)+B$(1) each iteration, producing a scrolling marquee effect.
  • The AND conditional string expression at line 2330 (("NEW DECK" AND F=52)) prints “NEW DECK” only when a fresh deck is in play, a standard Sinclair BASIC trick.
  • Variable reuse: Z, H, I, N serve double duty as both loop counters and card-position/screen coordinates across different subroutines.

Anomalies and Observations

Line 1480 checks INKEY$ immediately after PAUSE 0 has already consumed the keypress event, meaning the INKEY$="H" branch at line 1480 may not trigger reliably; the program falls through to line 1500 directly in most cases, which is harmless since line 1500 is the hit routine. The GO TO 1500 at line 1480 and the label at line 1500 are effectively the same destination. Line 1350 calls GO SUB 1950 only when I=2, invoking the bet-input routine before dealing the second initial card to the player — a slightly unconventional placement but functionally correct since the bet must be placed before play begins.

Content

Appears On

Capital Area Timex Sinclair User Group’s Library Tape.

Related Products

Related Articles

Related Content

Image Gallery

Blackjack

Source Code

 1000 GO TO 3350
 1010 LET D=((INT (RND*F))*2)+1
 1020 LET F=F-1: PAPER 7: LET A=2*(INT (VAL Z$(D+1)/2))
 1030 FOR N=1 TO 6: LET AA=A
 1035 IF (N=3 OR N=4) AND Z$(D)>"J" THEN LET AA=2-A
 1040 PRINT AT Z+N,H-1;"\e";: PRINT INK AA;A$((CODE Z$(D)-64)+(VAL Z$(D+1)*13),N);: PRINT "\f"
 1050 NEXT N
 1055 BEEP .005,5
 1060 LET E$(I)=Z$(D)
 1070 LET Z$=Z$( TO D-1)+Z$(D+2 TO )
 1080 PAPER 4: INK 0: RETURN 
 1090 IF E$(I)>="B" AND E$(I)<="I" THEN LET T=T+CODE E$(I)-64
 1100 IF E$(I)>"I" THEN LET T=T+10
 1110 IF E$(I)="K" THEN LET BJ=1
 1120 IF E$(I)="A" THEN LET T=T+11: LET G=G+1
 1130 RETURN 
 1150 IF E$(I)>="B" AND E$(I)<="I" THEN LET U=U+CODE E$(I)-64
 1160 IF E$(I)>"I" THEN LET U=U+10
 1170 IF E$(I)="K" THEN LET BJ=1
 1180 IF E$(I)="A" THEN LET U=U+11: LET G=G+1
 1190 RETURN 
 1210 OVER 1: INK 0
 1220 FOR Z=3 TO 13 STEP 10
 1230 FOR H=3 TO 23 STEP 5
 1240 PRINT PAPER 4;AT Z-1,H;"_____";AT Z,H;"\e   \f";AT Z+1,H;"\e   \f";AT Z+2,H;"\e   \f";AT Z+3,H;"\e   \f";AT Z+4,H;"\e   \f";AT Z+5,H;"\e   \f";AT Z+6,H;"\g\g\g\g\g"
 1250 PRINT PAPER 6;AT Z,H;" ▄ ▄ ";AT Z+1,H;" ▚▀▞ ";AT Z+2,H;" ▌▛▟ ";AT Z+3,H;" ▛▟▐ ";AT Z+4,H;" ▞▄▚ ";AT Z+5,H;" ▀ ▀ ": REM Werner Kaelin 1984/85
 1260 BEEP .02,H: NEXT H: NEXT Z: OVER 0
 1270 LET Z=12
 1280 LET G=0
 1290 LET T=0
 1300 LET BJ=0
 1310 IF BET<=0 THEN GO TO 2250
 1320 LET H=-1
 1330 FOR I=1 TO 2
 1340 LET H=H+5
 1350 IF I=2 THEN GO SUB 1950
 1360 GO SUB 1010
 1370 NEXT I
 1380 FOR I=1 TO 2
 1390 GO SUB 1090
 1400 NEXT I
 1410 IF T=22 THEN LET G=G-1: LET T=T-10
 1430 IF G=1 AND BJ=1 THEN GO TO 2160
 1440 IF T=21 THEN GO TO 2190
 1450 LET V=2
 1460 PAPER 4: INK 0: PRINT AT J,K;"<H>IT ME OR <S>TAY?";AT 11,19;"TOTAL ";T;" "
 1470 PAUSE 0
 1475 IF INKEY$="S" OR INKEY$="s" THEN GO TO 1620
 1480 IF INKEY$="H" OR INKEY$="h" OR INKEY$=" " THEN GO TO 1500
 1500 PRINT AT J,1;C$
 1510 LET H=H+5: GO SUB 1010
 1530 GO SUB 1090
 1540 IF T>21 AND G=0 THEN GO TO 2210
 1550 IF T>21 AND G>0 THEN LET G=G-1
 1560 IF T>21 THEN LET T=T-10
 1570 LET V=V+1
 1580 IF V=5 THEN GO TO 2130
 1590 IF T=21 THEN GO TO 2190
 1600 LET I=I+1
 1610 GO TO 1460
 1620 PRINT AT 11,19;" STAY ";T
 1630 PRINT AT J,K;"COMPUTER DRAWS      "
 1640 LET U=0
 1650 LET G=0
 1660 LET BJ=0
 1670 LET Z=2
 1680 LET H=-1
 1690 FOR I=1 TO 2
 1700 LET H=H+5
 1710 GO SUB 1010
 1720 NEXT I
 1730 FOR I=1 TO 2
 1740 GO SUB 1150
 1750 NEXT I
 1760 IF U=22 THEN LET G=G-1: LET U=U-10
 1780 IF G=1 AND BJ=1 THEN GO TO 2070
 1790 LET C=2
 1800 IF U=21 THEN GO TO 2030
 1810 IF U>=T AND V<5 THEN GO TO 2230
 1820 PRINT AT 11,K;"TOTAL ";U
 1825 PAUSE 50
 1830 LET H=H+5
 1840 LET C=C+1
 1850 GO SUB 1010
 1860 GO SUB 1150
 1865 PRINT AT 10,1;C$
 1870 IF U>21 AND G<=0 THEN GO TO 2100
 1880 IF C=5 AND U<=21 THEN GO TO 2000
 1890 IF V=5 AND C=5 THEN GO TO 2030
 1900 LET B=U
 1910 IF U>21 AND G>0 THEN LET U=U-10
 1920 IF B>21 AND G>0 THEN LET G=G-1
 1930 LET I=I+1
 1940 GO TO 1800
 1955 FOR N=0 TO 20: BEEP .03,N: NEXT N
 1960 PAPER 4: INK 0: INPUT TAB 6; FLASH 1;" PLACE YOUR BET ";G$: FLASH 0: LET GO=CODE G$
 1965 IF GO<48 OR GO>57 THEN GO TO 1955
 1970 LET GOBET=VAL G$: IF GOBET<1 OR GOBET>BET THEN GO TO 1955
 1975 PRINT AT J,1;C$;AT 11,1;C$
 1980 PAPER 1: INK 6: PRINT AT 20,24-LEN G$; BRIGHT 1;" BET $";GOBET;" "
 1990 PAPER 4: INK 0: RETURN 
 2000 PRINT AT J,K;"OOH  A FIVE CARDER";AT 11,1;C$;AT 11,16;"I WIN DOUBLE"
 2010 LET BET=BET-(GOBET*2)
 2020 GO TO 2290
 2030 PRINT AT J,K;"TWENTY-ONE     "
 2040 PRINT AT 11,K;"              I WIN ...  "
 2050 LET BET=BET-GOBET
 2060 GO TO 2290
 2070 PRINT AT J,K;"OH DEAR BLACKJACK";AT 11,1;C$;AT 11,16;"I WIN TREBLE"
 2080 LET BET=BET-(GOBET*3)
 2090 GO TO 2290
 2100 PRINT AT J,K;"CURSES...";AT 11,K;"     I BUST >>> YOU WIN"
 2110 LET BET=BET+GOBET
 2120 GO TO 2290
 2130 PRINT AT J,K;"CURSES...";AT 11,K;"FIVE CARDER WINS DOUBLE"
 2140 LET BET=BET+(GOBET*2)
 2150 GO TO 2290
 2160 PRINT AT J,K;"CURSES...";AT 11,K;"BLACKJACK WINS TREBLE  "
 2170 LET BET=BET+(GOBET*3)
 2180 GO TO 2290
 2190 PRINT AT J,K;"CURSES...";AT 11,K;"TWENTY-ONE >>> YOU WIN "
 2200 GO TO 2110
 2210 PRINT AT J,K;"YOU BUST"
 2220 GO TO 2040
 2230 PRINT AT J,K;"I BEAT YOU ";U;" TO ";T;"  "
 2240 GO TO 2040
 2250 PAPER 4: INK 0: PRINT AT J,K;"YOUR POCKETS ARE EMPTY.";AT 11,K;"MY GUARD THREW YOU OUT.": FLASH 1: PRINT AT 20,1;" TRY AGAIN ??? HIT ANY LETTER ": FLASH 0
 2260 LET BET=100
 2270 LET F=0
 2280 PAUSE 0
 2282 PRINT AT 20,1;C$;AT J,3;"ALLRIGHT, HERE WE GO AGAIN";AT 11,1;C$
 2290 FOR N=-20 TO 20: BEEP .02,ABS N+15: NEXT N: PAUSE 100
 2310 IF F<9 THEN LET F=52: LET Z$="A0B0C0D0E0F0G0H0I0J0K0L0M0A1B1C1D1E1F1G1H1I1J1K1L1M1A2B2C2D2E2F2G2H2I2J2K2L2M2A3B3C3D3E3F3G3H3I3J3K3L3M3"
 2320 LET J=10: INK 0: PAPER 4: FOR I=1 TO J: PRINT AT I,1;C$;AT 21-I,1;C$;: NEXT I
 2330 PRINT AT J,11;"BLACKJACK";AT 11,11;("NEW  DECK" AND F=52)
 2340 PLOT 8,16: DRAW 0,151: DRAW 239,0: DRAW 0,-151
 2360 PAPER 1: INK 6: PRINT BRIGHT 1; OVER 1;AT 20,1;C$;AT 20,1;" YOU OWN $";BET
 2390 GO TO 1210
 2480 LET J=13*(I-1)
 2490 LET F$=("\a" AND I=1)+("\b" AND I=2)+("\c" AND I=3)+("\d" AND I=4)
 2500 LET G$=" "+F$+" "
 2510 LET H$=F$+" "+F$
 2520 LET I$=F$+F$+F$
 2530 LET J$="   "
 2540 LET A$(J+1,1)="A  "
 2550 LET A$(J+1,2)=J$
 2560 LET A$(J+1,3)=G$
 2570 LET A$(J+1,4)=J$
 2580 LET A$(J+1,5)=J$
 2590 LET A$(J+1,6)="  A"
 2600 LET A$(J+2,1)="2  "
 2610 LET A$(J+2,2)=G$
 2620 LET A$(J+2,3)=J$
 2630 LET A$(J+2,4)=J$
 2640 LET A$(J+2,5)=G$
 2650 LET A$(J+2,6)="  2"
 2660 LET A$(J+3,1)="3  "
 2670 LET A$(J+3,2)=G$
 2680 LET A$(J+3,3)=G$
 2690 LET A$(J+3,4)=J$
 2700 LET A$(J+3,5)=G$
 2710 LET A$(J+3,6)="  3"
 2720 LET A$(J+4,1)="4  "
 2730 LET A$(J+4,2)=H$
 2740 LET A$(J+4,3)=J$
 2750 LET A$(J+4,4)=J$
 2760 LET A$(J+4,5)=H$
 2770 LET A$(J+4,6)="  4"
 2780 LET A$(J+5,1)="5  "
 2790 LET A$(J+5,2)=H$
 2800 LET A$(J+5,3)=G$
 2810 LET A$(J+5,4)=J$
 2820 LET A$(J+5,5)=H$
 2830 LET A$(J+5,6)="  5"
 2840 LET A$(J+6,1)="6  "
 2850 LET A$(J+6,2)=H$
 2860 LET A$(J+6,3)=H$
 2870 LET A$(J+6,4)=J$
 2880 LET A$(J+6,5)=H$
 2890 LET A$(J+6,6)="  6"
 2900 LET A$(J+7,1)="7  "
 2910 LET A$(J+7,2)=H$
 2920 LET A$(J+7,3)=H$
 2930 LET A$(J+7,4)=G$
 2940 LET A$(J+7,5)=H$
 2950 LET A$(J+7,6)="  7"
 2960 LET A$(J+8,1)="8  "
 2970 LET A$(J+8,2)=H$
 2980 LET A$(J+8,3)=H$
 2990 LET A$(J+8,4)=H$
 3000 LET A$(J+8,5)=H$
 3010 LET A$(J+8,6)="  8"
 3020 LET A$(J+9,1)="9  "
 3030 LET A$(J+9,2)=H$
 3040 LET A$(J+9,3)=H$
 3050 LET A$(J+9,4)=I$
 3060 LET A$(J+9,5)=H$
 3070 LET A$(J+9,6)="  9"
 3080 LET A$(J+10,1)="10 "
 3090 LET A$(J+10,2)=H$
 3100 LET A$(J+10,3)=I$
 3110 LET A$(J+10,4)=I$
 3120 LET A$(J+10,5)=H$
 3130 LET A$(J+10,6)=" 10"
 3140 LET A$(J+11,1)="J  "
 3150 LET A$(J+11,2)=F$+"▝█"
 3160 LET A$(J+11,3)="▗▄█"
 3170 LET A$(J+11,4)="█▀▘"
 3180 LET A$(J+11,5)="█▖"+F$
 3190 LET A$(J+11,6)="  J"
 3200 LET A$(J+12,1)="Q  "
 3210 LET A$(J+12,2)=F$+"▝█"
 3220 LET A$(J+12,3)="▜▄▛"
 3230 LET A$(J+12,4)="▟▀▙"
 3240 LET A$(J+12,5)="█▖"+F$
 3250 LET A$(J+12,6)="  Q"
 3260 LET A$(J+13,1)="K  "
 3270 LET A$(J+13,2)=F$+"▐▛"
 3280 LET A$(J+13,3)="█▛ "
 3290 LET A$(J+13,4)=" ▟█"
 3300 LET A$(J+13,5)="▟▌"+F$
 3310 LET A$(J+13,6)="  K"
 3330 RETURN 
 3350 LET Z=0: LET N=Z: LET H=Z
 3360 LET I=Z: LET F=Z
 3370 LET J=10: LET K=4
 3380 DIM E$(6): LET BET=100
 3390 LET C$="\e                            \f"
 3400 OVER 0: BRIGHT 0: BORDER 0: PAPER 4: INK 0: CLS 
 3460 PLOT 8,8: DRAW 239,0: DRAW 0,159: DRAW -239,0: DRAW 0,-159
 3470 PLOT 39,47: DRAW 177,0: DRAW 0,89: DRAW -177,0: DRAW 0,-89
 3480 LET H=5: FOR I=15 TO H STEP -1: PRINT AT I,H; BRIGHT 1; PAPER 1;"                      ": BEEP .01,20-I: NEXT I
 3490 PRINT AT 3,4;"\f"; BRIGHT 1; INK 6; PAPER 2;" WELCOME TO BLACKJACK ";
 3500 PRINT PAPER 4;"\e"; BRIGHT 1; INK 7; PAPER 1;AT 6,H;"    programmed by";AT 7,H;"    Gwyn Dewey in";AT 9,H;"   51 GAME PROGRAMS";AT 10,H;"   FOR THE T/S 1000";AT 12,H;"      adapted by";AT 13,H;"  Werner Kaelin 1984";AT 14,H;"   Potomac MD 20854"
 3510 LET AA=1
 3520 IF AA THEN DIM A$(52,6,3): GO SUB 4000
 3530 GO SUB 5000: LET B$="HIT ANY KEY TO START "
 3540 PRINT AT 18,4; PAPER 4; INK 0;"\f"; PAPER 2; INK 6; BRIGHT 1;" ";B$;: PRINT PAPER 4;"\e"
 3550 BEEP .06,CODE B$(2)-60
 3560 LET B$=B$(2 TO )+B$(1)
 3570 IF INKEY$="" THEN GO TO 3540
 3580 BORDER 2: BRIGHT 0
 3590 INPUT "": RANDOMIZE : GO TO 2310
 4000 RESTORE : FOR A=USR "A" TO USR "G"+7
 4010 READ UG: POKE A,UG: NEXT A
 4020 RETURN 
 4100 DATA 0,8,28,62,127,127,42,8
 4105 DATA 0,28,28,107,127,107,8,8
 4110 DATA 0,8,28,62,127,62,28,8
 4120 DATA 0,54,127,127,127,62,28,8
 4140 DATA 128,128,128,128,128,128,128,128
 4150 DATA 1,1,1,1,1,1,1,1
 4160 DATA 255,0,0,0,0,0,0,0
 4190 RETURN 
 4200 REM A B C D E F G H I J K L
 4210 REM \a \b \c \d \e \f \g \h \i \j \k \l
 5000 PAPER 7
 5010 FOR I=30 TO 0 STEP -2
 5020 PRINT AT 0,I;" ";: GO SUB 5200
 5030 NEXT I
 5035 IF AA THEN LET I=1: GO SUB 2480
 5040 FOR I=1 TO 20 STEP 2
 5050 PRINT AT I,0;: GO SUB 5200: PRINT AT I+1,0;" "
 5060 NEXT I
 5065 IF AA THEN LET I=2: GO SUB 2480
 5070 FOR I=0 TO 31 STEP 2
 5080 PRINT AT 21,I;: GO SUB 5200: PRINT " "
 5090 NEXT I
 5095 IF AA THEN LET I=3: GO SUB 2480
 5100 FOR I=21 TO 1 STEP -2
 5110 PRINT AT I,31;" ";AT I-1,31;: GO SUB 5200
 5120 NEXT I
 5130 IF AA THEN LET I=4: GO SUB 2480
 5140 RETURN 
 5200 LET H=INT (4*RND): INK 2*INT (H/2): PRINT CHR$ (144+H);
 5210 BEEP .04,12+4*H: RETURN 
 9900 CLEAR : SAVE "BJ" LINE 3350
 9910 PRINT AT 10,2;"Rewind tape and press ENTER"''TAB 9;"to VERIFY 'BJ'": PAUSE 0: VERIFY ""
 9920 GO TO 3350

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top