23

Pontoon


Everyone knows how to play Pontoon (or Vingt-et-un), so we need not waste time discussing it. In this computer version the user plays against the computer. Both start with £100 cash, and the bets are very simple; £1 per hand. You are not allowed to 'buy' another card, although some readers may wish to include this facility, by changing the procedure a little at PROCPLAY.
   The deck of cards is worth considering. It is contained in the array A(0) to A(51), with Hearts having values 0 to 12, Clubs from 13 to 25 and so on. Initially the deck is uncut - i.e. the cards are in order - and PROCSHUFFLE moves them around. We utilise a pointer called NXTCARD to indicate the next card to be dealt, and when NXTCARD equals 52 (off the end of the deck), it is set to 0 again. This means that once the deck has been shuffled, the cards are dealt infallibly in the same order. According to the 'letter of the law' this is right, but experience has shown that the situation can arise where a Pontoon call is impossible and so the deal never changes hands. (Besides, in the game as played entirely by humans, there is a slight rearrangements of cards as they are collected and placed at the bottom of the deck.) Therefore, I have arranged for the deck to be reshuffled whenever NXTCARD equals 52, as well as whenever there is a Pontoon call.
   When the player peruses his or her own hand - as player or dealer - the cards are shown pictorially, as you will see from the illustration, and I have also arranged that the computer's hand is shown in those situations where it may be suspected that the computer is cheating or perhaps not functioning correctly. The displays are of course very similar, and the user must be aware of the text above the display, which lets you know whose hand is being shown.
   The arrays P(5) and C(5) hold the undecoded card values held by the player and the computer respectively, and line 40 prepares the uncut deck. Lines 50 to 80 redefine four graphics symbols for Heart, Club, Diamond and Spade, and line 100 defines a text area at the bottom of the screen.
   The game loop is easy to follow. B is the flag denoting who is the dealer, while PFLAG and CFLAG are the score values of the player's hand and the computer's hand respectively, where 0 = bust, 1 = stick, 3 = Pontoon and 5 = five-card trick.
   PROCOMPLAY - the computer's play - starts with a call to PROCPREP, which prepares the screen. We then utilise function ADD, defined on lines 1540 to 1580, which decodes the card number held (0 to 51) to its value in Pontoon (1-11). The logic of computer choice, etc., follows. If the computer's hand is between 16 and 21, there is a mathematical choice in the equation of line 470, which makes the computer play a good game, but one that is not too predictable.
   If the computer has bust - gone over 21 - lines 540 onwards check for the presence of an Ace. If one is found, the total is reduced by 10 in line 550, and the coded card number is made negative. This is so the card will still be displayed correctly, but it cannot again reduce the score by 10.
   When it is the player's turn, line 620 calls PROCHAND, which displays the cards graphically. The two parameters passed to PROCHAND are (a) the number of the card in the hand - first, second, etc. - and (b) the code number of the card. Line 1320 calculates the position of the card on the screen, and then line 1330 defines the graphics area to be the position and size of the card and clears it to background black, in case it overlaps another card. Line 1340 redefines that area a little smaller and clears it in white, then lines 1350 and 1360 repeat the process. The result is a white playing card with a tiny black edge, inside it being a black line marking off a white margin. (See the illustration.)
   Line 1370 decodes the card number to suit and value, and then E$ is loaded with the print equivalent. Finally, lines 1470 on print the suit symbol and the value in two places. If desired, users could extend this to have suit symbols printed the correct number of times - nine times on the nine of Hearts, for example - but in practice twice is quite enough.
   You should be able to follow the rest of the listing quite easily.

Variables

PCASHPlayer's cash
CCASHComputer's cash
A(51)The pack or deck of cards
P(5)Player's coded card numbers
C(5)Computer coded card numbers
Q$General input string
BBanker, where 0 = computer and 1 = player
PFLAGValue of player's hand, where 0 = bust, etc.
CFLAGValue of computer's hand
CCounter when dealing cards
CDCoded value of card dealt
CCARDSNumber of cards in computer's hand
PCARDSNumber of cards in player's hand
CTOTGame value of computer's cards
PTOTGame value of player's cards
XGeneral counter
G$Dummy
SSelected card whilst shuffling
ZTemporary holding variable in exchanging
NXTCARDCard next to be dealt, 0 to 51

In PROCHAND:
I%Card in hand - first, second etc.
V%Coded number of card; then suit 0-3
A%Position on screen of left edge
B%Ditto, bottom edge
C%Ditto, right edge
D%Ditto, top edge
E%Card value in suit, 0 (King) to 12 (Queen)
S$Suit symbol, Heart, Club, Diamond, Spade
E$Value 2 to 10, or initial, A, J, Q, K
PPrint offset to allow for 2-digit '10'

   10 MODE7:PROCTITLE("PONTOON")
   20 PCASH=100:CCASH=100:*FX11,0
   30 DIM A(51),P(5),C(5)
   40 FOR X=0 TO 51:A(X)=X:NEXT
   50 VDU23,224,54,127,127,127,62,28,8,0
   60 VDU23,225,28,28,107,127,107,8,28,0
   70 VDU23,226,8,28,62,127,62,28,8,0
   80 VDU23,227,8,28,62,127,127,107,8,0
   90 INPUT'''"Do you want the bank (Y-N)",Q$
  100 MODE5:VDU28,0,29,19,21:IF Q$="Y" B=1 ELSE B=0
  110 PROCSHUFFLE
  120  
  130 REM - Game loop
  140  
  150 REPEAT:CLS
  160 PROCDEAL:IF B=1 GOTO 190
  170 PROCPLAY
  180 IF PFLAG=0 CFLAG=1:GOTO220
  190 PROCOMPLAY:IF B=0 GOTO220
  200 IF CFLAG=0 PFLAG=1:GOTO220
  210 PROCPLAY
  220 PROCWINNER
  230 CLS:IF PFLAG<>3 AND CFLAG<>3 GOTO280
  240 PRINT"Pontoon"
  250 IF B=0 AND PFLAG=3 GOTO 270
  260 IF B=1 AND CFLAG<>3 GOTO 275
  270 PRINT"Deal changes.":B=1-B
  275 PROCSHUFFLE
  280 UNTIL PCASH=0 OR CCASH=0
  290 END
  300  
  310 DEFPROCDEAL
  320 IF B PRINT"You deal.."ELSE PRINT"I deal.."
  330 FOR C=1 TO 2
  340 PROCGETCARD:P(C)=CD
  350 PROCGETCARD:C(C)=CD
  360 NEXT C:CCARDS=2:PCARDS=2
  370 ENDPROC
  380  
  390 DEFPROCOMPLAY
  400 PROCPREP("")
  410 CTOT=FNADD(C(1))+FNADD(C(2))
  420 CLS:IF CCARDS<5 GOTO440
  430 PRINT"I have a 5-card trick.":CFLAG=5:GOTO580
  440 IF CTOT<>21 OR CCARDS<>2 GOTO460
  450 PRINT"I have Pontoon.":CFLAG=3:GOTO580
  460 IF CTOT>21 GOTO540
  470 IF CTOT<16 OR RND(1)<(20-CTOT)/13 GOTO490
  480 PRINT"I stick.":CFLAG=1:GOTO580
  490 PRINT"I take a card.":PROCGETCARD
  500 CCARDS=CCARDS+1:C(CCARDS)=CD
  510 CTOT=CTOT+FNADD(CD)
  520 IF CTOT<=21 GOTO420
  530 REM - Over 21. Any Aces?
  540 FOR X=1 TO CCARDS
  550 IF C(X)MOD13=1 C(X)=-C(X):CTOT=CTOT-10
  560 NEXT X:IF CTOT<=21 GOTO420
  570 PRINT;'"I bust with ";CTOT:CFLAG=0
  580 PROCRET:ENDPROC
  590  
  600 DEFPROCPLAY
  610 PROCPREP("Your cards")
  620 FOR Z=1 TO 2:PROCHAND(Z,P(Z)):NEXT:PC=2
  630 PTOT=FNADD(P(1))+FNADD(P(2))
  640 VDU4:IF PTOT<16 GOTO700
  650 IF PTOT=21 AND PC=2 PRINT"Pontoon!":PFLAG=3:GOTO800
  660 COLOUR3:PRINT"Stick or twist (S-T)";
  670 REPEAT:G$=GET$
  680 UNTIL G$="T" OR G$="S" OR ASCG$=13
  690 IF G$="S" OR ASCG$=13 PFLAG=1:GOTO810
  700 PROCGETCARD:PC=PC+1:PROCHAND(PC,CD)
  710 P(PC)=CD:PTOT=PTOT+FNADD(CD)
  720 IF PTOT<=21 CLS:GOTO 780
  730 REM Any Aces?
  740 FOR X=1 TO PC
  750 IF P(X) MOD13=1 P(X)=-P(X):PTOT=PTOT-10
  760 NEXT:IF PTOT<=21 GOTO780
  770 COLOUR1:PRINT"BUST!":PFLAG=0:GOTO800
  780 IF PC=5 PRINT"5-CARD TRICK!":PFLAG=5:GOTO800
  790 CLS:GOTO640
  800 PRINT''"Press RETURN";:G$=GET$
  810 ENDPROC
  820  
  830 DEFPROCWINNER
  835 IF PFLAG=5 OR CFLAG=5 S%=5 ELSE S%=2
  840 CLS:IF PFLAG=0 GOTO960
  850 PROCPREP("My cards")
  860 FOR X%=1 TO CCARDS
  870 PROCHAND(X%,C(X%)):NEXT
  880 IF PFLAG>CFLAG GOTO940
  890 IF CFLAG>PFLAG GOTO960
  900 IF PTOT>CTOT GOTO940
  910 IF CTOT>PTOT GOTO960
  920 PRINT"Dealer wins ties."'
  930 IF B=0 GOTO960
  940 COLOUR2:PRINT"You win!"
  950 PCASH=PCASH+S%:CCASH=CCASH-S%:GOTO980
  960 COLOUR1:PRINT'"I win!"
  970 PCASH=PCASH-S%:CCASH=CCASH+S%
  980 COLOUR3
  990 PRINT;'"CASH;"'"You - `";PCASH;" Me - `";CCASH
 1000 PROCRET:ENDPROC
 1010  
 1020 DEFPROCTITLE(X$)
 1030 PRINTCHR$132;STRING$(19,"Oo")
 1040 PROCDBL((36-LEN(X$))/2,3,131,X$)
 1050 PRINT'CHR$132;STRING$(19,"Oo")
 1060 ENDPROC
 1070  
 1080 DEFPROCRET:COLOUR2
 1090 PRINT'"Press RETURN ";:G$=GET$:CLS
 1100 ENDPROC
 1110  
 1120 DEFPROCDBL(X%,Y%,C%,X$)
 1130 PRINTTAB(X%,Y%);CHR$C%;CHR$141;X$
 1140 PRINTTAB(X%,Y%+1);CHR$C%;CHR$141;X$
 1150 ENDPROC
 1160  
 1170 DEFPROCSHUFFLE
 1180 IF B PRINT"You shuffle.."ELSE PRINT"I shuffle.."
 1190 FOR X=0 TO 51
 1200 S=RND(52)-1:IF S=X GOTO1200
 1210 Z=A(S):A(S)=A(X):A(X)=Z
 1220 NEXT:NXTCARD=0:PROCRET
 1230 ENDPROC
 1240  
 1250 DEFPROCGETCARD
 1260 CD=A(NXTCARD):NXTCARD=NXTCARD+1
 1270 IF NXTCARD=52 NXTCARD=0:PROCSHUFFLE
 1280 ENDPROC
 1290  
 1300 DEFPROCHAND(I%,V%)
 1310 LOCAL A%,B%,C%,D%,E%,P,E$,S$
 1320 A%=I%*160:B%=400+72*(I%MOD2):C%=A%+300:D%=B%+400
 1330 GCOL0,128:VDU24,A%;B%;C%;D%;16
 1340 GCOL0,131:VDU24,A%+8;B%+4;C%-8;D%-4;16
 1350 GCOL0,128:VDU24,A%+44;B%+44;C%-44;D%-44;16
 1360 GCOL0,131:VDU24,A%+52;B%+48;C%-52;D%-48;16
 1370 E%=ABS((V%)MOD13):V%=ABS((V%)DIV13)
 1380 IF E%=1 E$="A":GOTO1430
 1390 IF E%=0 E$="K":GOTO1430
 1400 IF E%=11 E$="J":GOTO1430
 1410 IF E%=12 E$="Q":GOTO1430
 1420 E$=STR$E%
 1430 IF V%=0 GCOL0,1:S$=CHR$224
 1440 IF V%=1 GCOL0,0:S$=CHR$225
 1450 IF V%=2 GCOL0,1:S$=CHR$226
 1460 IF V%=3 GCOL0,0:S$=CHR$227
 1470 VDU5:MOVEA%+52,B%+300:PRINTS$
 1480 MOVEA%+186,B%+124:PRINTS$
 1490 MOVEA%+56,B%+340:PRINTE$
 1500 IF LEN(E$)=1 P=192 ELSE P=128
 1510 MOVEA%+P,B%+84:PRINTE$
 1520 VDU4:ENDPROC
 1530  
 1540 DEF FNADD(A%)
 1550 A%=A%MOD13
 1560 IF A%=0 OR A%>=11 A%=10
 1570 IF A%=1 A%=11
 1580 =A%
 1590  
 1600 DEFPROCPREP(X$)
 1610 VDU26,18,0,128,16,28,0,29,19,21,5,18,0,2
 1620 MOVE300,950:PRINTX$:VDU4:ENDPROC