I have something working now. I don't have any data to validate against, but I'm pretty sure it is coming up with the correct results.
First thing I did was update the code to generate a 2nd straight lookup table, one where there are 2 jokers. Then I updated eval_joker.h with a function for handling the 2 joker situation.
An enumeration came up with these results, which do seem reasonable:
Code:
BAD: 0
High Card: 26266380
One Pair: 69844920
Two Pair: 39921192
Trips: 8498332
Straight: 17340116
Flush: 8895804
Full House: 5197776
Quads: 487104
Straight Flush: 642120
Quints: 6816
Total Hands: 177100560
The code to generate the table:
Code:
static void
doDoubleStraightTable(void) {
int i, j, k;
MakeTable_begin("doublejokerStraightTable",
DBLJST_FILENAME,
"uint8",
StdDeck_N_RANKMASKS);
MakeTable_comment(DBLJST_COMMENT_STRING);
for (i=0; i < StdDeck_N_RANKMASKS; i++) {
int maxSf = 0, sf;
for (j=StdDeck_Rank_FIRST; j <= StdDeck_Rank_LAST-1; j++) {
for (k=StdDeck_Rank_FIRST+1; k <= StdDeck_Rank_LAST; k++) {
sf = straight_func(i | (1 << j) | (1 << k));
if (sf > maxSf)
maxSf = sf;
};
};
MakeTable_outputUInt8(maxSf);
};
MakeTable_end();
}
My new eval method looks like this, it is called when 2 jokers are present:
Code:
static inline HandVal
JokerDeck_DoubleJokerRules_EVAL_N(JokerDeck_CardMask cards, int n_cards) {
uint32 ranks, ss, sh, sd, sc, jrank, jrank2,
n_ranks, n_dups, two_mask, three_mask, four_mask;
HandVal retval;
/* OK, we know we have 2 jokers */
ss = JokerDeck_CardMask_SPADES(cards);
sc = JokerDeck_CardMask_CLUBS(cards);
sd = JokerDeck_CardMask_DIAMONDS(cards);
sh = JokerDeck_CardMask_HEARTS(cards);
retval = 0;
ranks = SC | SD | SH | SS;
n_ranks = nBitsTable[ranks];
/* Check for straight, flush, or straight flush */
if (n_ranks >= 3) {
if (nBitsTable[SS] >= 3) {
if (doublejokerStraightTable[SS])
retval = HandVal_HANDTYPE_VALUE(JokerRules_HandType_STFLUSH)
+ HandVal_TOP_CARD_VALUE(doublejokerStraightTable[SS]);
else
retval = __flushVal(SS);
}
else if (nBitsTable[SC] >= 3) {
if (doublejokerStraightTable[SC])
retval = HandVal_HANDTYPE_VALUE(JokerRules_HandType_STFLUSH)
+ HandVal_TOP_CARD_VALUE(doublejokerStraightTable[SC]);
else
retval = __flushVal(SC);
}
else if (nBitsTable[SD] >= 3) {
if (doublejokerStraightTable[SD])
retval = HandVal_HANDTYPE_VALUE(JokerRules_HandType_STFLUSH)
+ HandVal_TOP_CARD_VALUE(doublejokerStraightTable[SD]);
else
retval = __flushVal(SD);
}
else if (nBitsTable[SH] >= 3) {
if (doublejokerStraightTable[SH])
retval = HandVal_HANDTYPE_VALUE(JokerRules_HandType_STFLUSH)
+ HandVal_TOP_CARD_VALUE(doublejokerStraightTable[SH]);
else
retval = __flushVal(SH);
}
else {
int st;
st = doublejokerStraightTable[ranks];
if (st)
retval = HandVal_HANDTYPE_VALUE(JokerRules_HandType_STRAIGHT)
+ HandVal_TOP_CARD_VALUE(st);
};
};
/* OK, lets add 2 aces that aren't already set and see what happens; if
all the aces are already set, then we have quints and can return */
jrank = 1 << JokerDeck_Rank_ACE;
if (!(ss & jrank))
ss |= jrank;
else if (!(sc & jrank))
sc |= jrank;
else if (!(sd & jrank))
sd |= jrank;
else if (!(sh & jrank))
sh |= jrank;
else
return HandVal_HANDTYPE_VALUE(JokerRules_HandType_QUINTS)
+ HandVal_TOP_CARD_VALUE(JokerDeck_Rank_ACE);
jrank2 = 1 << JokerDeck_Rank_ACE;
if (!(ss & jrank2))
ss |= jrank2;
else if (!(sc & jrank2))
sc |= jrank2;
else if (!(sd & jrank2))
sd |= jrank2;
else if (!(sh & jrank2))
sh |= jrank2;
else
return HandVal_HANDTYPE_VALUE(JokerRules_HandType_QUINTS)
+ HandVal_TOP_CARD_VALUE(JokerDeck_Rank_ACE);
if (HandVal_HANDTYPE(retval) == JokerRules_HandType_STFLUSH)
return retval;
ranks |= jrank;
ranks |= jrank2;
...
}