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
PCASH | Player's cash |
CCASH | Computer'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 |
B | Banker, where 0 = computer and 1 = player |
PFLAG | Value of player's hand, where 0 = bust, etc. |
CFLAG | Value of computer's hand |
C | Counter when dealing cards |
CD | Coded value of card dealt |
CCARDS | Number of cards in computer's hand |
PCARDS | Number of cards in player's hand |
CTOT | Game value of computer's cards |
PTOT | Game value of player's cards |
X | General counter |
G$ | Dummy |
S | Selected card whilst shuffling |
Z | Temporary holding variable in exchanging |
NXTCARD | Card 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 |
P | Print 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