Video Poker Tools

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
RankValue
Two0
Three1
Four2
Five3
Six4
Seven5
Eight6
Nine7
Ten8
Jack9
Queen10
King11
Ace12
SuitValue
Club0
Diamond1
Heart2
Spade3

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;
}


Copyright © 2006 Video Poker Tools