(require '[clojure.math.combinatorics :as c])
(def mod-deck (vec (for [e (range 52)] [(mod e 13) (mod e 4)])))
(def mod->int (zipmap mod-deck (range 52)))
(def suit-combos (vec (c/permutations [0 1 2 3])))
(def syms (atom {}))
(defn mk-syms [num]
(doall
(pmap
(fn [e] (let [h (sort (map mod-deck e))
entries (first (filter #(@syms %)
(for [f suit-combos]
(sort (mapv #(vector (% 0) (f (% 1)))
h)) ) ) ) ]
(if (nil? entries)
(swap! syms assoc h 1)
(swap! syms update-in [entries] inc) )))
(c/combinations (range 52) num)
))
1
)
(spit "PATHNAME/syms.txt") ;sticks the result in a text file, about 5MB for 5 cards
;(def syms (read-string (slurp "PATHNAME/FILENAME.txt))) ;to read back in
to run for 5 cards: (mk-syms 5)
On my computer ('12 'mini quad), it ran in 82s for 5 cards, so it's not winning any speed awards, but to get different size starting hands, just call with that number. I'm not doing anything here with bit manipulations, but if you want to pack into bits, do something like:
(defn mk-key [hand]
(apply bit-or
(for [e hand] (bit-shift-left 1 e))) )
(def syms-bits (atom {}))
(doseq [[k v] @syms] (swap! syms-bits assoc (mk-key (map mod->int k)) v))
For 7 cards, you may have to slide this into the main function due to memory concerns. The version I originally used was slightly different.
edit: I get the correct # for 5 cards, but I'm not certain I'm taking the appropriate care for doing this in parallel, so I'd double check any output.
Before I go further, let me remind you the formula for choosing k out of n items, with replacement, is combin(n+k-1,k). Think of the deck having k-1 "repeat" cards.
First, let's ask the question how many classes of 5-card hands are there?
- There are combin(13,5)=1,287 ways all five cards can be in the same suit.
- There are combin(13,4)*13=9,295 ways four cards can be in the same suit and one singleton in another suit.
- There are combin(13,3)*combin(13,2)=22,308 ways 3 cards can be in the same suit and 2 in another suit.
- There are combin(13,3)*combin(13+2-1,2)=26,026 ways 3 cards can be in the same suit and 1 each in two other suits.
- There are (COMBIN(13,2)*(COMBIN(13,2)+1)/2)*13=40,053 ways 2 cards can be in two separate suits and 1 in a third suit.
- There are COMBIN(13,2)*COMBIN(13+3-1,3)=35,490 ways 2 cards can be in one suit and 3 singletons in the other 3 suits.
Add that up and you get 133,459.
If you're going to cycle through the whole deck you have to weight all 133,459 by the appropriate number of suits in each class. Here is a table to help you with that.
Suit distribution | Comments | Ranks | Suits | Product |
---|---|---|---|---|
5,0 | All | 1287 | 4 | 5148 |
4,1 | All | 9295 | 12 | 111540 |
3,2 | All | 22308 | 12 | 267696 |
3,1,1 | Matching singletons | 3718 | 12 | 44616 |
3,1,1 | Non-matching singletons | 22308 | 24 | 535392 |
2,2,1 | Both matching ranks | 1014 | 12 | 12168 |
2,2,1 | One matching rank | 11154 | 24 | 267696 |
2,2,1 | No matching ranks | 27885 | 24 | 669240 |
2,1,1,1 | Matching ranks | 1014 | 4 | 4056 |
2,1,1,1 | One matching rank | 12168 | 12 | 146016 |
2,1,1,1 | No matching ranks | 22308 | 24 | 535392 |
Total | 134459 | 2598960 |
I admit this is not elegant like the solutions posted earlier. It will require more code and just one math error will screw everything up. However, it isn't a memory hog. It should use quite little.
I can confirm the 7-card case has 6,009,159 classes of hands. Upon request, I can supply a similar math table for that.
I'm still working on the bit mapping solution, just for my own programming edification.
Assign each rank a Prime Number from 2 to 41.
A Hand evaluates to a unique number which is the product of all of its card ranks.
A second evaluation is done to each cards suit, ie if all suits are equal then it is flush.
The number of possible hands using this unique number are only 6.175
A look Up table is created using this unique number from lowest to highest (so that binary search can be quickly done)
The table has this Unique Number and the ranking of the hand (and a second ranking for flushes) as follows:
NON FLUSH
Unique Ranking Quantity of Rankings
Number
4 Kind 156 11-23 13
FH 156 24-36 13
Straight 10 1314-1323 10
3 Kind 858 1324-1336 13
2 Pairs 858 1337-2194 858
Pair 2860 2195-5054 2860
Nothing 1277 5055-6331 1277
TOTAL 6175 5044
FLUSH
Royal Fl 1 1
Straight Fl 2-10 9
Flush 37-1313 1277
Total 1287
So for example for 4 KIND
You get 156 unique numbers but you rank them only from 11-23, 13 different rankings for the 13 ranks
And the 6.175 unique numbers map to 5044 rankings AND 1287 of them have a second ranking for flushes = 6331 total rankings
Quote: AceTwoA completely different approach to evaluate poker hands which I found out many years ago and did the algorithm in Excel VBA is as follows:
Assign each rank a Prime Number from 2 to 41.
A Hand evaluates to a unique number which is the product of all of its card ranks.
A second evaluation is done to each cards suit, ie if all suits are equal then it is flush.
The number of possible hands using this unique number are only 6.175
A look Up table is created using this unique number from lowest to highest (so that binary search can be quickly done)
The table has this Unique Number and the ranking of the hand (and a second ranking for flushes) as follows:
NON FLUSH
4 Kind 156 11-23 13
FH 156 24-36 13
Straight 10 1314-1323
The method used by "Cactus Kev"?
http://suffe.cool/poker/evaluator.html
Quote: tringlomaneThe method used by "Cactus Kev"?
http://suffe.cool/poker/evaluator.html
Yes. I forgot where I found it. But looking at the link, that's where I found it.
It is quite fast.
Quote: tringlomaneThe method used by "Cactus Kev"?
http://suffe.cool/poker/evaluator.html
Also now that I look at the Cactus Kev Evaluation, I modified it a bit as I was only interested in evaluating normal poker hands between 2 players.
For example 4 Kind has 156 Distinct Hands BUT it is impossible for 2 people to have 4 Kind of the same rank. So mine evaluates only to 13 rankings.
2 cards: 247
3 cards: 1,755
4 cards: 19,435
Anyone agree or disagree?
2 cards: 169 unique patterns
3 cards: 1,755 unique patterns
4 cards: 16,432 unique patterns
Here are the patterns:
Type | Rank Pattern | Rank Weight | Suit Pattern | Suit Weight | Total |
---|---|---|---|---|---|
1P | AA | 13 | AB | 6 | 78 |
0P | A/B | 78 | A/A | 4 | 312 |
0P | A/B | 78 | A/B | 12 | 936 |
Totals | 169 | 1326 |
Type | Rank Pattern | Rank Weight | Suit Pattern | Suit Weight | Total |
---|---|---|---|---|---|
3K | AAA | 13 | ABC | 4 | 52 |
1P | AA/B | 156 | AB/A | 12 | 1872 |
1P | AA/B | 156 | AB/C | 12 | 1872 |
0P | A/B/C | 286 | A/A/A | 4 | 1144 |
0P | A/B/C | 286 | A/A/B | 12 | 3432 |
0P | A/B/C | 286 | A/B/A | 12 | 3432 |
0P | A/B/C | 286 | A/B/B | 12 | 3432 |
0P | A/B/C | 286 | A/B/C | 24 | 6864 |
Totals | 1755 | 22100 |
Type | Rank Pattern | Rank Weight | Suit Pattern | Suit Weight | Total |
---|---|---|---|---|---|
4K | AAAA | 13 | ABCD | 1 | 13 |
3K | AAA/B | 156 | ABC/A | 12 | 1872 |
3K | AAA/B | 156 | ABC/D | 4 | 624 |
2P | AA/BB | 78 | AB/AB | 6 | 468 |
2P | AA/BB | 78 | AB/AC | 24 | 1872 |
2P | AA/BB | 78 | AB/CD | 6 | 468 |
1P | AA/B/C | 858 | AB/A/A | 12 | 10296 |
1P | AA/B/C | 858 | AB/A/B | 12 | 10296 |
1P | AA/B/C | 858 | AB/A/C | 24 | 20592 |
1P | AA/B/C | 858 | AB/C/A | 24 | 20592 |
1P | AA/B/C | 858 | AB/C/C | 12 | 10296 |
1P | AA/B/C | 858 | AB/C/D | 12 | 10296 |
0P | A/B/C/D | 715 | A/A/A/A | 4 | 2860 |
0P | A/B/C/D | 715 | A/A/A/B | 12 | 8580 |
0P | A/B/C/D | 715 | A/A/B/A | 12 | 8580 |
0P | A/B/C/D | 715 | A/A/B/B | 12 | 8580 |
0P | A/B/C/D | 715 | A/A/B/C | 24 | 17160 |
0P | A/B/C/D | 715 | A/B/A/A | 12 | 8580 |
0P | A/B/C/D | 715 | A/B/A/B | 12 | 8580 |
0P | A/B/C/D | 715 | A/B/A/C | 24 | 17160 |
0P | A/B/C/D | 715 | A/B/B/A | 12 | 8580 |
0P | A/B/C/D | 715 | A/B/B/B | 12 | 8580 |
0P | A/B/C/D | 715 | A/B/B/C | 24 | 17160 |
0P | A/B/C/D | 715 | A/B/C/A | 24 | 17160 |
0P | A/B/C/D | 715 | A/B/C/B | 24 | 17160 |
0P | A/B/C/D | 715 | A/B/C/C | 24 | 17160 |
0P | A/B/C/D | 715 | A/B/C/D | 24 | 17160 |
Totals | 16432 | 270725 |
edit: I mention this because it comes to mind when I see 2-4 card counts listed together.
Sorry if this is a high jack... Any chance you are planning to use the techniques in this thread to fashion a more time-efficient analysis of Three-Way Action? (If memory serves, your original code took 80 days!) The reason I ask is that I sometimes play on a version whose pay tables are different from those on your WoO page. By using the hand counts shown on that page (which I believe are sub-optimal for my game), I estimate the return to be only a bit higher than 99%, but I'd love to know the actual return and "optimal-ish" strategy, as this may still be a couponing opportunity. I'd like to know if it's a "good bet" in spite of itself! ;)
Thank you!
"We now return you to your regularly scheduled" thread!
Quite clever, folks, making your code not only effective but efficient! I commend thee!
Quote: camaplHey Wiz,
Sorry if this is a high jack... Any chance you are planning to use the techniques in this thread to fashion a more time-efficient analysis of Three-Way Action? (If memory serves, your original code took 80 days!) The reason I ask is that I sometimes play on a version whose pay tables are different from those on your WoO page. By using the hand counts shown on that page (which I believe are sub-optimal for my game), I estimate the return to be only a bit higher than 99%, but I'd love to know the actual return and "optimal-ish" strategy, as this may still be a couponing opportunity. I'd like to know if it's a "good bet" in spite of itself! ;)
Just for clarity, you're referring to 3 Way Action, with the numeral 3. There is also a defunct table game called Three Way Action.
I'm afraid my analysis on that is over ten years old and I don't recall the details very well. What you see on the page is what there is. I certainly never went down the road of making a playable strategy. Given that this game seems to be going the way of the dodo bird, revisiting it is not a high priority for me.
Sorry, I'm sure that's not what you wanted to hear. And sorry for the tardy reply, I was in Europe at the time you initially asked.
Thanks for the response. Hope the trip went well!
Quote: camaplYes, 3, not Three. Understood. No worries - I only bumped b/c I realized I put "Wiz", not "Wizard."
Thanks for the response. Hope the trip went well!
You're welcome.
Just FYI, bumping is against the rules, but I was in a good mood after some time away.
Yes, had a nice trip. Will post reports on at least the casinos soon.
Quote: WizardQuote: MathExtremist
var list = new Dictionary<long, int>();
List<uint> suits = new List<uint>();
for (var c5 = 4; c5 < 52; ++c5) {
for (var c4 = 3; c4 < c5; ++c4) {
for (var c3 = 2; c3 < c4; ++c3) {
for (var c2 = 1; c2 < c3; ++c2) {
for (var c1 = 0; c1 < c2; ++c1) {
// Set a bit for each card in the bitmask
ulong mask = 1 << c5 | 1 << c4 | 1 << c3 | 1 << c2 | 1 << c1;
// reused variable - start with a blank slate
suits.clear();
// strip the suits out, add them individually to the container
suits.Add((uint)((mask >> (13 * 0)) & 0x1fffUL));
suits.Add((uint)((mask >> (13 * 1)) & 0x1fffUL));
suits.Add((uint)((mask >> (13 * 2)) & 0x1fffUL));
suits.Add((uint)((mask >> (13 * 3)) & 0x1fffUL));
// sort them
suits.Sort();
// rebuild the handprint
ulong key = (ulong)suits[0] | (ulong)suits[1] << (13 * 1) | (ulong)suits[2] << (13 * 2) | (ulong)suits[3] << (13 * 3);
// use the key however you want (e.g., the add-or-increment operation you're already doing.)
// ...
} } } } }
Thank you. I've been trying to figure out the logic of this but your level is obviously higher than mine.
Can you please go over more slowly, and in as simple English as possible, what these lines do:
ulong mask = 1 << c5 | 1 << c4 | 1 << c3 | 1 << c2 | 1 << c1;
and
suits.Add((uint)((mask >> (13 * 3)) & 0x1fffUL));
and
suits.Add((uint)((mask >> (13 * 0)) & 0x1fffUL));
If the code is different in C++, could I trouble you to translate it.
Thank you!!!
I know this thread is long time ago but I am just try to follow to find a good way to map the 1-deck hands into unique one. I am tracking the original post and all replies. I tried the method posted at top, it is quite straightforward to me. I end up getting 134459 hands but when I add the duplicate number for each 134459 hands, I get 2588664 hands instead. I figure out there was a bug in the sorting function (where H should be H) but that's is the reason why end up total 2588664 hands instead of 2598960.
Then, I tried the method I just quoted. It is quite surprisingly short and I port to the c++ code as
map<long, int> uniqueMap;
vector<int> suits;
for (int c5 = 4; c5 < 52; ++c5) {
for (int c4 = 3; c4 < c5; ++c4) {
for (int c3 = 2; c3 < c4; ++c3) {
for (int c2 = 1; c2 < c3; ++c2) {
for (int c1 = 0; c1 < c2; ++c1) {
// Set a bit for each card in the bitmask
long mask = 1 << c5 | 1 << c4 | 1 << c3 | 1 << c2 | 1 << c1;
// reused variable - start with a blank slate
suits.clear();
// strip the suits out, add them individually to the container
suits.push_back((int)((mask >> (13 * 0)) & 0x1fffUL));
suits.push_back((int)((mask >> (13 * 1)) & 0x1fffUL));
suits.push_back((int)((mask >> (13 * 2)) & 0x1fffUL));
suits.push_back((int)((mask >> (13 * 3)) & 0x1fffUL));
// sort them
sort(suits.begin(), suits.end());
// rebuild the handprint
long key = (long)suits[0] | (long)suits[1] << (13 * 1) | (long)suits[2] << (13 * 2) | (long)suits[3] << (13 * 3);
if (uniqueMap.find(key)!=uniqueMap.end()) {
uniqueMap[key]++;
} else {
uniqueMap.insert(make_pair(key, 1));
}
}}}}}
It results 102221 hands but all unique hands with duplicates added up to the 2598960. Could any one help to check what's wrong with my code. Thanks.
In C++ one has to take care about data types, casting and so on.
The following code compiles on VC++ and gives the expected result.
Remark: I cannot post the whole code, because the forum software thinks it contains links.
Therefore only the different lines.
map<unsigned long long, int> uniqueMap;
vector<unsigned long long> suits;
// Set a bit for each card in the bitmask
unsigned long long mask = 1ull << c5 | 1ull << c4 | 1ull << c3 | 1ull << c2 | 1ull << c1;
// rebuild the handprint
unsigned long long key = ((unsigned long long)suits[0]) | ((unsigned long long)suits[1] << (13 * 1)) | ((unsigned long long)suits[2] << (13 * 2)) | ((unsigned long long)suits[3] << (13 * 3));
this is a beginning for me.Quote: ThatDonGuyI seem to recall somebody asking a while ago if there was an "easy" way to map the 2,598,960 different possible 5-card hands into the 134,459 "unique" 5-card hands (the ones that took suits into account, but didn't depend on "specific" suits -
Combin (52,5) = 2,598,960 possible unique poker hands
7,462 = possible distinct poker hands
data, list and thought process from here:
http://suffe.cool/poker/evaluator.html
Hand Value | Unique | Distinct |
---|---|---|
Straight Flush | 40 | 10 |
Four of a Kind | 624 | 156 |
Full Houses | 3744 | 156 |
Flush | 5108 | 1277 |
Straight | 10200 | 10 |
Three of a Kind | 54912 | 858 |
Two Pair | 123552 | 858 |
One Pair | 1098240 | 2860 |
High Card | 1302540 | 1277 |
TOTAL | 2598960 | 7462 |
why do so many say there are 134,459 "unique" 5-card hands
(even S.N. Ethier comes up with that value in his book. I also found out he does not teach any more!)
(I can find this almost everywhere, but the above (that there are only 7,462 where suits do not matter except where they do matter) is found only one place?)
I looked at the text file (he linked to) in Excel and it all looks great and adds up to exactly C(52,5)
I do not see what I may have missed.
and if I did not miss anything
Yahoo!
Sally
Quote: mustangsallythis is a beginning for me.
Combin (52,5) = 2,598,960 possible unique poker hands
7,462 = possible distinct poker hands
data, list and thought process from here:
http://suffe.cool/poker/evaluator.html
Hand Value Unique Distinct Straight Flush 40 10 Four of a Kind 624 156 Full Houses 3744 156 Flush 5108 1277 Straight 10200 10 Three of a Kind 54912 858 Two Pair 123552 858 One Pair 1098240 2860 High Card 1302540 1277 TOTAL 2598960 7462
why do so many say there are 134,459 "unique" 5-card hands
(even S.N. Ethier comes up with that value in his book. I also found out he does not teach any more!)
(I can find this almost everywhere, but the above (that there are only 7,462 where suits do not matter except where they do matter) is found only one place?)
I looked at the text file (he linked to) in Excel and it all looks great and adds up to exactly C(52,5)
I do not see what I may have missed.
and if I did not miss anything
Yahoo!
Sally
Hi, Sally.
My off the cuff answer is that the “unique” hands and “distinct” hands is that unique counts the number of different suits in a hand (but doesn’t care what those suits are), but unique hands ignore how many suits are in a hand.
So a ten high straight containing 3 of one suit (T, 9 and 8) and 2 (7 and 6) of another suit is not distinct from a ten high straight containing 4 of one suit (T, 9, 8, and 7) and 1 of a different suit (6), but they are in different categories for uniqueness. (Because they may have different answers about whether to draw cards.)
This is a pure guess and I am not a VP player.
Quote: mustangsallythis is a beginning for me.
Combin (52,5) = 2,598,960 possible unique poker hands
7,462 = possible distinct poker hands
data, list and thought process from here:
http://suffe.cool/poker/evaluator.html
Hand Value Unique Distinct Straight Flush 40 10 Four of a Kind 624 156 Full Houses 3744 156 Flush 5108 1277 Straight 10200 10 Three of a Kind 54912 858 Two Pair 123552 858 One Pair 1098240 2860 High Card 1302540 1277 TOTAL 2598960 7462
why do so many say there are 134,459 "unique" 5-card hands
(even S.N. Ethier comes up with that value in his book. I also found out he does not teach any more!)
(I can find this almost everywhere, but the above (that there are only 7,462 where suits do not matter except where they do matter) is found only one place?)
I looked at the text file (he linked to) in Excel and it all looks great and adds up to exactly C(52,5)
I do not see what I may have missed.
and if I did not miss anything
Yahoo!
Sally
Your definition of "distinct" is different from mine.
For Straight Flushes, Fours-Of-A-Kind, and Flushes, they are the same.
However, as an example, take Full Houses into account.
You appear to be treating AAAKK as one distinct hand. (In terms of non-draw poker, that is correct.)
I, however, treat it as two:
1. Both Kings have suits that match Aces: As Ah Ad Ks Kh
2. One King has a suit that matches an Ace, but the other does not: As Ah Ad Ks Kc
The distinction is necessary when drawing because of the possibility of drawing a flush.
For straights, the difference is much greater, because for each sequence, there are 4 possible suits for the second card, 4 for the third, 4 for the fourth, and 4 for the fifth (it doesn't matter what suit the first card is), minus the one that makes it a straight flush, which is 255 distinct hands.
You have to differentiate, say, As Ks Qd Js 10s from the other Ace-high straights as you are holding 4 to a Royal Flush, whereas As Kd Qc Jh 10s is only 2 to a Royal, which will require a different play.
What I did was:
1a) change the definition of suits from names to numbers, easier to use; 1, 2, 3 or 4
1b) change the definition of J,Q,K to 11,12,13 and change A to 1 (again, just easier to write programs this way)
1) make the suit of the first card always 1
2) if the suit of the second card is the same as the first card, of course it's 1; if it's different, then make it suit 2
3) if the suit of the third card is the same as the first card, it's 1; if it's the same as the suit of the 2nd card, make it the suit of the 2nd card (would have to be 2); if it's different from both 1st and 2nd cards, then it's suit 3
4) similar process for the fourth card
5) similar process for the fifth card
Then I tally up how many original hands fall into the same mapped hand (what I call "dups") -- it can be 1,2,3,4,6,8,12 or 24.
For example:
2 suit 1
6 suit 2
11 suit 3
12 suit 4
13 suit 2
this one has 24 dups; hold 3 to a straight JQK
4 suit 1
5 suit 1
5 suit 2
9 suit 1
12 suit 2
6 dups; pair of 5's beats the single Q
When I sum all the dups for the 204,087 mapped hands, I get the result I should: 2,598,960
When I do expected value calculations, I take the expected value for any one particular row of the 204,087 and multiply by dups to "un-map" it.
The code only uses itertools. In the code, a suit folding function is provided, which maps any hand to a unique representative. A dictionary "mapping" is also created, where keys are each unique/canonical hands representative, and values are the count of the equivalence class.
Each card is represented by an integer ID from 0 to 51. Suits are represented by 0 to 3, card rank are represented by 0-12, and card ID = rank*4+suit. This ID also coincide with the integer ID used by HenryRLee et al. in their PokerHandEvaluator.
Change r from 5 to 7 gets 7 hands mapping. The 7 hands calculation takes about 16.5 mins in my local computer.
from itertools import combinations
mapping = {}
r = 5
def folding(hand):
rank_list = [[],[],[],[]]
for card in hand:
rank_list[card%4].append(card//4)
rank_list. sort(reverse = True, key=lambda x:(len(x),x))
return tuple(k*4 + i for i in range(0,4) for k in rank_list[i])
for hand in combinations(range(52),r):
mapping[folding(hand)] = mapping. get(folding(hand),0) + 1
print(len(mapping))
cnt=0
for i in mapping:
cnt+=mapping[i]
print(cnt)
void printArrays(handInfo & hand, int weights)
{
int i, j, i0, i1, i2, i3, i4, k;
int deckSize = 54;
// dump unique and weight arrays to stdout for creating source code
int * tmp = new int [3162510 * sizeof(int)];
for (k = 0; k < 3162510; k++) {
tmp[k] = 0;
}
int shift;
unsigned long long int mask, uno = 1, masks[5];
unsigned long long int order, max;
for (i0 = 0; i0 < deckSize - 4; i0++) {
for (i1 = i0 + 1; i1 < deckSize - 3; i1++) {
for (i2 = i1 + 1; i2 < deckSize - 2; i2++) {
for (i3 = i2 + 1; i3 < deckSize - 1; i3++) {
for (i4 = i3 + 1; i4 < deckSize; i4++) {
hand.set(0, i0);
hand.set(1, i1);
hand.set(2, i2);
hand.set(3, i3);
hand.set(4, i4);
hand.indexSort();
mask = (uno << i0) | (uno << i1)
| (uno << i2) | (uno << i3) | (uno << i4);
for (i = 0, shift = 0; shift < 53; i++, shift += 13) {
masks = (mask >> shift) & 0x1fff;
}
// Order the bits for each suit, largest first, into order mask
order = 0;
for (shift = 0; shift < 40; shift += 13) {
max = j = 0;
for (i = 0; i < 4; i++) {
if (masks > max) {
max = masks;
j = i;
}
}
if (max > 0) {
masks= 0;
order |= max << shift;
}
}
// copy jokers to last bits
if (masks[4] > 0) {
order |= masks[4] << 52;
}
// copy the ordered bits back into the hand (with new suits)
j = 0;
for (i = 0; i < 5; i++) {
for ( ; j < 54; j++) {
if ((order >> j) & 1) {
hand.set(i, j++);
break;
}
}
}
hand.indexSort();
k = hand.key5();
tmp[k]++;
}
}
}
}
}
i = j = 0;
if (weights < 2) {
printf("char unique[] = {\n");
} else {
printf("char weight[] = {\n");
}
for (i0 = 0; i0 < deckSize - 4; i0++) {
for (i1 = i0 + 1; i1 < deckSize - 3; i1++) {
for (i2 = i1 + 1; i2 < deckSize - 2; i2++) {
for (i3 = i2 + 1; i3 < deckSize - 1; i3++) {
for (i4 = i3 + 1; i4 < deckSize; i4++) {
if (i4 == 53 && i3 != 52) continue;
hand.set(0, i0);
hand.set(1, i1);
hand.set(2, i2);
hand.set(3, i3);
hand.set(4, i4);
hand.indexSort();
k = hand.key5();
if (!tmp[k]) continue;
// make sure we use the first joker for one-joker hands
if (i4 == 52) {
tmp[k] *= 2;
}
if (weights > 1) {
hand.showHand();
printf("wgt= %d %d\n", tmp[k], k);
}
if (weights < 2) {
printf("%2d, %2d, %2d, %2d, %2d, // %d\n", i0, i1, i2, i3, i4, i);
} else {
printf("%2d, // %d\n", tmp[k], i);
}
i++;
j += tmp[k];
}
}
}
}
}
if (weights < 2) {
printf("};\n");
} else {
printf("};\n\nconst int u_arraySize = %d;\n", i);
}
}
char unique[] = {
0, 1, 2, 3, 4, // 0
0, 1, 2, 3, 5, // 1
0, 1, 2, 3, 6, // 2
0, 1, 2, 3, 7, // 3
.........
12, 25, 38, 50, 52, // 152643
12, 25, 38, 51, 52, // 152644
12, 25, 38, 52, 53, // 152645
};
Where 0-51 index normal cards and 52 and 53 are the joker indices.
Alternately, the function prints the array of hand weights if weights==2:
char weight[] = {
4, // 0
4, // 1
.......
8, // 152643
2, // 152644
4 // 152645
};
If I am not evaluating a game with jokers, I just ignore an hand with a joker and I get the right number of unique hands and total number of hands if I add up the weights (what Kevin calls dups).