Back to project page pokerdrome.
The source code is released under:
Pokerdrome was released under the GPLv3+ (https://www.gnu.org/licenses/gpl.html) by darlose pokerengine (https://code.google.com/p/pokerengine/) was released under the Apache License 2.0 (https://www...
If you think the Android project pokerdrome listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.darlose.pokerdrome; /*w w w .j av a 2 s .co m*/ /* * Copyright (c) 2005 Your Corporation. All Rights Reserved. */ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; /** * User: sam * Date: Apr 2, 2005 * Time: 4:26:31 PM */ public final class HandRank implements Comparable<HandRank> { private static final int NUM_SUITS = Card.Suit.values().length; private static final int NUM_RANKS = Card.Rank.values().length; private final Cards hand; private final Cards fiveCardHand; private Rank rank = Rank.HIGH; private static final int HAND_SIZE = 5; private static final int TOTAL_POSSIBLE = 7; public String toString() { return fiveCardHand + ": " + rank.name(); } /** * Used to sort handranks. First check to see which has a higher absolute handrank, then if equal, determine which * hand is better. */ public int compareTo(HandRank handRank) { int compare = getRank().compareTo(handRank.getRank()); if (compare != 0) { return compare; } Cards myHand = getHand(); Cards theirHand = handRank.getHand(); for (int i = 0; i < HAND_SIZE; i++) { if (myHand.size() > i) { Card card1 = myHand.get(i); Card card2 = theirHand.get(i); compare = card1.compareTo(card2); if (compare != 0) return compare; } } return 0; } public enum Rank { HIGH, PAIR, TWOPAIR, THREEOFAKIND, STRAIGHT, FLUSH, FULLHOUSE, FOUROFAKIND, STRAIGHTFLUSH } /** * Before calling this method sort the hand from highest to lowest rank. If you do not do this you will not get interesting results. * * @param hand The hand must be sorted from highest to lowest rank. */ public HandRank(Cards hand) { this.hand = hand; fiveCardHand = new Cards(HAND_SIZE); evaluate(); } public Rank getRank() { return rank; } private Cards getHand() { return fiveCardHand; } /* * Evaluate the hand using the rules of poker. * */ private void evaluate() { // Bin cards by rank and suit for (Card card : hand) { assertCard(card); } // Check for flushes and straight flushes if (isStraightFlushOrFlush()) { if (rank == Rank.STRAIGHTFLUSH) return; // If you have a FLUSH and there are 7 or fewer cards, nothing else can beat it if (hand.size() <= 7) return; } // We'll need this to determine the rest of the hands int trips = 0; int pairs = 0; // Check for 4 of a kind, count trips/pairs for (int i = ranks.length - 1; i >= 0; i--) { Card[] value = ranks[i]; if (value == null) continue; Card.Rank key = RANKS[i]; int size = numRanks[i]; if (size >= 4) { rank = Rank.FOUROFAKIND; // Get the five card hand for (int j = 0; j < value.length; j++) { Card card = value[j]; if (card != null) fiveCardHand.add(card); } for (Card card : hand) { if (card.getRank() != key) { fiveCardHand.add(card); return; } } } if (size == 3) trips++; if (size == 2) pairs++; } // Find full houses if ((trips == 1 && pairs >= 1) || (trips > 1)) { foundFullHouse(); return; } // Now we use the flush from above if (rank == Rank.FLUSH) { return; } // Find the straights int[] inarow = {1}; Card firstCard = checkStraight(hand, inarow); if (inarow[0] == HAND_SIZE) { foundStraight(firstCard); return; } // Trips if (trips == 1) { foundTrips(); return; } // Two of a kind if (pairs >= 2) { foundTwoPair(); return; } // One Pair if (pairs == 1) { foundPair(); return; } // High Card for (int i = 0; i < HAND_SIZE; i++) { if (hand.size() > i) fiveCardHand.add(hand.get(i)); } } private void foundFullHouse() { rank = Rank.FULLHOUSE; Card.Rank tripRank = null; // Find the biggest trips for (int i = ranks.length - 1; i >= 0; i--) { Card[] value = ranks[i]; if (value == null) continue; if (numRanks[i] == 3) { tripRank = RANKS[i]; break; } } // Remove this trip and find the biggest match for the house final int tripOrd = tripRank.ordinal(); for (int j = 0; j < numRanks[tripOrd]; j++) fiveCardHand.add(ranks[tripOrd][j]); ranks[tripOrd] = null; Card.Rank pairRank = null; // Find the next biggest pair for (int i = ranks.length - 1; i >= 0; i--) { Card[] value = ranks[i]; if (value == null) continue; if (numRanks[i] >= 2) { pairRank = RANKS[i]; break; } } Card[] pairCards = ranks[pairRank.ordinal()]; // Just add the first two cards from the match for (int i = 0; i < 2; i++) { fiveCardHand.add(pairCards[i]); } } private void foundPair() { rank = Rank.PAIR; Card.Rank firstPair = null; for (int i = 0; i < ranks.length; i++) { Card[] value = ranks[i]; if (value == null) continue; if (numRanks[i] == 2) { firstPair = RANKS[i]; break; } } final int firstOrd = firstPair.ordinal(); for (int i = 0; i < numRanks[firstOrd]; i++) fiveCardHand.add(ranks[firstOrd][i]); int i = 0; for (Card card : hand) { if (card.getRank() != firstPair) { fiveCardHand.add(card); if (++i == 3) break; } } } private void foundStraight(Card firstCard) { boolean add = false; Card last = null; for (Card card : hand) { // Purposeful optimization if (card == firstCard) { add = true; } if (add) { if (last == null || last.getRank() != card.getRank()) { fiveCardHand.add(card); if (fiveCardHand.size() == HAND_SIZE) break; last = card; } } } // Make sure you add the Ace in for the wheel if (fiveCardHand.size() == 4) { fiveCardHand.add(hand.get(0)); } rank = Rank.STRAIGHT; } private void foundTrips() { rank = Rank.THREEOFAKIND; Card.Rank tripRank = null; // Find the biggest trips for (int i = 0; i < ranks.length; i++) { Card[] value = ranks[i]; if (value == null) continue; if (numRanks[i] == 3) { tripRank = RANKS[i]; for (int j = 0; j < numRanks[i]; j++) fiveCardHand.add(ranks[i][j]); break; } } int i = 0; for (Card card : hand) { if (card.getRank() != tripRank) { fiveCardHand.add(card); i++; } if (i == 2) break; } } private void foundTwoPair() { rank = Rank.TWOPAIR; Card.Rank firstPair = null; Card.Rank secondPair = null; int firstOrd = -1; int secondOrd = -1; for (int i = ranks.length - 1; i >= 0; i--) { Card[] value = ranks[i]; if (value == null) continue; if (numRanks[i] == 2) { Card.Rank rank = RANKS[i]; if (firstPair == null) { firstPair = rank; firstOrd = firstPair.ordinal(); } else { secondPair = rank; secondOrd = secondPair.ordinal(); break; } } } for (int i = 0; i < numRanks[firstOrd]; i++) fiveCardHand.add(ranks[firstOrd][i]); for (int i = 0; i < numRanks[secondOrd]; i++) fiveCardHand.add(ranks[secondOrd][i]); for (Card card : hand) { if (card.getRank() != firstPair && card.getRank() != secondPair) { fiveCardHand.add(card); break; } } } private boolean isStraightFlushOrFlush() { for (int i = 0; i < suits.length; i++) { Card[] cards = suits[i]; if (cards == null) continue; if (numSuits[i] >= HAND_SIZE) { int[] inarow = {1}; Card firstCard = checkStraight(cards, numSuits[i], inarow); if (inarow[0] == HAND_SIZE) { boolean add = false; for (int j = 0; j < numSuits[i]; j++) { Card card = suits[i][j]; // Purposeful optimization if (card == firstCard) { add = true; } if (add) { fiveCardHand.add(card); } if (fiveCardHand.size() == HAND_SIZE) break; } if (fiveCardHand.size() == 4) { fiveCardHand.add(suits[i][0]); } rank = Rank.STRAIGHTFLUSH; } else { // At least a flush for (int j = 0; j < HAND_SIZE; j++) { fiveCardHand.add(cards[j]); rank = Rank.FLUSH; } } return true; } } return false; } // This would have been a good place to use a closure. Make sure that this // method changes in sync with the other version private static Card checkStraight(Cards hand, int[] inarow) { // This is the value of the straight Card firstCard = null; // Keep track of the last card so we can skip over pairs and determine continuity Card lastCard = null; // Check to see if there is a straight as well int num = hand.size(); for (int i = 0; i < num; i++) { Card card = hand.get(i); if (lastCard != null) { int lastOrd = lastCard.getRank().ordinal(); int cardOrd = card.getRank().ordinal(); if (lastOrd - cardOrd == 1) { inarow[0]++; if (inarow[0] == 4 && card.getRank() == Card.Rank.TWO && hand.get(0).getRank() == Card.Rank.ACE) { // Wheel inarow[0]++; } } else if (lastOrd - cardOrd != 0) { inarow[0] = 1; firstCard = card; } } else { firstCard = card; } lastCard = card; // Highest straight found if (inarow[0] == HAND_SIZE) return firstCard; // OPT: If we have a straight or have too few cards remaining, return. if (num - i + inarow[0] < HAND_SIZE) return null; } return null; } private static Card checkStraight(Card[] cards, int num, int[] inarow) { // This is the value of the straight Card firstCard = null; // Keep track of the last card so we can skip over pairs and determine continuity Card lastCard = null; // Check to see if there is a straight as well for (int i = 0; i < num; i++) { Card card = cards[i]; if (lastCard != null) { int lastOrd = lastCard.getRank().ordinal(); int cardOrd = card.getRank().ordinal(); if (lastOrd - cardOrd == 1) { inarow[0]++; if (inarow[0] == 4 && card.getRank() == Card.Rank.TWO && cards[0].getRank() == Card.Rank.ACE) { // Wheel inarow[0]++; } } else if (lastOrd - cardOrd != 0) { inarow[0] = 1; firstCard = card; } } else { firstCard = card; } lastCard = card; // Highest straight found if (inarow[0] == HAND_SIZE) return firstCard; // OPT: If we have a straight or have too few cards remaining, return. if (num - i + inarow[0] < HAND_SIZE) return null; } return null; } private final Card[][] ranks = new Card[NUM_RANKS][]; private final int[] numRanks = new int[NUM_RANKS]; private final Card[][] suits = new Card[NUM_SUITS][]; private final int[] numSuits = new int[NUM_SUITS]; private static final Card.Rank[] RANKS = new Card.Rank[NUM_RANKS]; private static final Card.Suit[] SUITS = new Card.Suit[NUM_SUITS]; static { int i = 0; for (Card.Rank rank : Card.Rank.values()) { RANKS[i++] = rank; } i = 0; for (Card.Suit suit : Card.Suit.values()) { SUITS[i++] = suit; } } private void assertCard(Card card) { int cardRank = card.getRank().ordinal(); Card[] rankList = ranks[cardRank]; if (rankList == null) { rankList = new Card[NUM_SUITS]; ranks[cardRank] = rankList; } int numRank = numRanks[cardRank]++; rankList[numRank] = card; int cardSuit = card.getSuit().ordinal(); Card[] suitList = suits[cardSuit]; if (suitList == null) { suitList = new Card[NUM_RANKS]; suits[cardSuit] = suitList; } int numSuit = numSuits[cardSuit]++; suitList[numSuit] = card; } }