问题
Is there any easy method to compare two poker hands? I'm going about this pretty naively, so if anybody has experience doing this, it could be helpful.
回答1:
There isn't an easy (and performant) way to do this, especially if you want to evaluate five-card subsets of seven-card hands, like in Texas Hold 'em.
You might want to check out pokersource which has some Java bindings.
Edit - an additional resource is the pokerai forums. I found quite a few Java algorithms there. They are regularly run through benchmarks and are often accompanied by enumeration algorithms for Monte Carlo simulation. This appears to be the main post.
回答2:
I found this which seems promising.
You can also roll your own.
回答3:
Look at this free poker java lib from Alberta university : http://spaz.ca/poker/doc/ca/ualberta/cs/poker/package-summary.html
回答4:
(Shameless plug) You can use my library to do this pretty easily
https://github.com/ableiten/foldem
The code for doing so looks something like this:
Evaluator evaluator = new DefaultEvaluator();
Board board = board("AcTs4d3h3s");
Hand a = hand("AsTd");
Hand b = hand("TcJh");
if (evaluator.rank(a, board) > evaluator.rank(b, board)) {
System.out.println("Hand A wins!");
} else {
System.out.println("Hand B wins (or draws)!");
}
Also has support for simulation based equity calculation and basic postflop analysis.
回答5:
Assuming you already have some kind of data structure in place for determining the kind of hand that the player has, you could just assign some kind of int value to each type of hand and compare them. Whatever player has the higher value wins. If the values are equal, you'd just have to compare the hands against eachother. I.E if both have pairs, just compare the numbers of the card, or if they have a full house, compare the value of the card that they have 3 of.
EDIT: if they have the same hand, just check the next highest card in their hand (kicker).
回答6:
An example of a ready made Texas Hold'em 7- and 5-card evaluator can be found here with documentation and further explained here. All feedback welcome at the e-mail address found therein.
回答7:
I wrote a poker hand evaluation library for java, that does exactly what your looking for. It wasn't easy but it is performant. I released it under the GNU GPL on GitHub.
get sourecode here
回答8:
I wrote this, let me know if this helps. Essentially I map each card to a number 2 of spades being 0,and Ace of spades being a 12 and 2 of hearts a 3 etc etc. I wish I saw this thread before I put in the work.
/**
* Takes any subset of numberCards and creates an array which directly says
* how good the cards are This method is long so If it is working try not to
* tweak it TODO potential re-factor
*
* @todo Fix this @fixMe
* @param cards to analyze
* @return condensed form of hand in the format(tier, High Card, High Card
* 2,Kicker(s),sometimes some zeroes)
*/
public static int[] analyzeCards(int[] cards) {
int suitFlush = 0;
int[] unsuitedCards = new int[cards.length];
for (int i = 0; i < cards.length; i++) {
unsuitedCards[i] = (cards[i] % 13);
}
Arrays.sort(unsuitedCards);
unsuitedCards = reverse(unsuitedCards);
//converting cards into just numbers 0-12 in descending order
int[] lookForPairsHere=unsuitedCards.clone();
// System.out.println(Arrays.toString(unsuitedCards));
//defining the suits of the cards 0,1,2,3
// and the suits are in order of the cards
int[] suitsOfCards = new int[cards.length];
for (int i = 0; i < cards.length; i++) {
suitsOfCards[i] = cards[i] / 13;
}
int[] numberOfEachValuedCard = {0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0};
int[] pairs = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
lookForPairsHere = unsuitedCards.clone();
int[] originalCards = cards.clone();
int[] condensedCards = {0, -1, 0, 0, 0, 0};
int[] suits = {0, 0, 0, 0};
boolean[] hasQuality = {false, false}; // hasQuality[0] is flush and
//hasQuality[1] is a straight
for (int i = 0; i < suitsOfCards.length; i++) {
suits[suitsOfCards[i]]++;
}
for (int i = 0; i < 4; i++) {
if (suits[i] > 4) {
hasQuality[0] = true;
// System.out.println("flush");
// there is a flush!
suitFlush = i;
}
}
int[] straightCards = {-2, -2, -2, -2, -2, -2, -2};
int i = 0;
int j = 1;
int card = 0;
// some iterators I will need to keep track of temporarily
// i is just an iterator j is the number of consecuetive cards
if(hasQuality[0]){
for (i = 0; i <originalCards.length; i++) {
if (originalCards[i]/13 == suitFlush) {
straightCards[i] = originalCards[i];
}
}
Arrays.sort(straightCards);
straightCards=reverse(straightCards);
//sorting flushCards in order;
unsuitedCards = removeDuplicates(unsuitedCards);
// getting rid of duplicates to prevent trouble
condensedCards[1]=straightCards[0]%13;
}
if (/*there is not a flush already*/!hasQuality[0]) {
for(i=0;(i<unsuitedCards.length-5);i++){
if(unsuitedCards[i]-1==unsuitedCards[i+1]&&
unsuitedCards[i]-2==unsuitedCards[i+2]&&
unsuitedCards[i]-3==unsuitedCards[i+3]&&
unsuitedCards[i]-4==unsuitedCards[i+4]){
hasQuality[1]=true;
condensedCards[1]=unsuitedCards[i];
}
}
if (hasQuality[1] == false) {
int b = 0;
if (unsuitedCards[0] == 12) {
//looks for ace-5 flush
for (i = 0; i < unsuitedCards.length; i++) {
if (unsuitedCards[i] == 3 || unsuitedCards[i] == 2 || unsuitedCards[i] == 1
|| unsuitedCards[i] == 0) {
b++;
}
}
if (b>3) {
hasQuality[1] = true;
//there is an ace-5 flush
condensedCards[1] = 3;
}
}
}
} else/*there is a flush already so a straight is suited*/ {
Arrays.sort(straightCards);
straightCards = reverse(straightCards);
//order it
// look for A normal straight
for(i=0;(i<straightCards.length-5);i++){
if(straightCards[i]-1==straightCards[i+1]&&
straightCards[i]-2==straightCards[i+2]&&
straightCards[i]-3==straightCards[i+3]&&
straightCards[i]-4==straightCards[i+4]){
hasQuality[1]=true;
condensedCards[1]=straightCards[i];
}
}
if (hasQuality[1] == false) {
int b = 0;
if (straightCards[0] == 12) {
//looks for ace-5 flush
for (int z = 0; (z< straightCards.length); z++){
if (straightCards[z] == 3 || straightCards[z] == 2 ||
straightCards[z] == 1
||straightCards[z] == 0) {
b++;
}
}
if (b>3) {
hasQuality[1] = true;
//there is an ace-5 flush
condensedCards[1] = 3;
}
}
}
}
if (hasQuality[1] && hasQuality[0]) {
condensedCards[0] = 8;
return condensedCards;
}
if (hasQuality[1] && !hasQuality[0]) {
condensedCards[0] = 4;
return condensedCards;
}
if (hasQuality[0] && !hasQuality[1]) {
condensedCards[0] = 5;
for(i=2;i<=5;i++){
condensedCards[i]=straightCards[i-1];
}
return condensedCards;
}
card = 0;
for (i = 0; i < lookForPairsHere.length; i++) {
numberOfEachValuedCard[lookForPairsHere[i]]++;
}
for (i = 12; i >= 0 && card < 5; i--) {
// create an array that has how much of each card
if (numberOfEachValuedCard[i] > 0) {
pairs[2 * card] = numberOfEachValuedCard[i];
pairs[2 * card + 1] = i;
card++;
}
}
//parse the array above
int[] pairCondensed = {0, 0, 0, 0, 0};
for (i = 0; i < 5; i++) {
pairCondensed[i] = pairs[2 * i];
}
//highest to lowest
Arrays.sort(pairCondensed);
pairCondensed = reverse(pairCondensed);
if (pairCondensed[0] == 4 && pairCondensed[1] == 1) {
//four of a kind
condensedCards[0] = 7;
for (i = 0; pairs[i] > 0; i += 2) {
if (pairs[i] == 4) {
condensedCards[1] = pairs[i + 1];
}
for (j = 0; j < 10; j += 2) {
if (pairs[j] == 1) {
condensedCards[2] = pairs[j + 1];
break;
}
}
}
return condensedCards;
}
if (pairCondensed[0] == 3 && pairCondensed[1] == 2) {
//full house
condensedCards[0] = 6;
for (i = 0; i < 10; i += 2) {
if (pairs[i] == 3) {
condensedCards[1] = pairs[i + 1];
}
if (pairs[i] == 2) {
condensedCards[2] = pairs[i + 1];
}
}
return condensedCards;
}
if (pairCondensed[0] == 3 && pairCondensed[1] == 1) {
//three kind
condensedCards[0] = 3;
for (i = 0; i < 10; i += 2) {
if (pairs[i] == 3) {
condensedCards[1] = pairs[i + 1];
}
}
//kicker stuff here
j = 3;
for (i = 0; j < 5; i++) {
if (unsuitedCards[i] != condensedCards[1]) {
condensedCards[j] = unsuitedCards[i];
j++;
}
}
}
if (pairCondensed[0] == 2 && pairCondensed[1] == 2) {
//two pair
condensedCards[0] = 2;
for (i = 0; i < 10; i += 2) {
if (pairs[i] == 2 && condensedCards[1] == -1) {
condensedCards[1] = pairs[i + 1];
}
if (pairs[i] == 2 && condensedCards[1] != -1) {
condensedCards[2] = pairs[i + 1];
}
}
if (condensedCards[2] > condensedCards[1]) {
int temp2 = condensedCards[2];
int temp1 = condensedCards[1];
condensedCards[1] = temp2;
condensedCards[2] = temp1;
}
//kicker stuff here
j = 3;
for (i = 0; j < 4; i++) {
if (unsuitedCards[i]
!= condensedCards[1] && unsuitedCards[i]
!= condensedCards[2]) {
condensedCards[j] = unsuitedCards[i];
j++;
}
}
}
if (pairCondensed[0] == 2&&pairCondensed[1]==1) {
//one pair
condensedCards[0] = 1;
for (i = 0; i < 10; i += 2) {
if (pairs[i] == 2) {
condensedCards[1] = pairs[i + 1];
}
}
//kicker stuff here
j = 3;
for (i = 0; j < 6 && i < 5; i++) {
if (unsuitedCards[i] != condensedCards[1]) {
condensedCards[j] = unsuitedCards[i];
j++;
}
}
}
if (condensedCards[0] == 0) {
//high card/ no pair
for (i = 0,j=1; j <=5 && i < originalCards.length; i++) {
condensedCards[j]=lookForPairsHere[i];
j++;
}
}
return condensedCards;
}
来源:https://stackoverflow.com/questions/5205949/poker-hands-in-java