Guest User

Untitled

a guest
Mar 21st, 2011
1,151
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.util.Arrays;
  2.  
  3. public class HandEval {
  4.     private Card[] availableCards = new Card[7];
  5.    
  6.     private final static short ONE = 1;
  7.     private final static short TWO = 2;
  8.     private final static short THREE = 3;
  9.     private final static short FOUR = 4;
  10.    
  11.     // Constructor
  12.     public HandEval(){
  13.     }
  14.    
  15.     //methods
  16.     protected void addCard(Card card, int i){
  17.         availableCards[i] = card;
  18.     }
  19.    
  20.     protected Card getCard(int i){
  21.         return availableCards[i];
  22.     }
  23.    
  24.     protected int numCards(){
  25.         return availableCards.length;
  26.     }
  27.    
  28.     protected void sortByRank(){
  29.         Arrays.sort(availableCards, new rankComparator());
  30.     }
  31.    
  32.     protected void sortBySuit(){
  33.         Arrays.sort(availableCards, new suitComparator());
  34.     }
  35.    
  36.     protected void sortBySuitThenRank(){
  37.         Arrays.sort(availableCards, new suitComparator());
  38.         Arrays.sort(availableCards, new rankComparator());
  39.     }
  40.    
  41.     protected void sortByRankThenSuit(){
  42.         Arrays.sort(availableCards, new rankComparator());
  43.         Arrays.sort(availableCards, new suitComparator());
  44.     }
  45.    
  46.     protected String evaluateHand(){
  47.         String handResult = new String();
  48.         short[] rankCounter = new short[13];
  49.         short[] suitCounter = new short[4];
  50.        
  51.         // initializations
  52.         for (int i=0;i<rankCounter.length;i++){
  53.             rankCounter[i] =0;
  54.         }
  55.        
  56.         for (int i=4;i<suitCounter.length;i++){
  57.             suitCounter[i] = 0;
  58.         }
  59.        
  60.         // Loop through sorted cards and total ranks
  61.         for(int i=0; i<availableCards.length;i++){
  62.             rankCounter[ availableCards[i].getRank() ]++;
  63.             suitCounter[ availableCards[i].getSuit() ]++;
  64.         }
  65.        
  66.         //sort cards for evaluation
  67.         this.sortByRankThenSuit();
  68.        
  69.         // hands are already sorted by rank and suit for royal and straight flush checks.      
  70.         // check for royal flush
  71.         handResult = evaluateRoyal(rankCounter, suitCounter);
  72.        
  73.         // check for straight flush
  74.         if (handResult == null || handResult.length() == 0){
  75.             handResult = evaluateStraightFlush(rankCounter, suitCounter);
  76.         }
  77.        
  78.         // check for four of a kind
  79.         if (handResult == null || handResult.length() == 0){
  80.             handResult = evaluateFourOfAKind(rankCounter);
  81.         }
  82.        
  83.         // check for full house
  84.         if (handResult == null || handResult.length() == 0){
  85.             handResult = evaluateFullHouse(rankCounter);
  86.         }
  87.        
  88.         // check for flush
  89.         if (handResult == null || handResult.length() == 0){
  90.             handResult = evaluateFlush(rankCounter, suitCounter);
  91.         }
  92.        
  93.         // check for straight
  94.         if (handResult == null || handResult.length() == 0){
  95.             // re-sort by rank, up to this point we had sorted by rank and suit
  96.             // but a straight is suit independent.
  97.             this.sortByRank();
  98.             handResult = evaluateStraight(rankCounter);
  99.         }
  100.        
  101.         // check for three of a kind
  102.         if (handResult == null || handResult.length() == 0){
  103.             handResult = evaluateThreeOfAKind(rankCounter);
  104.         }
  105.        
  106.         // check for two pair
  107.         if (handResult == null || handResult.length() == 0){
  108.             handResult = evaluateTwoPair(rankCounter);
  109.         }
  110.        
  111.         // check for one pair
  112.         if (handResult == null || handResult.length() == 0){
  113.             handResult = evaluateOnePair(rankCounter);
  114.         }
  115.        
  116.         // check for highCard
  117.         if (handResult == null || handResult.length() == 0){
  118.             handResult = evaluateHighCard(rankCounter);
  119.         }
  120.        
  121.         //===================================================================================
  122.         //System.out.println("\nDEBUG: Inside hand eval -- Royal hand to eval:");
  123.         // DEBUG Print rankCounter and suit Counter
  124.         //for (int i=0;i<rankCounter.length;i++){
  125.         //  System.out.println("rankCounter position: " + i + " value: " + rankCounter[i]);
  126.         //}
  127.         //for (int i=0;i<suitCounter.length;i++){
  128.         //  System.out.println("suitCounter position: " + i + " value: " + suitCounter[i]);
  129.         //}
  130.         //===================================================================================
  131.        
  132.        
  133.        
  134.         return handResult;
  135.     }
  136.    
  137.     private String evaluateRoyal(short[] rankCounter, short[] suitCounter){
  138.         String result = "";
  139.        
  140.         // Check for Royal Flush (10 - Ace of the same suit).
  141.         // check if there are 5 of one suit, if not royal is impossible    
  142.         if ((rankCounter[9] >= 1 &&       /* 10 */
  143.                 rankCounter[10] >= 1 &&   /* Jack */
  144.                 rankCounter[11] >= 1 &&  /* Queen */
  145.                 rankCounter[12] >= 1 &&  /* King */
  146.                 rankCounter[0] >= 1)    /* Ace */
  147.                 && (suitCounter[0] > 4 || suitCounter[1] > 4 ||
  148.                         suitCounter[2] > 4 || suitCounter[3] > 4)){
  149.            
  150.             // min. requirements for a royal flush have been met,
  151.             // now loop through records for an ace and check subsequent cards.
  152.             // Loop through the aces first since they are the first card to
  153.             // appear in the sorted array of 7 cards.
  154.             royalSearch:
  155.                 for (int i=0;i<3;i++){
  156.                     // Check if first card is the ace.
  157.                     // Ace must be in position 0, 1 or 2
  158.                     if (availableCards[i].getRank() == 0){
  159.                         // because the ace could be the first card in the array
  160.                         // but the remaining 4 cards could start at position 1,
  161.                         // 2 or 3 loop through checking each possibility.
  162.                         for (int j=1;j<4-i;j++){
  163.                             if ((availableCards[i+j].getRank() == 9 &&
  164.                                     availableCards[i+j+1].getRank() == 10 &&
  165.                                     availableCards[i+j+2].getRank() == 11 &&
  166.                                     availableCards[i+j+3].getRank() == 12)
  167.                                     &&
  168.                                     (availableCards[i].getSuit() == availableCards[i+j].getSuit() &&
  169.                                     availableCards[i].getSuit() == availableCards[i+j+1].getSuit() &&
  170.                                     availableCards[i].getSuit() == availableCards[i+j+2].getSuit() &&
  171.                                     availableCards[i].getSuit() == availableCards[i+j+3].getSuit())){
  172.                                         // Found royal flush, break and return.
  173.                                         result = "Royal Flush!! Suit: " + Card.suitAsString(availableCards[i].getSuit());
  174.                                         break royalSearch;             
  175.                             }
  176.                         }
  177.                     }              
  178.                 }
  179.         }      
  180.         return result;
  181.     }
  182.    
  183.     // Straight flush is 5 consecutive cards of the same suit.
  184.     private String evaluateStraightFlush(short[] rankCounter, short[] suitCounter){
  185.         String result = "";
  186.        
  187.         if (suitCounter[0] > 4 || suitCounter[1] > 4 ||
  188.                 suitCounter[2] > 4 || suitCounter[3] > 4){
  189.            
  190.             // min. requirements for a straight flush have been met.
  191.             // Loop through available cards looking for 5 consecutive cards of the same suit,
  192.             // start in reverse to get the highest value straight flush
  193.             for (int i=availableCards.length-1;i>3;i--){
  194.                 if ((availableCards[i].getRank()-ONE == availableCards[i-ONE].getRank() &&
  195.                         availableCards[i].getRank()-TWO == availableCards[i-TWO].getRank() &&
  196.                         availableCards[i].getRank()-THREE == availableCards[i-THREE].getRank() &&
  197.                         availableCards[i].getRank()-FOUR == availableCards[i-FOUR].getRank())
  198.                         &&
  199.                         (availableCards[i].getSuit() == availableCards[i-ONE].getSuit() &&
  200.                         availableCards[i].getSuit() == availableCards[i-TWO].getSuit() &&
  201.                         availableCards[i].getSuit() == availableCards[i-THREE].getSuit() &&
  202.                         availableCards[i].getSuit() == availableCards[i-FOUR].getSuit())){
  203.                             // Found royal flush, break and return.
  204.                             result = "Straight Flush!! " + Card.rankAsString(availableCards[i].getRank()) + " high of " + Card.suitAsString(availableCards[i].getSuit());
  205.                             break;
  206.                 }
  207.             }
  208.         }
  209.         return result;
  210.     }
  211.    
  212.     // Four of a kind is 4 cards with the same rank: 2-2-2-2, 3-3-3-3, etc...
  213.     private String evaluateFourOfAKind(short[] rankCounter){
  214.         String result = "";
  215.        
  216.         for (int i=0;i<rankCounter.length;i++){
  217.             if (rankCounter[i] == FOUR){
  218.                 result = "Four of a Kind, " + Card.rankAsString(i) +"'s";
  219.                 break;
  220.             }
  221.         }  
  222.         return result;
  223.     }
  224.    
  225.     // Full house is having 3 of a kind of one rank, and two of a kind of
  226.     // a second rank.  EX: J-J-J-3-3
  227.     private String evaluateFullHouse(short[] rankCounter){
  228.         String result = "";
  229.         short threeOfKindRank = -1;
  230.         short twoOfKindRank = -1;
  231.        
  232.         for (int i=rankCounter.length;i>0;i--){
  233.             if ((threeOfKindRank < (short)0) || (twoOfKindRank < (short)0)){
  234.                 if ((rankCounter[i-ONE]) > 2){
  235.                     threeOfKindRank = (short) (i-ONE);                 
  236.                 }
  237.                 else if ((rankCounter[i-ONE]) > 1){
  238.                     twoOfKindRank = (short)(i-ONE);
  239.                 }
  240.             }
  241.             else
  242.             {
  243.                 break;
  244.             }
  245.         }
  246.        
  247.         if ((threeOfKindRank >= (short)0) && (twoOfKindRank >= (short)0)){
  248.             result = "Full House: " + Card.rankAsString(threeOfKindRank) + "'s full of " + Card.rankAsString(twoOfKindRank) + "'s";
  249.         }
  250.        
  251.         return result;
  252.     }
  253.    
  254.     // Flush is 5 cards of the same suit.
  255.     private String evaluateFlush(short[] rankCounter, short[] suitCounter){
  256.         String result = "";
  257.        
  258.         // verify at least 1 suit has 5 cards or more.
  259.         if (suitCounter[0] > 4 || suitCounter[1] > 4 ||
  260.                 suitCounter[2] > 4 || suitCounter[3] > 4){
  261.            
  262.             for (int i=availableCards.length-1;i>3;i--){
  263.                 if (availableCards[i].getSuit() == availableCards[i-ONE].getSuit() &&
  264.                         availableCards[i].getSuit() == availableCards[i-TWO].getSuit() &&
  265.                         availableCards[i].getSuit() == availableCards[i-THREE].getSuit() &&
  266.                         availableCards[i].getSuit() == availableCards[i-FOUR].getSuit()){
  267.                             // Found royal flush, break and return.
  268.                             result = "Flush!! " + Card.rankAsString(availableCards[i].getRank()) + " high of " + Card.suitAsString(availableCards[i].getSuit());
  269.                             break;
  270.                 }
  271.             }          
  272.         }
  273.        
  274.        
  275.         return result;
  276.     }
  277.    
  278.     // Straight is 5 consecutive cards, regardless of suit.
  279.     private String evaluateStraight(short[] rankCounter){
  280.         String result = "";
  281.        
  282.         // loop through rank array to check for 5 consecutive
  283.         // index with a value greater than zero
  284.         for (int i=rankCounter.length;i>4;i--){
  285.             if ((rankCounter[i-1] > 0) &&
  286.                     (rankCounter[i-2] > 0) &&
  287.                     (rankCounter[i-3] > 0) &&
  288.                     (rankCounter[i-4] > 0) &&
  289.                     (rankCounter[i-5] > 0)){
  290.                         result = "Straight " + Card.rankAsString(i-1) + " high";
  291.                         break;
  292.             }
  293.         }
  294.         return result;
  295.     }
  296.    
  297.     // Three of a kind is 3 cards of the same rank.
  298.     private String evaluateThreeOfAKind(short[] rankCounter){
  299.         String result = "";
  300.        
  301.         // loop through rank array to check for 5 consecutive
  302.         // index with a value greater than zero
  303.         for (int i=rankCounter.length;i>0;i--){
  304.             if (rankCounter[i-1] > 2){
  305.                         result = "Three of a Kind " + Card.rankAsString(i-1) + "'s";
  306.                         break;
  307.             }
  308.         }
  309.         return result;
  310.     }
  311.    
  312.     // Two pair is having 2 cards of the same rank, and two
  313.     // different cards of the same rank.  EX: 3-3-7-7-A
  314.     private String evaluateTwoPair(short[] rankCounter){
  315.         String result = "";
  316.         short firstPairRank = -1;
  317.         short secondPairRank = -1;
  318.        
  319.         for (int i=rankCounter.length;i>0;i--){
  320.             if ((firstPairRank < (short)0) || (secondPairRank < (short)0)){            
  321.                 if (((rankCounter[i-ONE]) > 1) && (firstPairRank < (short)0)){
  322.                     firstPairRank = (short) (i-ONE);                   
  323.                 }
  324.                 else if ((rankCounter[i-ONE]) > 1){
  325.                     secondPairRank = (short)(i-ONE);
  326.                 }
  327.             }
  328.             else
  329.             {
  330.                 // two pair found, break loop.
  331.                 break;
  332.             }
  333.         }
  334.        
  335.         // populate output
  336.         if ((firstPairRank >= (short)0) && (secondPairRank >= (short)0)){
  337.             if (secondPairRank == (short)0){
  338.                 // Aces serve as top rank but are at the bottom of the rank array
  339.                 // swap places so aces show first as highest pair
  340.                 result = "Two Pair: " + Card.rankAsString(secondPairRank) + "'s and " + Card.rankAsString(firstPairRank) + "'s";
  341.             }
  342.             else
  343.             {
  344.                 result = "Two Pair: " + Card.rankAsString(firstPairRank) + "'s and " + Card.rankAsString(secondPairRank) + "'s";
  345.             }          
  346.         }
  347.        
  348.         return result;
  349.     }
  350.    
  351.     // One is is two cards of the same rank.
  352.     private String evaluateOnePair(short[] rankCounter){
  353.         String result = "";
  354.        
  355.         for (int i=rankCounter.length;i>0;i--){
  356.             if((rankCounter[i-ONE]) > 1){
  357.                 result = "One Pair: " + Card.rankAsString(i-ONE) + "'s";   
  358.                 break;
  359.             }
  360.         }
  361.         return result;
  362.     }
  363.    
  364.     // high card is the highest card out of the 7 possible cards to be used.
  365.     private String evaluateHighCard(short[] rankCounter){
  366.         String result = "";
  367.        
  368.         for (int i=rankCounter.length;i>0;i--){
  369.             if((rankCounter[i-ONE]) > 0){
  370.                 result = "High Card: " + Card.rankAsString(i-ONE);
  371.                 break;
  372.             }
  373.         }
  374.         return result;
  375.     }
  376.  
  377. }
RAW Paste Data