Home
Jacks or Better Tool
Deuces Wild Tool
Bankroll Tool
WinPoker Review
Source Code
Links
E-mail
|
Jacks or Better Hand Evaluator
The source code provided on this page is for the class JBEvaluator that takes as input a five card hand and returns a value representing the hand rank (eg straight flush, two pair) for the game of Jacks or Better video poker. See example.cpp in the source code for usage of this class.
Individual cards are represented by an integer between 0 and 51 according to the formula:
- Card = (13 * Suit) + Rank
| Rank | Value |
| Two | 0 |
| Three | 1 |
| Four | 2 |
| Five | 3 |
| Six | 4 |
| Seven | 5 |
| Eight | 6 |
| Nine | 7 |
| Ten | 8 |
| Jack | 9 |
| Queen | 10 |
| King | 11 |
| Ace | 12 |
|
| Suit | Value |
| Club | 0 |
| Diamond | 1 |
| Heart | 2 |
| Spade | 3 |
|
Source Code
The below source code represents 3 files:
- example.cpp - Very simple example program
- JBEvaluator.h - Class definition
- JBEvaluator.cpp - Class functions
/* *******************************************
**** example.cpp ****
**** Should output: ****
*******************************************
**** AS KS QS JS TS Evaluation = 9 ****
**** AC 2C 3C 4C 5C Evaluation = 8 ****
**** 5C 5D 5H 5S JS Evaluation = 7 ****
**** JS JD JH 8S 8C Evaluation = 6 ****
**** AH QH TH 4H 3H Evaluation = 5 ****
**** 8C 9D TS JH QD Evaluation = 4 ****
**** AS AC AD JS TS Evaluation = 3 ****
**** QD QH 2D 2C 7C Evaluation = 2 ****
**** JD JC QS 3C TS Evaluation = 1 ****
**** TS TC 2D JS 4D Evaluation = 0 ****
**** KD QD 7C 5D 2H Evaluation = 0 ****
******************************************* */
#include <stdio.h>
#include "JBEvaluator.h"
void printHand(int *hand)
{
char rank[] = "23456789TJQKA";
char suit[] = "CDHS";
for (int i = 0; i < 5; i++)
{
int card = hand[i];
printf("%c%c ", rank[card % 13], suit[card / 13]);
}
}
int main (int argc, char *argv[])
{
JBEvaluator evaluator;
int hands[11][5] = {
{51,50,49,48,47}, //AS,KS,QS,JS,TS = Royal FLush
{12, 0, 1, 2, 3}, //AC,2C,3C,4C,5C = Straight Flush
{ 3,16,29,42,48}, //5C,5D,5H,5S,JS = Four of a Kind
{48,22,35,45, 6}, //JS,JD,JH,8S,8C = Full House
{38,36,34,28,27}, //AH,QH,TH,4H,3H = Flush
{ 6,20,47,35,23}, //8C,9D,TS,JH,QD = Straight
{51,12,25,48,47}, //AS,AC,AD,JS,TS = Three of a Kind
{23,36,13, 0, 5}, //QD,QH,2D,2C,7C = Two Pair
{22, 9,49, 1,47}, //JD,JC,QS,3C,TS = Jack or Better
{47, 8,13,48,15}, //TS,TC,2D,JS,4D = Nothing
{24,23, 5,16,26} //KD,QD,7C,5D,2H = Nothing
};
for (int i = 0; i < 11; i++)
{
printHand(hands[i]);
printf("Evaluation = %d\n", evaluator.evaluate(hands[i]));
}
}
/* *******************************************
**** JBEvaluator.h ****
******************************************* */
#pragma once
const int ROYAL_FLUSH = 9;
const int STRAIGHT_FLUSH = 8;
const int FOUR_KIND = 7;
const int FULL_HOUSE = 6;
const int FLUSH = 5;
const int STRAIGHT = 4;
const int THREE_KIND = 3;
const int TWO_PAIR = 2;
const int JACK_BETTER = 1;
const int NOTHING = 0;
class JBEvaluator
{
public:
JBEvaluator(void);
~JBEvaluator(void);
int evaluate(int *);
int evaluate(void);
private:
int rankHash[4];
int bitCount[8192];
int straightData[8192];
int *cardData1[52];
int cardData2[52];
};
/* *******************************************
**** JBEvaluator.cpp ****
******************************************* */
#include "JBEvaluator.h"
JBEvaluator::JBEvaluator(void)
{
for (int i = 0; i < 8192; i++)
{
straightData[i] = 0;
bitCount[i] = 0;
for (int j = 0; j < 13; j++)
{
if ((i & (1 << j)))
{
bitCount[i]++;
}
}
}
int straights[10] = {4111,31,62,124,248,496,992,1984,3968,7936};
for (int i = 0; i < 10; i++)
{
straightData[straights[i]] = i + 1;
}
for (int i = 0; i < 52; i++)
{
cardData1[i] = &(rankHash[i / 13]);
cardData2[i] = 1 << (i % 13);
}
}
JBEvaluator::~JBEvaluator(void)
{
}
int JBEvaluator::evaluate(int *hand)
{
rankHash[0] = 0;
rankHash[1] = 0;
rankHash[2] = 0;
rankHash[3] = 0;
*cardData1[hand[0]] |= cardData2[hand[0]];
*cardData1[hand[1]] |= cardData2[hand[1]];
*cardData1[hand[2]] |= cardData2[hand[2]];
*cardData1[hand[3]] |= cardData2[hand[3]];
*cardData1[hand[4]] |= cardData2[hand[4]];
return evaluate();
}
int JBEvaluator::evaluate(void)
{
//Royal Flush
for (int i = 0; i < 4; i++)
{
if (straightData[rankHash[i]] == 10)
{
return ROYAL_FLUSH;
}
}
//Straight Flush
for (int i = 0; i < 4; i++)
{
if (straightData[rankHash[i]])
{
return STRAIGHT_FLUSH;
}
}
//Four of a Kind
int hash4 = rankHash[0] & rankHash[1] & rankHash[2] & rankHash[3];
if (hash4)
{
return FOUR_KIND;
}
//Full House
int hash3 = (rankHash[0] & rankHash[1] & rankHash[2]) | (rankHash[0] & rankHash[1] & rankHash[3])
| (rankHash[0] & rankHash[2] & rankHash[3]) | (rankHash[1] & rankHash[2] & rankHash[3]);
int hash2 = (rankHash[0] & rankHash[1]) | (rankHash[0] & rankHash[2]) | (rankHash[0] & rankHash[3])
| (rankHash[1] & rankHash[2]) | (rankHash[1] & rankHash[3]) | (rankHash[2] & rankHash[3]);
if (hash3 && bitCount[hash2] == 2)
{
return FULL_HOUSE;
}
//Flush
for (int i = 0; i < 4; i++)
{
if (bitCount[rankHash[i]] == 5)
{
return FLUSH;
}
}
//Straight
int hash1 = rankHash[0] | rankHash[1] | rankHash[2] | rankHash[3];
if (straightData[hash1])
{
return STRAIGHT;
}
//Three of a Kind
if (hash3)
{
return THREE_KIND;
}
//Two Pair
if (bitCount[hash2] == 2)
{
return TWO_PAIR;
}
//Jack or Better
if (hash2 >= (1 << 9))
{
return JACK_BETTER;
}
//Nothing
return NOTHING;
}
|