program CardGame; { Author: John Howard jh Date: 08-SEP-94 Version: 1.0 Demonstrate two methods to shuffle cards. Swap method is fast! Demonstrate how to evaluate Bridge hands: Each hand of 13 cards are arranged by suits and rank within suit (aces are high). The hand is then evaluated using the following standard bridge values. Aces count 4 Kings count 3 Queens count 2 Jacks count 1 Voids (no cards in a suit) count 3 Singletons (one card in a suit) count 2 Doubletons (two cards in a suit) count 1 Long suits with more than five cards in the suit count 1 for each card over five in number Example: 2C QD TC AD 6C 3D TD 3H 5H 7H AS JH KH = 16 points because there are 2 aces, 1 king, 1 queen, 1 jack, 1 singleton. } {$DEFINE BridgeHand} const {$IFDEF BridgeHand} points : integer = 0; {$ENDIF} maxdeck = 52; maxsuit = 13; sentinel = 0; suits = 4; type card = byte; suit = array[1..maxsuit] of card; { ace rank is 1, king rank is 13 } var hearts, diamonds : suit; {red} clubs, spades : suit; {black} deck : array[1..maxdeck] of card; i, j, k : integer; { indices } count : integer; { count of used cards } procedure swap(a,b : integer); var temp : integer; begin temp := deck[a]; deck[a] := deck[b]; deck[b] := temp; end; BEGIN {main} writeln('method one - random swap. Absolutely the fastest!'); randomize; for i := 1 to maxdeck do {initialize deck} deck[i] := i; { Card number MODULO 13 will help to rank } for i := 1 to maxdeck do {index card deck} begin j := random(maxdeck) +1; { range is 1..52 } SWAP(i, j); { shuffle two cards } end; for i := 1 to maxdeck do {index card deck} write(deck[i], ' '); { display card order } writeln; writeln('method two - rank each card. Theoretically may take forever!'); randomize; for i := 1 to maxdeck do {initialize deck} deck[i] := sentinel; { Zero is our sentinel } for i := 1 to maxsuit do {initialize suits with their card numbers} begin hearts[i] := i; { range is 1..13 } diamonds[i] := i + maxsuit; { range is 14..26 } clubs[i] := i + 2*maxsuit; { range is 27..39 } spades[i] := i + 3*maxsuit; { range is 40..52 } end; count := maxdeck; {$IFDEF BridgeHand} count := maxsuit; {$ENDIF} repeat i := random(maxdeck) +1; { range is 1..52 } if deck[i] = sentinel then begin j := random(maxsuit) +1; { range is 1..13 } k := random(suits) +1; { range is 1..4 } case k of 1 : if hearts[j] <> sentinel then begin hearts[j] := sentinel; deck[i] := j; dec(count); end; 2 : if diamonds[j] <> sentinel then begin diamonds[j] := sentinel; deck[i] := j+ maxsuit; dec(count); end; 3 : if clubs[j] <> sentinel then begin clubs[j] := sentinel; deck[i] := j+ 2*maxsuit; dec(count); end; 4 : if spades[j] <> sentinel then begin spades[j] := sentinel; deck[i] := j+ 3*maxsuit; dec(count); end; end; {case} end; until (count = 0); for i := 1 to maxdeck do {index card deck} write(deck[i], ' '); { display card order } writeln; {$IFDEF BridgeHand} { Only block for Hearts is shown. Code is similar for each suit! } count := 0; if hearts[1] = sentinel then inc(points, 4); { ace } if hearts[13] = sentinel then inc(points, 3); { king } if hearts[12] = sentinel then inc(points, 2); { queen } if hearts[11] = sentinel then inc(points, 1); { jack } for i := 1 to maxsuit do if hearts[i] = sentinel then inc(count); case count of 0: inc(points, 3); { void } 1: inc(points, 2); { singleton } 2: inc(points, 1); { doubleton } 6..13: inc(points, count-5); { long suit } end; {case} writeln('Points for Hearts = ', points); {$ENDIF} END. {program}