I'm trying to create a hand evaluator that it will allow me to compare if one hand is better than another. I know there many other post on SO about this topic however many of them are old now and the links no longer link to anything useful. The only way I can think of doing this at the moment is to manually check for every different combination. Eg check for ace of any suit, if this doesn't exist then move to the next combination eg straight flush then 4 of a kind and so on. However, then how would you compare a pair of 2s to a pair of 3s unless you gave an integer to every combination of cards that made something interesting. However, that would very hard to do manually. Is there a better way?
-
3Do it manually but do it in order of decreasing hand strength so you don't accidentally evaluate a 2 pair that was actually a 3 pair for instance. So basically, check if it's a royal flush, check if its a straight flush, check if its a 4 of a kind, and so on... – Ogen Nov 12 '14 at 10:25
-
@John, do you already have the code to check if the player has 2s or 3s etc.? – ihsan Nov 12 '14 at 10:53
-
@Ihsan no sorry I've only just started looking at this from a theoretical aspect wondering how I will do it rather than actually trying to implement it yet. – Alex Nov 12 '14 at 10:56
-
Oh, well, okay then! – ihsan Nov 12 '14 at 10:59
-
The complicated part is to identify the combination's "power"(flush is tronger the a pair, etc...), not card value – Alaychem goes to Codidact Nov 12 '14 at 10:59
-
There are ready-made libraries available, including mine: http://lcrocker.github.io/onejoker/. Mine is probably the least useful if you want to learn how to do it, because it's a big opaque lookup table, but it's fast. – Lee Daniel Crocker Nov 12 '14 at 16:44
3 Answers
Why hard?
class Card{
String suite;
int value;
....
}
// ...if two combinations are equal, Do for both combinations
int power = 0;
for (Card card: combination){
power += card.getValue()
}
// and compare!

- 533
- 5
- 19
-
1Enums would work better for both suites and cards. Also, if not needed for anything else `ordinal()` method could be used instead of value – Deltharis Nov 12 '14 at 10:24
-
@Alaychem but cards have different values depending on their context for example 4 twos have more value than 3 kings etc. – Alex Nov 12 '14 at 10:39
-
@John you asked "how would you compare a pair of 2s to a pair of 3s?" and to this I've answerd. first, of course, you must identify comination and compare them. – Alaychem goes to Codidact Nov 12 '14 at 10:46
-
@John Has Neil Ghani not converted you to haskell? I read a good answer on this the other week http://stackoverflow.com/questions/6598203/poker-hands-modeling-question – Kevvvvyp Nov 18 '14 at 22:33
I would separate the problem for each type of combinations, and assign an integer for a specific occurence of a combination called ie. strength (so a Straight Flush of 5-4-3-2-A is the weakest and K-Q-J-10-9 is the strongest).
Individual combinations can be handled pretty well i think. For a royal flush, you sort your 7 cards by their number descending, and check if the first 5 cards are (A-K-Q-J-10) and if they are of the same suit. A royal flush's strength is indefinite.
For flush you can sort your cards by suit, and check if you can move 4 times in your list of card without witnessing a suit change. A Flush's strength is determined by the highest valued card of it.
A very brief template for the idea:
// main logic of who wins, note it doesn't handle when two players have the same
// combo with same strength
class HandComparator {
public Player compare(Player player1, Player player2) {
HandEvaluator handEvaluator = new HandEvaluator();
Combination player1Combo = handEvaluator.evaluate(player1.hand);
Combination player2Combo = handEvaluator.evaluate(player2.hand);
if (player1Combo.type.equals(player2Combo.type)) {
// note, strength is only taken into account if the two players have
// the same combo (ie both has full house)
if (player1Combo.strength < player2Combo.strength) {
return player2;
} else {
return player1;
}
} else if (player1Combo.type.compareTo(player2Combo.type) < 0) {
return player2;
} else {
return player1;
}
}
}
class Card {
int suit;
int number;
}
class Player {
List<Card> hand;
}
// this is built by CombinationRecognisers. Note, that the member 'strength' is
// related to a specific combination, not all possible hands
class Combination {
enum Type {
ROYAL_FLUSH,
STRAIGHT_FLUSH;
// etc.
}
Type type;
int strength;
}
// implement this for all combinations (ROYAL_FLUSH,STRAIGHT_FLUSH, etc)
interface CombinationRecogniser {
public Combination evaluate(List<Card> hand);
}
/*
* this class holds all CombinationRecognisers and iterates throught them. It
* will stop the moment a combo has been found.
*/
class HandEvaluator {
static List<CombinationRecogniser> recognizers = new ArrayList<CombinationRecogniser>();
static {
recognizers.add(new RoyalFlushRecogniser());
recognizers.add(new StraightFlushRecogniser());
}
public Combination evaluate(List<Card> hand) {
for (CombinationRecogniser recogniser : recognizers) {
Combination combination = recogniser.evaluate(hand);
if (combination != null) {
return combination;
}
}
return null;
}
}
class RoyalFlushRecogniser implements CombinationRecogniser {
@Override
public Combination evaluate(List<Card> hand) {
// code goes here that decides if the given hand is a valid royal flush
return null; // of new Combination() if the given hand is a valid royal flush
}
}
class StraightFlushRecogniser implements CombinationRecogniser {
@Override
public Combination evaluate(List<Card> hand) {
// code goes here that decides if the given hand is a valid straight flush
return null; // of new Combination() if the given hand is a valid royal flush
}
}
This code actually works if you implement the CombinationRecogniser interface for all special combinations. An example:

- 466
- 1
- 6
- 14
-
1assigning an integer would be a simple way that I would like to do but aren't there too many combinations possible? Like Ace King seven five two of hearts then Like Ace King seven five three of hearts etc. There are 13 choose 5 combinations of flushes that is 1300 combinations. Then the same for straights etc. – Alex Nov 12 '14 at 10:40
-
you don't use that integer to distinguish between all the possible cards, you distinguish between the same combination (ie. to determine which of two straights is better). That's more or less 13 possible outcomes most of the time (ie. 10 possible highest cards are in a straight) – Attila Neparáczki Nov 12 '14 at 10:42
-
Doesn't change the fact that you misunderstand what i'm saying – Attila Neparáczki Nov 13 '14 at 13:21
I don't know if this is the best approach, but this could be possible and this is all manually.
Let's say you already have the code to determine which hand the player has in this format:
22s, KKs, 98o, 11o
Now you have an array with three values e.g.:
["K", "K", "s"]
...and another array:
[9, 8, "o"]
You first have to class those hands (like flush, straight etc.) to make sure which one will win (royal flush always win). And after those checks, you have to do some checks in the array. Check if it's suited or offsuit, if "K"
is higher than 9 etc.
You can give them values like this:
...
8=8
9=9
10=10
J=11
Q=12
K=13
A=14 (or 1)
And then compare with that. This is a hard algorithm to do it properly without doing so many things manually. I hope someone who has experience with this takes my answer over and recover my mistakes or wrong steps/thoughts.

- 576
- 2
- 5
- 18