C

The C program below calculates the probability a specific pre-flop hand will win given a number of players in Texas Hold’em. It can be compiled using the command “gcc dealHands.c deal.c getDeck.c getHandValue.c -o dealHands” on a linux system.

You have to love the simplicity of C. The trick is understanding pointers. Of all the languages I use this has the best performance. If speed of execution is your top priority this is the language to use.

dealHands.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "hands.h"
/*
There are only 169 unique hands in holdem - 13 pocket pairs,
78 suited hands and 78 unsuited hands (really the 13 pairs
are unsuited so that makes 91 unsuited hands). Cards are
valued from 0 to 12 (duece to ace). The 4 arrays below are
used to keep track of how often a unique hand is dealt and
how often that hand wins. The index is computed by taking
the value of the higher valued card of the 2 dealt and
multiplying by 100 then adding the value of the lower valued card
(i.e. a pair of aces would have an index 1212, ace-king would have
an index of 1211 and a pair of dueces would have a value of 0).
That makes the arrays below a huge waste of space but it makes the code
easier to follow (if C had a hash array like perl or an associative
array like php this would be much easier). Should refactor in the
furure to save memory. sHands is number of each type of Suited Hand
dealt, uHands is number of each type of Unsuited Hand dealt. sWins
is number of Suited Hands dealt that won. And you can figure what
uWins is.
*/
long sHands[1213];
long uHands[1213];
long sWins[1213];
long uWins[1213];

/* The idea here is to play a given number of hands of Texas Hold'm
   at a table with a given number of players and determine if all
   players stay in the hand which hands would win what percentage
   of the time */
int main(int argc, char **argv)
{
  if(argc!=3){
      printf("dealHands requires 2 arguments - number of hands to play and number of players per hand\n");
      exit(1);
  }
  long handsToPlay=atol(argv[1]);
  int handsPerGame=atol(argv[2]);
  long i;
  int deal(int); // Module to deal hands
  char card1;
  char card2;
  char handLiteral[3];
  handLiteral[2]=0;
  // Initialize arrays
  for(i=0;i<1213;++i){
      sHands[i]=0;
      uHands[i]=0;
      sWins[i]=0;
      uWins[i]=0;
  }
  srand(time(NULL)); // Seed random number generator
  for(i=0;i<handsToPlay;++i){
      //printf("Hand %ld\n", i);
      deal(handsPerGame);
  }
  for(i=0;i<1213;++i){
      if(sHands[i]>0){
         card1=i/100;
         card2=i-(card1*100);
         handLiteral[0]=charCardRank[card1];
         handLiteral[1]=charCardRank[card2];
         printf("suited %s %ld %ld\n", handLiteral, sHands[i], sWins[i]);
      }
  }
  for(i=0;i<1213;++i){
      if(uHands[i]>0){
         card1=i/100;
         card2=i-(card1*100);
         handLiteral[0]=charCardRank[card1];
         handLiteral[1]=charCardRank[card2];
         printf("unsuited %s %ld %ld\n", handLiteral, uHands[i], uWins[i]);
      }
  }

return 0;
}

deal.c
#include <stdio.h>
#include <stdlib.h>
#include "hands.h"
  extern long sHands[1213];
  extern long uHands[1213];
  extern long sWins[1213];
  extern long uWins[1213];

int deal(long handCount)
{
  int getHandValue(handInfo *); //Module to value a hand
  char shuffDeck[52];
  char flop[5];
  char cardIndex;
  char playerIndex;
  char cardNo=0;
  int getDeck(char[52]); //Module to get a shuffled deck
  getDeck(&shuffDeck[0]); //Get a new shuffled deck
  handInfo handDetail[10]; // a structure that contains information needed to evaluate a hand
  long long int winningHand;
  char card1;
  char card2;
  char hold;
  char card1Suit;

  //Deal the players hands
  for(cardIndex=0;cardIndex<2;++cardIndex){
      for(playerIndex=0;playerIndex<handCount;++playerIndex){
          handDetail[playerIndex].cards[cardIndex]=shuffDeck[cardNo++];
      }
  }
  cardNo++; //burn - the burns probably don't affect the outcome but it follows the way the game is played
  flop[0]=shuffDeck[cardNo++];
  flop[1]=shuffDeck[cardNo++];
  flop[2]=shuffDeck[cardNo++];
  cardNo++; //burn
  flop[3]=shuffDeck[cardNo++];
  cardNo++; //burn
  flop[4]=shuffDeck[cardNo++];

  for(playerIndex=0;playerIndex<handCount;++playerIndex){
    for(cardIndex=2;cardIndex<7;++cardIndex){
        // Add the board cards to each players hand to be used in valuing the hand
        handDetail[playerIndex].cards[cardIndex]=flop[cardIndex-2];
    }
  }
  winningHand=0;
  for(playerIndex=0;playerIndex<handCount;++playerIndex){
      /* getHandValue takes the information in the handDetail
         structure and computes value for the hand which it then
         places in the structure element handValue. This will be
         used to compute the winning hand. */
      getHandValue(&handDetail[playerIndex]);
      handDetail[playerIndex].isSuited=FALSE;
      card1 = handDetail[playerIndex].cards[0];
      card2 = handDetail[playerIndex].cards[1];
      card1Suit=handDetail[playerIndex].cards[0]%4;
      if(card1Suit == (card2%4)){
          handDetail[playerIndex].isSuited=TRUE;
      }
      /*cards are identified by their position in a sorted deck see
        hands.h by doing a modulus operation on the card number you get
        the suit (we only care if the players cards are suited not
        what suit they are) by dividing by 4 we get the value of the
        card. For example at index 4 is the THREE of CLUBS, at index 5
        is the THREE of DIAMONDS ..... Since these are intergers dividing
        by 4 gets us a result of 1 regardless of the suit. And 1 is the
        index for a THREE.*/
      card1=card1/4;
      card2=card2/4;
      /* Once we've removed suit from the card value we want the relativly
         higher ranked card to always be the first card (does not matter
         for pairs */
      if(card1<card2){
          hold=card1;
          card1=card2;
          card2=hold;
      }
      handDetail[playerIndex].handKey=(card1*100)+card2;
      if(handDetail[playerIndex].handValue>winningHand){
          winningHand=handDetail[playerIndex].handValue;
      }
  }
  //Count hands for each combination and winners
  for(playerIndex=0;playerIndex<handCount;++playerIndex){
      if(handDetail[playerIndex].handValue!=0){
          if(handDetail[playerIndex].isSuited){
              sHands[handDetail[playerIndex].handKey]++;
          }
          else{
              uHands[handDetail[playerIndex].handKey]++;
          }
      }
      if(handDetail[playerIndex].handValue==winningHand){
          if(handDetail[playerIndex].isSuited){
              sWins[handDetail[playerIndex].handKey]++;
          }
          else{
              uWins[handDetail[playerIndex].handKey]++;
          }
      }
      else{
      }

  }
return 0;
}

getDeck.c
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define FALSE  0
#define TRUE   1
/* Create a shuffled deck */
int getDeck(char  shuffDeck[])
{
  char cardIndex;
  char dealtCardIndex;
  char randHold;
  char noMatch;
  shuffDeck[0]=rand()%52;//The first card is easy to deal just a random number 0 - 51
  // After the first card we need to check that the card has not been dealt already
  for(cardIndex=1;cardIndex<52;++cardIndex){
      while(TRUE){
          noMatch=TRUE;
          randHold=rand()%52;
          for(dealtCardIndex=0;dealtCardIndex<cardIndex;++dealtCardIndex){
              if(shuffDeck[dealtCardIndex]==randHold){
                  noMatch=FALSE;
                  break;
              }
          }
          if(noMatch){
              shuffDeck[cardIndex]=randHold;
              break;
          }
      }
  }
return 0;
}

getHandValue.c
#include <stdio.h>
#include <stdlib.h>
#include "hands.h"

int isThereQuads(handInfo *handDetail);
int isThereABoat(handInfo *handDetail);
int isThereAFlush(handInfo *handDetail);
int isThereAStraight(handInfo *handDetail);
int isThereTrips(handInfo *handDetail);
int isThereTwoPair(handInfo *handDetail);
int isThereOnePair(handInfo *handDetail);
int sortCards(char sortedCards[]);

int getHandValue(handInfo *handDetail)
{
    char i;
    char sortedCards[]={-1, -1, -1, -1, -1, -1, -1};
    //Makes sense to check for a flush first, if a flush exists within the seven cards
    //the only higher possible hand is a straight flush which is easy to check for
    //using the same code that will check for a straight
    handDetail->handType=unknown;
    isThereAFlush(handDetail);
    if(handDetail->handType==unknown){ //Only use of handType, easily refactored out, keeping it for now
       if(!isThereQuads(handDetail)){
           if(!isThereABoat(handDetail)){
               if(!isThereAStraight(handDetail)){
                   if(!isThereTrips(handDetail)){
                       if(!isThereTwoPair(handDetail)){
                           if(!isThereOnePair(handDetail)){
                               for(i=0;i<7;i++){
                                   sortedCards[i]=handDetail->cards[i]/4;
                               }
                               sortCards(sortedCards);
                               handDetail->handType=HighCard;
                               handDetail->handValue=(HANDTYPE*HIGHCARD)+
                                                    (sortedCards[0]*FIRSTKICKER)+
                                                    (sortedCards[1]*SECONDKICKER)+
                                                    (sortedCards[2]*THIRDKICKER)+
                                                    (sortedCards[3]*FOURTHKICKER)+
                                                    (sortedCards[4]*FIFTHKICKER);
                               handDetail->parm[0]=sortedCards[0];
                               handDetail->parm[1]=sortedCards[1];
                               handDetail->parm[2]=sortedCards[2];
                               handDetail->parm[3]=sortedCards[3];
                               handDetail->parm[4]=sortedCards[4];
                           }
                       }
                   }
               }
           }
       }
    }
    return 0;
}

int isThereQuads(handInfo *handDetail){
    char i;
    char cardCount[]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    char highCard=0;
    int areQuads=FALSE;
    char quads=0;
    for(i=0;i<7;i++){
        cardCount[(handDetail->cards[i]/4)]++;
    }
    for(i=0;i<13;i++){
        if(cardCount[i]==4){
            areQuads=TRUE;
            quads=i;
            break;
        }
    }
    if(areQuads){
        for(i=12;i>-1;i--){
            if(i != quads){
                if(cardCount[i]>0){
                    highCard=i;
                    break;
                }
            }
        }
        //printf("!!!!We got quads quad card is %s \n", cardRank[quads]);
        handDetail->handType=Quads;
        handDetail->handValue=(HANDTYPE*QUADS)+
                             (quads*FIRSTKICKER)+
                             (highCard*SECONDKICKER);
        handDetail->parm[0]=quads;
        handDetail->parm[1]=highCard;
        handDetail->parm[2]=0;
        handDetail->parm[3]=0;
        handDetail->parm[4]=0;
    }
    return areQuads;
}

int isThereABoat(handInfo *handDetail){
    char i;
    char cardCount[]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    char highTrips=-1;
    char highPair=-1;
    int isABoat=FALSE;
    for(i=0;i<7;i++){
        cardCount[(handDetail->cards[i]/4)]++;
    }
    for(i=12;i>-1;i--){
        if(cardCount[i]==3){
            highTrips=i;
            break;
        }
    }
    if(highTrips>-1){
        for(i=12;i>-1;i--){
            if(i!=highTrips){
                if(cardCount[i]>1){
                    highPair=i;
                    isABoat=TRUE;
                }
            }
        }
    }
    if(isABoat){
        //printf("!!!!We have a boat %s and %s\n", cardRank[highTrips], cardRank[highPair]);
        //printf("!!!!We have a boat %s\n", cardRank[highTrips]);
        handDetail->handType=Boat;
        handDetail->handValue=(HANDTYPE*BOAT)+
                             (highTrips*FIRSTKICKER)+
                             (highPair*SECONDKICKER);
        handDetail->parm[0]=highTrips;
        handDetail->parm[1]=highPair;
        handDetail->parm[2]=0;
        handDetail->parm[3]=0;
        handDetail->parm[4]=0;
    }
    return isABoat;
}

int isThereAFlush(handInfo *handDetail){
    char i;
    int suits[4]={0, 0, 0, 0};
    char suit;
    char isAFlush=FALSE;
    char flushSuit;
    char sortedCards[]={-1, -1, -1, -1, -1, -1, -1};
    char highCard;
    //I know it's a waste of most of the structure by I get to reuse my straight logic
    handInfo holdFlush;
    for(i=0;i<7;i++){
        suit=handDetail->cards[i]%4;
        suits[suit]++;
    }
    for(i=0;i<4;i++){
        if(suits[i]>4){
            isAFlush=TRUE;
            flushSuit=i;
            break;
        }
    }
    if(isAFlush){
        //OK if we know this hand is a flush the only better hand it could be is a straight flush
        //lets check!
       for(i=0;i<7;i++){
           if((handDetail->cards[i]%4)!=flushSuit){
               holdFlush.cards[i]=-1;
               sortedCards[i]=-1;
           }
           else{
               holdFlush.cards[i]=handDetail->cards[i];
               sortedCards[i]=handDetail->cards[i];
           }
       }

       if(isThereAStraight(&holdFlush)){
           //printf("!!!!!!!There is a Straight Flush high card is %s\n", cardRank[holdFlush.parm[0]]);
           handDetail->handType=SFlush;
           handDetail->handValue=(HANDTYPE*SFLUSH)+
                                (holdFlush.parm[0]*FIRSTKICKER);// only place parm is needed, should be refactored out
       }
       else{
           sortCards(sortedCards);
           //printf("There is a flush and it is %s!!!!!!!!!!!!!\n", suitName[flushSuit]);
           //printf("Flush is ");
           //for(i=0;i<7;i++){
               //if(sortedCards[i] != -1){
                   //printf("%s ", deck[sortedCards[i]]);
               //}
           //}
           //printf("\n");
           handDetail->handType=Flush;
           handDetail->handValue=(HANDTYPE*FLUSH)+
                                ((sortedCards[0]/4)*FIRSTKICKER)+
                                ((sortedCards[1]/4)*SECONDKICKER)+
                                ((sortedCards[2]/4)*THIRDKICKER)+
                                ((sortedCards[3]/4)*FOURTHKICKER)+
                                ((sortedCards[4]/4)*FIFTHKICKER);
           handDetail->parm[0]=sortedCards[0]/4;
           handDetail->parm[1]=sortedCards[1]/4;
           handDetail->parm[2]=sortedCards[2]/4;
           handDetail->parm[3]=sortedCards[3]/4;
           handDetail->parm[4]=sortedCards[4]/4;
       }
    }
    return 0;
}

int isThereAStraight(handInfo *handDetail){
    char i;
    char cardCount[]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    char highCard=0;
    int isAStraight=FALSE;
    for(i=0;i<7;i++){
        if(handDetail->cards[i]!=-1){
            cardCount[(handDetail->cards[i]/4)]++;
        }
    }
    if(cardCount[FIVE] > 0 && cardCount[FOUR] > 0 && cardCount[THREE] > 0 && cardCount[DEUCE] > 0 && cardCount[ACE] > 0){
        highCard=FIVE;
    }
    if(cardCount[SIX] > 0 && cardCount[FIVE] > 0 && cardCount[FOUR] > 0 && cardCount[THREE] > 0 && cardCount[DEUCE] > 0){
        highCard=SIX;
    }
    if(cardCount[SEVEN] > 0 && cardCount[SIX] > 0 && cardCount[FIVE] > 0 && cardCount[FOUR] > 0 && cardCount[THREE] > 0){
        highCard=SEVEN;
    }
    if(cardCount[EIGHT] > 0 && cardCount[SEVEN] > 0 && cardCount[SIX] > 0 && cardCount[FIVE] > 0 && cardCount[FOUR] > 0){
        highCard=EIGHT;
    }
    if(cardCount[NINE] > 0 && cardCount[EIGHT] > 0 && cardCount[SEVEN] > 0 && cardCount[SIX] > 0 && cardCount[FIVE] > 0){
        highCard=NINE;
    }
    if(cardCount[TEN] > 0 && cardCount[NINE] > 0 && cardCount[EIGHT] > 0 && cardCount[SEVEN] > 0 && cardCount[SIX] > 0){
        highCard=TEN;
    }
    if(cardCount[JACK] > 0 && cardCount[TEN] > 0 && cardCount[NINE] > 0 && cardCount[EIGHT] > 0 && cardCount[SEVEN] > 0){
        highCard=JACK;
    }
    if(cardCount[QUEEN] > 0 && cardCount[JACK] > 0 && cardCount[TEN] > 0 && cardCount[NINE] > 0 && cardCount[EIGHT] > 0){
        highCard=QUEEN;
    }
    if(cardCount[KING] > 0 && cardCount[QUEEN] > 0 && cardCount[JACK] > 0 && cardCount[TEN] > 0 && cardCount[NINE] > 0){
        highCard=KING;
    }
    if(cardCount[ACE] > 0 && cardCount[KING] > 0 && cardCount[QUEEN] > 0 && cardCount[JACK] > 0 && cardCount[TEN] > 0){
        highCard=ACE;
    }
    if(highCard){
           handDetail->handValue=(HANDTYPE*STRAIGHT)+
                                (highCard*FIRSTKICKER);
           handDetail->parm[0]=highCard;
           handDetail->parm[1]=0;
           handDetail->parm[2]=0;
           handDetail->parm[3]=0;
           handDetail->parm[4]=0;
           isAStraight=TRUE;
           //printf("!!!!!!!There is a Straight high card is %s\n", cardRank[highCard]);
    }
    return isAStraight;
}

int isThereTrips(handInfo *handDetail){
    char i;
    char cardCount[]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    char highTrips=-1;
    char kicker1=-1;
    char kicker2=-1;
    int isTrips=FALSE;
    for(i=0;i<7;i++){
        cardCount[(handDetail->cards[i]/4)]++;
    }
    for(i=12;i>-1;i--){
        if(cardCount[i]==3){
            highTrips=i;
            isTrips=TRUE;
            break;
        }
    }
    if(isTrips){
        for(i=12;i>-1;i--){
            if(i!=highTrips){
                if(cardCount[i]>0){
                    if(kicker1==-1){
                        kicker1=i;
                    }
                    else{
                        kicker2=i;
                        break;
                    }
                }
            }
        }
        //printf("!!!!We have trips %s with kicker %s & %s\n", cardRank[highTrips], cardRank[kicker1], cardRank[kicker2]);
        handDetail->handType=Trips;
        handDetail->handValue=(HANDTYPE*TRIPS)+
                             (highTrips*FIRSTKICKER)+
                             (kicker1*SECONDKICKER)+
                             (kicker2*THIRDKICKER);
        handDetail->parm[0]=highTrips;
        handDetail->parm[1]=kicker1;
        handDetail->parm[2]=kicker2;
        handDetail->parm[3]=0;
        handDetail->parm[4]=0;
    }
    return isTrips;
}

int isThereTwoPair(handInfo *handDetail){
    char i;
    char cardCount[]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    char highPair=-1;
    char lowPair=-1;
    char kicker=-1;
    int isTwoPair=FALSE;
    for(i=0;i<7;i++){
        cardCount[(handDetail->cards[i]/4)]++;
    }
    for(i=12;i>-1;i--){
        if(cardCount[i]==2){
            highPair=i;
            break;
        }
    }
    if(highPair>-1){
        for(i=12;i>-1;i--){
            if(i!=highPair){
                if(cardCount[i]==2){
                    lowPair=i;
                    isTwoPair=TRUE;
                }
            }
        }
    }
    if(isTwoPair){
        for(i=12;i>-1;i--){
            if(i!=highPair && i!=lowPair){
                if(cardCount[i]>0){
                        kicker=i;
                        break;
                }
            }
        }
        //printf("!!!!Two Pair %s and %s with kicker %s\n", cardRank[highPair], cardRank[lowPair], cardRank[kicker]);
        handDetail->handType=TwoPair;
        handDetail->handValue=(HANDTYPE*TWOPAIR)+
                             (highPair*FIRSTKICKER)+
                             (lowPair*SECONDKICKER)+
                             (kicker*THIRDKICKER);
        handDetail->parm[0]=highPair;
        handDetail->parm[1]=lowPair;
        handDetail->parm[2]=kicker;
        handDetail->parm[3]=0;
        handDetail->parm[4]=0;
    }
    return isTwoPair;
}

int isThereOnePair(handInfo *handDetail){
    char i;
    char cardCount[]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    char pair=-1;
    char kicker1=-1;
    char kicker2=-1;
    char kicker3=-1;
    int isPair=FALSE;
    for(i=0;i<7;i++){
        cardCount[(handDetail->cards[i]/4)]++;
    }
    for(i=12;i>-1;i--){
        if(cardCount[i]==2){
            pair=i;
            isPair=TRUE;
            break;
        }
    }
    if(isPair){
        for(i=12;i>-1;i--){
            if(i!=pair){
                if(cardCount[i]>0){
                    if(kicker1==-1){
                        kicker1=i;
                    }
                    else{
                        if(kicker2==-1){
                            kicker2=i;
                        }
                        else{
                            kicker3=i;
                            break;
                        }
                    }
                }
            }
        }
        //printf("!!!!A pair of %s with kickers %s & %s & %s\n", cardRank[pair], cardRank[kicker1], cardRank[kicker2], cardRank[kicker3]);
        handDetail->handType=OnePair;
        handDetail->handValue=(HANDTYPE*ONEPAIR)+
                             (pair*FIRSTKICKER)+
                             (kicker1*SECONDKICKER)+
                             (kicker2*THIRDKICKER)+
                             (kicker3*FOURTHKICKER);
        handDetail->parm[0]=pair;
        handDetail->parm[1]=kicker1;
        handDetail->parm[2]=kicker2;
        handDetail->parm[3]=kicker3;
        handDetail->parm[4]=0;
    }
    return isPair;
}

int sortCards(char sortedCards[]){
//sort the cards by rank, simple bubble sort
    char holdCard;
    char i;
    char i2;
    char i3;
    for(i=0;i<6;i++){
        for(i2=0;i2<6;i2++){
            i3=i2+1;
            if(sortedCards[i2]<sortedCards[i3]){
                holdCard=sortedCards[i2];
                sortedCards[i2]=sortedCards[i3];
                sortedCards[i3]=holdCard;
            }
        }
    }
    return 0;
}

hands.h
#define TRUE 1
#define FALSE 0
#define CLUBS 0
#define DIAMONDS 1
#define HEARTS 2
#define SPADES 3
#define ACE 12
#define DEUCE 0
#define THREE 1
#define FOUR 2
#define FIVE 3
#define SIX 4
#define SEVEN 5
#define EIGHT 6
#define NINE 7
#define TEN 8
#define JACK 9
#define QUEEN 10
#define KING 11
#define HANDTYPE  10000000000LL
#define FIRSTKICKER 100000000
#define SECONDKICKER  1000000
#define THIRDKICKER     10000
#define FOURTHKICKER      100
#define FIFTHKICKER         1
#define SFLUSH   9
#define QUADS    8
#define BOAT     7
#define FLUSH    6
#define STRAIGHT 5
#define TRIPS    4
#define TWOPAIR  3
#define ONEPAIR  2
#define HIGHCARD 1
enum HandType{SFlush,Quads,Boat,Flush,Straight,Trips,TwoPair,OnePair,HighCard,unknown};
typedef struct {
    enum HandType handType; // only needed in one line of code should be refactored out
    char parm[5]; // only needed in one line of code should be refactored out
    char cards[7];
    /* handValue is a way I can value all hands in 11 digits and compare them to decide
       which hand is better */
    long long int handValue;
    int handKey;
    char isSuited;
}handInfo;

typedef char * string;

static const string suitName[]={"Clubs", "Diamonds", "Hearts", "Spades"};

static const string deck[]={"2c", "2d", "2h", "2s",
                            "3c", "3d", "3h", "3s",
                            "4c", "4d", "4h", "4s",
                            "5c", "5d", "5h", "5s",
                            "6c", "6d", "6h", "6s",
                            "7c", "7d", "7h", "7s",
                            "8c", "8d", "8h", "8s",
                            "9c", "9d", "9h", "9s",
                            "Tc", "Td", "Th", "Ts",
                            "Jc", "Jd", "Jh", "Js",
                            "Qc", "Qd", "Qh", "Qs",
                            "Kc", "Kd", "Kh", "Ks",
                            "Ac", "Ad", "Ah", "As"};
static const string cardRank[]={"2", "3", "4", "5", "6", "7", "8",
                              "9", "T", "J", "Q", "K", "A"};
static const char charCardRank[]={'2', '3', '4', '5', '6', '7', '8',
                              '9', 'T', 'J', 'Q', 'K', 'A'};