I am thinking about poker hand (5 cards) evaluation in Java. Now I am looking for simplicity and clarity rather than performance and efficiency. I probably can
You actually don't need any advanced functions, it can be all done bitwise: (source: http://www.codeproject.com/Articles/569271/A-Poker-hand-analyzer-in-JavaScript-using-bit-math)
(This one is actually written in JavaScript, but you can evaluate JavaScript from Java if needed, so it shouldn't be a problem. Also, this is as short as it gets, so if even for illustration of the approach...):
First you split your cards into two arrays: ranks (cs) and suits (ss) and to represent suits, you will use either 1,2,4 or 8 (that is 0b0001, 0b0010,...):
var J=11, Q=12, K=13, A=14, C=1, D=2, H=4, S=8;
Now here's the magic:
function evaluateHand(cs, ss) {
var pokerHands = ["4 of a Kind", "Straight Flush","Straight","Flush","High Card","1 Pair","2 Pair","Royal Flush", "3 of a Kind","Full House"];
var v,i,o,s = 1 << cs[0] | 1 << cs[1] | 1 << cs[2] | 1 << cs[3] | 1 << cs[4];
for (i = -1, v = o = 0; i < 5; i++, o = Math.pow(2, cs[i] * 4)) {v += o * ((v / o & 15) + 1);}
v = v % 15 - ((s / (s & -s) == 31) || (s == 0x403c) ? 3 : 1);
v -= (ss[0] == (ss[1] | ss[2] | ss[3] | ss[4])) * ((s == 0x7c00) ? -5 : 1);
return pokerHands[v];
}
Usage:
evaluateHand([A,10,J,K,Q],[C,C,C,C,C]); // Royal Flush
Now what it does (very briefly) is that it puts 1 into 3rd bit of s when there's a 2, into 4th when there's 3, etc., so for the above example s looks like this:
0b111110000000000
for [A,2,3,4,5] it would look like this
0b100 0000 0011 1100
etc.
v uses four bits to record multiple occurencies of same card, so it's 52bits long and if you have three Aces and two kings, its 8 MSB bits look like:
0111 0011 ...
The last line then checks for a flush or straight flush or royal flush (0x7c00).