Poker-AI.org http://poker-ai.org/phpbb/ |
|
Pokersource handling 2 jokers http://poker-ai.org/phpbb/viewtopic.php?f=24&t=2905 |
Page 1 of 1 |
Author: | cartwright [ Mon May 11, 2015 4:34 am ] |
Post subject: | Pokersource handling 2 jokers |
First, great forum! Sorry for first post being one asking for help, but... I am trying to analyze a game that is a standard 52 card deck plus 2 jokers which act like Pai Gow "bugs". So it can complete straights, flushes, straight flushes, or act as an Ace. It seems the PokerSource evaluator has a joker evaluator, but with a couple of restrictions: 1. It only supports 1 Joker 2. It doesn't let the Joker complete straight flushes. I'm not sure if this is intended... For example, this returns quads instead of a straight flush: Code: JokerDeck_CardMask quadSF = jokerHandStringToMask("XxAs5s4s3sAdAc"); int val = JokerDeck_JokerRules_EVAL_N(quadSF, 7); int type = HandVal_HANDTYPE(val); printf("Hand: %s, Value: %d, Type: %d\n", JokerDeck_maskString(quadSF), val, type); Any advice on how to proceed? Is there a different evaluator that would work better? |
Author: | cartwright [ Mon May 11, 2015 11:04 pm ] |
Post subject: | Re: Pokersource joker_eval bug? |
I updated eval_joker.h adding the following snipped after we check quints and got the results I wanted. Code: if (HandVal_HANDTYPE(retval) == JokerRules_HandType_STFLUSH) return retval; Now I need to figure out how to handle hands with 2 jokers. I've tried adding a second joker card to the deck_joker code as a first step, and it isn't quite working. Anyone ever get pokerSource working with 2 jokers? Is there a different approach anyone might recommend? |
Author: | cartwright [ Mon May 11, 2015 11:29 pm ] |
Post subject: | Re: Pokersource joker_eval bug? |
Here is what I've done so far: - in deck_joker.h I updated the JokerDeck_N_CARDS to 54 since I have 2 jokers, therefore 54 cards. - created a JokerDeck_JOKER2 set to 53 and ensured JokerDeckJOKER is 52 as before. - JokerDeck_IS_JOKER will return true if it is JokerDeckJOKER or JokerDeckJOKER2 - Updated deck_joker.c JokerDeck_cardToString to output Zx for the JokerDeck_JOKER2 card From there I can create a deck and output it, works fine. But if I try to create a hand, I have an issue. - The t_jokercardmasks.c file that is generated has 54 cards (Shouldn't it have had 53?) - The last 2 values in the t_jokercardmasks.c are the same. I presume that means the code can't differentiate between the 2 jokers, therefore can't have both. - I don't know how to modify mktab_joker.c to generate the table I want. Any help? Once I have that working, I guess I'll need to update the doStraightTable function to also account for the second joker. Would appreciate help there as well. |
Author: | cartwright [ Tue May 12, 2015 5:17 am ] |
Post subject: | Re: Pokersource joker_eval bug? |
If anyone is following along, I made some progress. I now have a joker deck that supports 2 jokers properly. It can still only evaluate hands with 1 joker, but it is progress! The change was pretty simple: in deck_joker.h we need to change the suit bit to one with 2 slots <- I guess, still not totally clear on how this works... Code: #ifdef WORDS_BIGENDIAN uint32 joker : 2; uint32 : 1; uint32 spades : 13; uint32 : 3; uint32 clubs : 13; uint32 : 3; uint32 diamonds: 13; uint32 : 3; uint32 hearts : 13; #else uint32 spades : 13; uint32 : 3; uint32 clubs : 13; uint32 : 3; uint32 diamonds: 13; uint32 : 3; uint32 hearts : 13; uint32 : 1; uint32 joker : 2; #endif Then in mktab_joker.c we need to cover both cards: Code: if (i == JokerDeck_JOKER) c.cards.joker = (1 << 0); else if (i == JokerDeck_JOKER2) c.cards.joker = (1 << 1); else { Now I can give it a hand with Zx or Xx and both will evaluate properly. Next step is to update the evaluator to handle hands with 2 jokers. Still seeking advice if anyone has some. |
Author: | spears [ Tue May 12, 2015 12:19 pm ] |
Post subject: | Re: Pokersource handling 2 jokers |
Sorry to see you are not getting much help. I found pokersource pretty hard going myself and it wouldn't surprise me if others feel the same. I eventually used the 2plus2 evaluator which is faster, and would probably use its approach on other game variants. viewtopic.php?f=24&t=2390 |
Author: | cartwright [ Tue May 12, 2015 5:17 pm ] |
Post subject: | Re: Pokersource handling 2 jokers |
spears wrote: Sorry to see you are not getting much help. I found pokersource pretty hard going myself and it wouldn't surprise me if others feel the same. I eventually used the 2plus2 evaluator which is faster, and would probably use its approach on other game variants. http://www.poker-ai.org/phpbb/viewtopic.php?f=24&t=2390 I have the 2p2 evaluator built and working as well, but it doesn't do jokers. My biggest concern was the expanded size of the lookup table when you add jokers to the mix. Maybe I should just build a separate lookup table for hands with jokers? I have found it kind of fun digging through pokersource since it is so heavily optimized. Relearning all the crazy C tricks! |
Author: | cartwright [ Tue May 12, 2015 5:47 pm ] |
Post subject: | Re: Pokersource handling 2 jokers |
cartwright wrote: spears wrote: Sorry to see you are not getting much help. I found pokersource pretty hard going myself and it wouldn't surprise me if others feel the same. I eventually used the 2plus2 evaluator which is faster, and would probably use its approach on other game variants. http://www.poker-ai.org/phpbb/viewtopic.php?f=24&t=2390 I have the 2p2 evaluator built and working as well, but it doesn't do jokers. My biggest concern was the expanded size of the lookup table when you add jokers to the mix. Maybe I should just build a separate lookup table for hands with jokers? I have found it kind of fun digging through pokersource since it is so heavily optimized. Relearning all the crazy C tricks! One other point, you said the 2p2 evaluator is faster, but it seems from the tests run in that original 2p2 thread, it is faster for enumeration, but for random hands (like a monte carlo situation) it isn't faster. My experience as been the same, for me pokersource is quite a bit faster under those conditions. |
Author: | spears [ Tue May 12, 2015 7:34 pm ] |
Post subject: | Re: Pokersource handling 2 jokers |
You may be right that pokersource is faster - I was just speaking from memory or probably my arse. Could you point me at the benchmark that compares them? Note that there were two versions of the java 2p2 code - The pretty version was about 5 times slower than the more optimised one. http://www.poker-ai.org/archive/www.pok ... &sk=t&sd=a Also random hands are not particularly realistic for the cases I've encountered. The 2p2 code does minimal work when one only card changes from the last eval - which is the normal case. I think you and I have a different idea of fun |
Author: | cartwright [ Tue May 12, 2015 8:56 pm ] |
Post subject: | Re: Pokersource handling 2 jokers |
spears wrote: You may be right that pokersource is faster - I was just speaking from memory or probably my arse. Could you point me at the benchmark that compares them? Note that there were two versions of the java 2p2 code - The pretty version was about 5 times slower than the more optimised one. http://www.poker-ai.org/archive/www.pok ... &sk=t&sd=a Also random hands are not particularly realistic for the cases I've encountered. The 2p2 code does minimal work when one only card changes from the last eval - which is the normal case. I think you and I have a different idea of fun Steve Brecher make a compairson in the 2p2 thread, his results are below. I pulled this from the XPokerEval package downloaded from codingthewheel.com. I haven't done any Java development, perhaps some of the optimaztions done would help with C++ as well. I was a full time java developer for a few years and have permanently moved on . All of my stuff is C/C++. For the work I'm doing I do both enumeration and random hands, but I'm not building a poker bot exactly. But for sure with enumeration 2p2 is wicked fast. Code: LOOKUP/RANDOM1M:
BAD!! = 0 High Card = 174303 Pair = 438408 Two Pair = 235438 Three of a Kind = 47901 Straight = 46004 Flush = 30026 Full House = 26001 Four of a Kind = 1632 Straight Flush = 287 Total Hands = 1000000 Validation seconds = 0.5780 Total HighPrecision Clocks = 1977461472 HighPrecision clocks per lookup = 1977.461472 HANDEVAL/RANDOM1M: BAD!! = 0 High Card = 174303 Pair = 438408 Two Pair = 235438 Three of a Kind = 47901 Straight = 46004 Flush = 30026 Full House = 26001 Four of a Kind = 1632 Straight Flush = 287 Total Hands = 1000000 Validation seconds = 0.0310 Total HighPrecision Clocks = 112314720 HighPrecision clocks per lookup = 112.314720 EVALN/RANDOM1M: BAD!! = 0 High Card = 174303 Pair = 438408 Two Pair = 235438 Three of a Kind = 47901 Straight = 46004 Flush = 30026 Full House = 26001 Four of a Kind = 1632 Straight Flush = 287 Total Hands = 1000000 Validation seconds = 0.0310 Total HighPrecision Clocks = 91655640 HighPrecision clocks per lookup = 91.655640 LOOKUP/ENUMERATE: BAD!! = 0 High Card = 23294460 Pair = 58627800 Two Pair = 31433400 Three of a Kind = 6461620 Straight = 6180020 Flush = 4047644 Full House = 3473184 Four of a Kind = 224848 Straight Flush = 41584 Total Hands = 133784560 Validation seconds = 0.6400 Total HighPrecision Clocks = 2157517656 HighPrecision clocks per lookup = 16.126806 HANDEVAL/ENUMERATE: BAD!! = 0 High Card = 23294460 Pair = 58627800 Two Pair = 31433400 Three of a Kind = 6461620 Straight = 6180020 Flush = 4047644 Full House = 3473184 Four of a Kind = 224848 Straight Flush = 41584 Total Hands = 133784560 Validation seconds = 3.1400 Total HighPrecision Clocks = 10640291544 HighPrecision clocks per lookup = 79.533031 EVALN/ENUMERATE: BAD!! = 0 High Card = 23294460 Pair = 58627800 Two Pair = 31433400 Three of a Kind = 6461620 Straight = 6180020 Flush = 4047644 Full House = 3473184 Four of a Kind = 224848 Straight Flush = 41584 Total Hands = 133784560 Validation seconds = 3.2180 Total HighPrecision Clocks = 10912503860 HighPrecision clocks per lookup = 81.567737 |
Author: | cartwright [ Wed May 13, 2015 6:02 am ] |
Post subject: | Re: Pokersource handling 2 jokers |
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; ... } |
Page 1 of 1 | All times are UTC |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |