I took a course few months ago about using computer programming to make decision. I am learning the basic coding skill which help me to solve some questions in gaming. Last week, I download an android game about a simple 5 card poker game or jacks or better. The rule is very simple, it uses 52 cards, randomly draw 5 card to form an initial hand, the player is free to replace none or any number (up to 5) cards in the first hand to form a better one. My algorithm is pretty straight though not fast.
I am going to generate C(52, 5)=2598960 hands. For each hand, I try all case by not replacing the cards, replace 1 card, replace 2 cards, replace 3 cards, replace 4 cards and replace 5 cards. For each replacement, I iterate all cases by replacing the card(s) in each possible position. for example, by replacing 1 card in a given hand, I enumerate all possible hands:
1) by replacing the first card, that results 52-5=47 hands. Each hand are equally possible @ P=1/47, so the expected payout will be P times sum all pay for each hand, call it E1
2) by replacing the 2nd card, that results 47 hands. Each hand are equally possible @ P=1/47, so the expected payout will be P times sum all pay for each hand, call it E2
3) by replacing the 3rd card, another 47 hands created. Each hand are equally possible @ P=1/47, so the expected payout will be P times sum all pay for each hand, call it E3
4) by replacing the 4th card, another 47 hands created. Each hand are equally possible @ P=1/47, so the expected payout will be P times sum all pay for each hand, call it E4
5) by replacing the 5th cards, another 47 hands created.Each hand are equally possible @ P=1/47, so the expected payout will be P times sum all pay for each hand, call it E5
I am returning the maximum of {E1, E2, E3, E4, E5} as the best payout when replacing one card. however, to maximum the profit, I should also consider the case when replace 2 cards, 3 cards, 4 cards, 5 cards and NO replacement. Each case will return the corresponding maximum payout. I will pick the biggest one as the average payout for the given hand out of 2598960.
Similar analysis on each other hand in 2598960, I could find the payout. By adding all those payout and divide it by 2598960, I will get the average overall payout for the game. I don't know if this is a right process or not. But when I find this website, I saw the probability of jacks of better in https://wizardofodds.com/games/video-poker/tables/jacks-or-better/
I don't know how those numbers are given but the probabilities of each hand not same as mine. So I wonder what's wrong with my scheme above.
Also, in the game play, https://wizardofodds.com/play/video-poker/single-hand/play.html, I got one hand,
2SPADE 9SPADE 10SPADE 10CLUB QDIAMOND
By looking at the ANALYZE (strategy) table, take the first row as example, if we hold 10SPADE and 10CLUB, the EV in credits is going to be 0.823682, the resulting hit for each winning hand is
Jacks or Better 0
2Pair 2592
3OAK 1854
STRAIGHT 0
FLUSH 0
FULL HOUSE 165
4OAK 45
STRAIGHT FLUSH 0
ROYAL FLUSH 0
It is pretty different from what I get with a program. But my question is why there will be no hit for Jacks or Better? If we hold 10SPADE and 10CLUE, I think we have 3 cards drawn from the rest of 47 cards and the change to obtain two ACEs or two Jacks or two Queens or two Kings are pretty high. Should the hit be zero?
Quote: EaglesnestThe result, "Jacks or Better" in this context is actually shorthand for "One pair, Jacks or Better." It doesn't refer to ANY hand that is at least JJxxx or better. Therefore, drawing to 1010xxx, you will either miss altogether or make two pair, trips, a full house, or quads--none of which fall in the results column of "Jacks or Better."
Thanks for your info. I am still confusing on the result. Let consider the following situation
ORIGINAL hand: 2SPADE 9SPADE 10SPADE 10CLUB QDIAMOND
By holding 10SPADE 10CLUB and replacing the other 3 from the rest 47 cards in the deck, I am trying to count how many possible hand give 3 of a kind. The ranking is
Royal flush > straight flush > 4 of a kind > full house > flush > straight > 3 of a kind > 2 pair > jacks or better
The game in the link I posted before show that if we keep 10SPADE and 10CLUB but change the other 3 cards, the possible hits are
4 of a kind: 45
full house: 165
3 of a kind: 1854
I revised my program it give me the exact count for "4 of a kind" and "full house" but the "3 of a kind" are not consistent. My program gives 927 hits for 3 of a kind. I did a math as follow to figure out what's going on
After the initial hand, there are 47 cards left. To make 3 of a kind, the only possible way is to draw 1 more TEN and 2 more cards other than TEN. If we draw 2 more TEN, than it is a 4 of a kind, which has been counted already. If we draw all 3 cards of the same kind other then 10, which will be full house, also counted already. So the possible hands give 3 of a kind but no 4 of a kind and no full house must consist 3 TEN and 2 not-the-same-point cards. The count should be
=COMBIN(2,1)*COMBIN(45,2) - 165 = 1815
where 164 is the hit for full house. The first COMBIN(2,1) is one of the other two TEN (HEART and DIAMOND), COMBIN(45,2) is draw two more cards from the rest 45 cards (excluding 10HEART and 10DIAMOND).
But now I have 3 answers: 927, 1815 and 1854, which one is correct?
Then subtract the number of hands which are 4OAK or FH (which are mutally exclusive, so that's a good thing).
The remainder will correctly give you your 3OAK for 10's.
Multiply that by 13 so you include all 3OAK's, and that number will be correct for the game.
I'm only a beginning programmer, so that may not help, but it's logically correct.
=2*[990-3*3-9*6] = 2*[990-63] = 1854
Quote: konglify
After the initial hand, there are 47 cards left. To make 3 of a kind, the only possible way is to draw 1 more TEN and 2 more cards other than TEN. If we draw 2 more TEN, than it is a 4 of a kind, which has been counted already. If we draw all 3 cards of the same kind other then 10, which will be full house, also counted already. So the possible hands give 3 of a kind but no 4 of a kind and no full house must consist 3 TEN and 2 not-the-same-point cards. The count should be
=COMBIN(2,1)*COMBIN(45,2) - 165 = 1815
where 164 is the hit for full house. The first COMBIN(2,1) is one of the other two TEN (HEART and DIAMOND), COMBIN(45,2) is draw two more cards from the rest 45 cards (excluding 10HEART and 10DIAMOND).
This doesn't work because you are subtracting all full houses, including those with only two tens. You must not subtract those ones, because you specified in the calculation that you are drawing another 10. The full houses with two tens are 3*combin(3,3) + 9*combin(4,3) = 3+36 = 39. This is precisely how far off your answer is (1815+39 = 1854).
Quote: CrystalMathThis doesn't work because you are subtracting all full houses, including those with only two tens. You must not subtract those ones, because you specified in the calculation that you are drawing another 10. The full houses with two tens are 3*combin(3,3) + 9*combin(4,3) = 3+36 = 39. This is precisely how far off your answer is (1815+39 = 1854).
I see what you mean now. Thanks a lot
I revised my program so I got the same result as the page now. But I have a question on estimating the payback. In the game I refer to at the given link, it randomly generate an initial hand and show the expectation (pay in credit) by consider all possible replacements on that hand. So based on that information, does it mean the best strategy is to replace the card(s) which will give the highest expectation?
Now it comes to my question. How to estimate the payback for the game? My idea is something like the following
1) loop each possible initial hand (total 2598960 hands)
2) for each hand, search the hand by replacing some cards so it gives the maximum expectation, call it EV(i)
3) repeat 1) and 2) for all 2598960 hands, so there will be EV(1), EV(2) ... EV(2598960)
4) the payback should be
payback = sum[EV(1), EV(2) ... EV(2598960)]/2598960
Do you think this is the correct math to estimate the payback for the game? I try to implement this with a program, I got something over 300%, I don't think that's the correct value :(
Maybe share your code here? You have a bug somewhere, but there's no way for us to know without reading your code.
Quote: konglifyNow it comes to my question. How to estimate the payback for the game? My idea is something like the following
1) loop each possible initial hand (total 2598960 hands)
2) for each hand, search the hand by replacing some cards so it gives the maximum expectation, call it EV(i)
3) repeat 1) and 2) for all 2598960 hands, so there will be EV(1), EV(2) ... EV(2598960)
4) the payback should be
payback = sum[EV(1), EV(2) ... EV(2598960)]/2598960
Do you think this is the correct math to estimate the payback for the game? I try to implement this with a program, I got something over 300%, I don't think that's the correct value :(
That sounds right - slow, but right (I don't think there's an "easy" way other than doing it that way).
Make sure your payout amounts are correct - 1 for jacks or better, 2 for two pair, and so on.
Check as many possible hands as you can for accuracy - for example, is a straight flush being counted as a straight flush and a flush, or a straight flush and a straight, for some reason?
Quote: ThatDonGuyQuote: konglifyNow it comes to my question. How to estimate the payback for the game? My idea is something like the following
1) loop each possible initial hand (total 2598960 hands)
2) for each hand, search the hand by replacing some cards so it gives the maximum expectation, call it EV(i)
3) repeat 1) and 2) for all 2598960 hands, so there will be EV(1), EV(2) ... EV(2598960)
4) the payback should be
payback = sum[EV(1), EV(2) ... EV(2598960)]/2598960
Do you think this is the correct math to estimate the payback for the game? I try to implement this with a program, I got something over 300%, I don't think that's the correct value :(
That sounds right - slow, but right (I don't think there's an "easy" way other than doing it that way).
Make sure your payout amounts are correct - 1 for jacks or better, 2 for two pair, and so on.
Check as many possible hands as you can for accuracy - for example, is a straight flush being counted as a straight flush and a flush, or a straight flush and a straight, for some reason?
You just point out one mistake I made. Thanks a lot. I am revising the code and it still didn't get the correct result. I will post the code later. Thanks all.
Quote: ThatDonGuyQuote: konglifyNow it comes to my question. How to estimate the payback for the game? My idea is something like the following
1) loop each possible initial hand (total 2598960 hands)
2) for each hand, search the hand by replacing some cards so it gives the maximum expectation, call it EV(i)
3) repeat 1) and 2) for all 2598960 hands, so there will be EV(1), EV(2) ... EV(2598960)
4) the payback should be
payback = sum[EV(1), EV(2) ... EV(2598960)]/2598960
Do you think this is the correct math to estimate the payback for the game? I try to implement this with a program, I got something over 300%, I don't think that's the correct value :(
That sounds right - slow, but right (I don't think there's an "easy" way other than doing it that way).
Make sure your payout amounts are correct - 1 for jacks or better, 2 for two pair, and so on.
Check as many possible hands as you can for accuracy - for example, is a straight flush being counted as a straight flush and a flush, or a straight flush and a straight, for some reason?
I think the algorithm is just go so slow. I estimate it will take about 200 hours to finish the calculation. I am just thinking some short cut to save some calculation. For example, if the initial hand to be
2Diamond 3Diamon 4Club 5Heart 8Spade
by considering all situations after the replacement, I will get expectation value (EV) of 0.680851.
For another initial hand
2Club 3Club 4Diamond 5Spade 8Heart
I got the exact same EV because the suits here will not affect the result. So if we could find a way to rank each hand such that above two hands give the same ranking, we could save the result of the hand of the same ranking to a hash table so to avoid duplicate calculations on any hand thereafter of the same ranking. But so far I didn't find a good and correct way to rank the hand for that purpose. Any idea?
Quote: konglifyI think the algorithm is just go so slow. I estimate it will take about 200 hours to finish the calculation. I am just thinking some short cut to save some calculation. For example, if the initial hand to be
2Diamond 3Diamon 4Club 5Heart 8Spade
by considering all situations after the replacement, I will get expectation value (EV) of 0.680851.
For another initial hand
2Club 3Club 4Diamond 5Spade 8Heart
I got the exact same EV because the suits here will not affect the result. So if we could find a way to rank each hand such that above two hands give the same ranking, we could save the result of the hand of the same ranking to a hash table so to avoid duplicate calculations on any hand thereafter of the same ranking. But so far I didn't find a good and correct way to rank the hand for that purpose. Any idea?
For 5-card hands, you just need to keep track of whether all 5 cards are the same suit or not. So for any list of 5 ranks that are all different, you need two entries (one suited and one not suited). If the 5 ranks have some duplicates, then you only need 1 entry (since it's not possible to be suited)
Quote: konglifyI think the algorithm is just go so slow. I estimate it will take about 200 hours to finish the calculation. I am just thinking some short cut to save some calculation. For example, if the initial hand to be
2Diamond 3Diamon 4Club 5Heart 8Spade
by considering all situations after the replacement, I will get expectation value (EV) of 0.680851.
For another initial hand
2Club 3Club 4Diamond 5Spade 8Heart
I got the exact same EV because the suits here will not affect the result. So if we could find a way to rank each hand such that above two hands give the same ranking, we could save the result of the hand of the same ranking to a hash table so to avoid duplicate calculations on any hand thereafter of the same ranking. But so far I didn't find a good and correct way to rank the hand for that purpose. Any idea?
There are 134,459 "unique" hands. The problem is, you have to figure out what they are in advance (as well as how many times each appears in the 2,598,960 total hands), and then hard-code them into your code. Since you say you are still learning how to code, I wouldn't recommend this right now.
However, here is a short version of the list (it only includes one set of ranks for each hand - for example, the only four-of-a-kind is four aces and the 2 of spades)
4-1 156 4 As Ah Ac Ad Ks
3-2 156 12 Both 2 in 3 As Ah Ac Ks Kh
156 12 One 2 in 3 As Ah Ac Ks Kd
3-1-1 858 12 1s match, in 3 As Ah Ac Ks Qs
858 4 1s match, not in 3 As Ah Ac Kd Qd
858 24 1s different, both in 3 As Ah Ac Ks Qh
858 12 1s different, lower in 3 As Ah Ac Kd Qs
858 12 1s different, higher in 3 As Ah Ac Ks Qd
2-2-1 858 12 2s match both, 1 in 2s As Ah Ks Kh Qs
858 12 2s match both, 1 not in 2s As Ah Ks Kh Qc
858 24 2s match 1, 1 matches both As Ah Ks Kd Qs
858 24 2s match 1, 1 matches lower As Ah Ks Kd Qd
858 24 2s match 1, 1 matches higher As Ah Ks Kd Qh
858 24 2s match 1, 1 matches neither As Ah Ks Kd Qc
858 12 2s different, 1 matches lower As Ah Kc Kd Qs
858 12 2s different, 1 matches higher As Ah Kc Kd Qc
2-1-1-1 2860 12 1s match, in 2 As Ah Ks Qs Js
2860 12 1s matchm not in 2 As Ah Kc Qc Jc
2860 12 1s AAB, both in 2 As Ah Ks Qs Jh
2860 12 1s ABA, both in 2 As Ah Ks Qh Js
2860 12 1s BAA, both in 2 As Ah Kh Qs Js
2860 24 1s AAB, A in 2 As Ah Ks Qs Jc
2860 24 1s ABA, A in 2 As Ah Ks Qc Js
2860 24 1s BAA, A in 2 As Ah Kc Qs Js
2860 24 1s AAB, B in 2 As Ah Kc Qc Js
2860 24 1s ABA, B in 2 As Ah Kc Qs Jc
2860 24 1s BAA, B in 2 As Ah Ks Qc Jc
2860 12 1s AAB, neither in 2 As Ah Kc Qc Jd
2860 12 1s ABA, neither in 2 As Ah Kc Qd Jc
2860 12 1s BAA, neither in 2 As Ah Kd Qc Jc
2860 24 1s ABC, AB in 2 As Ah Ks Qh Jc
2860 24 1s ABC, AC in 2 As Ah Ks Qc Jh
2860 24 1s ABC, BC in 2 As Ah Kc Qs Jh
2860 24 1s ABC, A in 2 As Ah Ks Qc Jd
2860 24 1s ABC, B in 2 As Ah Kc Qs Jd
2860 24 1s ABC, C in 2 As Ah Kc Qd Js
1-1-1-1-1 1287 4 Flush As Ks Qs Js 10s
1287 12 4-1 ABCD As Ks Qs Js 10h
1287 12 4-1 ABCE As Ks Qs Jh 10s
1287 12 4-1 ABDE As Ks Qh Js 10s
1287 12 4-1 ACDE As Kh Qs Js 10s
1287 12 4-1 BCDE Ah Ks Qs Js 10s
1287 12 3-2 ABC As Ks Qs Jh 10h
1287 12 3-2 ABD As Ks Qh Js 10h
1287 12 3-2 ABE As Ks Qh Jh 10s
1287 12 3-2 ACD As Kh Qs Js 10h
1287 12 3-2 ACE As Kh Qs Jh 10s
1287 12 3-2 ADE As Kh Qh Js 10s
1287 12 3-2 BCD Ah Ks Qs Js 10h
1287 12 3-2 BCE Ah Ks Qs Jh 10s
1287 12 3-2 BDE Ah Ks Qh Js 10s
1287 12 3-2 CDE Ah Kh Qs Js 10s
1287 24 3-1-1 ABC As Ks Qs Jh 10c
1287 24 3-1-1 ABD As Ks Qh Js 10c
1287 24 3-1-1 ABE As Ks Qh Jc 10s
1287 24 3-1-1 ACD As Kh Qs Js 10c
1287 24 3-1-1 ACE As Kh Qs Jc 10s
1287 24 3-1-1 ADE As Kh Qc Js 10s
1287 24 3-1-1 BCD Ah Ks Qs Js 10c
1287 24 3-1-1 BCE Ah Ks Qs Jc 10s
1287 24 3-1-1 BDE Ah Ks Qc Js 10s
1287 24 3-1-1 CDE Ah Kc Qs Js 10s
1287 24 2-2-1 AB/CD As Ks Qh Jh 10c
1287 24 2-2-1 AB/CE As Ks Qh Jc 10h
1287 24 2-2-1 AB/DE As Ks Qc Jh 10h
1287 24 2-2-1 AC/DE As Kc Qs Jh 10h
1287 24 2-2-1 BC/DE Ac Ks Qs Jh 10h
1287 24 2-2-1 AC/BD As Kh Qs Jh 10c
1287 24 2-2-1 AC/BE As Kh Qs Jc 10h
1287 24 2-2-1 AD/BE As Kh Qc Js 10h
1287 24 2-2-1 AD/CE As Kc Qh Js 10h
1287 24 2-2-1 BD/CE Ac Ks Qh Js 10h
1287 24 2-2-1 AD/BC As Kh Qh Js 10c
1287 24 2-2-1 AE/BC As Kh Qh Jc 10s
1287 24 2-2-1 AE/CD As Kh Qc Jh 10s
1287 24 2-2-1 AE/CD As Kc Qh Jh 10s
1287 24 2-2-1 BE/CD Ac Ks Qh Jh 10s
1287 24 2-1-1-1 AB As Ks Qh Jc 10d
1287 24 2-1-1-1 AC As Kh Qc Js 10d
1287 24 2-1-1-1 AD As Kh Qc Js 10d
1287 24 2-1-1-1 AE As Kh Qc Jd 10s
1287 24 2-1-1-1 BC Ah Ks Qs Jc 10d
1287 24 2-1-1-1 BD Ah Ks Qc Js 10d
1287 24 2-1-1-1 BE Ah Ks Qc Jd 10s
1287 24 2-1-1-1 CD Ah Kc Qs Js 10d
1287 24 2-1-1-1 CE Ah Kc Qs Jd 10s
1287 24 2-1-1-1 DE Ah Kc Qd Js 10s
The columns are, from left to right:
The rank breakdown (for example, 2-2-1 means a pair, another pair, and 1 of a third rank; 3-1-1 means a 3 of a kind and two singles)
The number of "unique" hands
The number of actual hands for each unique hand
A description of the suit breakdown - "in 3" means a suit matches a card in the 3 of a kind (for example, "3-1-1, 1s different, both in 3 - As Ah Ac Ks Qh" means a hand with a 3 of a kind and 2 singles where the singles have different suits (one is a spade, the other is a heart) and both suits are in the 3 of a kind; in the hands with five different values, A,B,C,D,E refer to the five cards in order
A sample hand
Quote: ThatDonGuyThere are 134,459 "unique" hands. The problem is, you have to figure out what they are in advance (as well as how many times each appears in the 2,598,960 total hands), and then hard-code them into your code. Since you say you are still learning how to code, I wouldn't recommend this right now.
However, here is a short version of the list (it only includes one set of ranks for each hand - for example, the only four-of-a-kind is four aces and the 2 of spades)
4-1 156 4 As Ah Ac Ad Ks
3-2 156 12 Both 2 in 3 As Ah Ac Ks Kh
156 12 One 2 in 3 As Ah Ac Ks Kd
3-1-1 858 12 1s match, in 3 As Ah Ac Ks Qs
858 4 1s match, not in 3 As Ah Ac Kd Qd
858 24 1s different, both in 3 As Ah Ac Ks Qh
858 12 1s different, lower in 3 As Ah Ac Kd Qs
858 12 1s different, higher in 3 As Ah Ac Ks Qd
2-2-1 858 12 2s match both, 1 in 2s As Ah Ks Kh Qs
858 12 2s match both, 1 not in 2s As Ah Ks Kh Qc
858 24 2s match 1, 1 matches both As Ah Ks Kd Qs
858 24 2s match 1, 1 matches lower As Ah Ks Kd Qd
858 24 2s match 1, 1 matches higher As Ah Ks Kd Qh
858 24 2s match 1, 1 matches neither As Ah Ks Kd Qc
858 12 2s different, 1 matches lower As Ah Kc Kd Qs
858 12 2s different, 1 matches higher As Ah Kc Kd Qc
2-1-1-1 2860 12 1s match, in 2 As Ah Ks Qs Js
2860 12 1s matchm not in 2 As Ah Kc Qc Jc
2860 12 1s AAB, both in 2 As Ah Ks Qs Jh
2860 12 1s ABA, both in 2 As Ah Ks Qh Js
2860 12 1s BAA, both in 2 As Ah Kh Qs Js
2860 24 1s AAB, A in 2 As Ah Ks Qs Jc
2860 24 1s ABA, A in 2 As Ah Ks Qc Js
2860 24 1s BAA, A in 2 As Ah Kc Qs Js
2860 24 1s AAB, B in 2 As Ah Kc Qc Js
2860 24 1s ABA, B in 2 As Ah Kc Qs Jc
2860 24 1s BAA, B in 2 As Ah Ks Qc Jc
2860 12 1s AAB, neither in 2 As Ah Kc Qc Jd
2860 12 1s ABA, neither in 2 As Ah Kc Qd Jc
2860 12 1s BAA, neither in 2 As Ah Kd Qc Jc
2860 24 1s ABC, AB in 2 As Ah Ks Qh Jc
2860 24 1s ABC, AC in 2 As Ah Ks Qc Jh
2860 24 1s ABC, BC in 2 As Ah Kc Qs Jh
2860 24 1s ABC, A in 2 As Ah Ks Qc Jd
2860 24 1s ABC, B in 2 As Ah Kc Qs Jd
2860 24 1s ABC, C in 2 As Ah Kc Qd Js
1-1-1-1-1 1287 4 Flush As Ks Qs Js 10s
1287 12 4-1 ABCD As Ks Qs Js 10h
1287 12 4-1 ABCE As Ks Qs Jh 10s
1287 12 4-1 ABDE As Ks Qh Js 10s
1287 12 4-1 ACDE As Kh Qs Js 10s
1287 12 4-1 BCDE Ah Ks Qs Js 10s
1287 12 3-2 ABC As Ks Qs Jh 10h
1287 12 3-2 ABD As Ks Qh Js 10h
1287 12 3-2 ABE As Ks Qh Jh 10s
1287 12 3-2 ACD As Kh Qs Js 10h
1287 12 3-2 ACE As Kh Qs Jh 10s
1287 12 3-2 ADE As Kh Qh Js 10s
1287 12 3-2 BCD Ah Ks Qs Js 10h
1287 12 3-2 BCE Ah Ks Qs Jh 10s
1287 12 3-2 BDE Ah Ks Qh Js 10s
1287 12 3-2 CDE Ah Kh Qs Js 10s
1287 24 3-1-1 ABC As Ks Qs Jh 10c
1287 24 3-1-1 ABD As Ks Qh Js 10c
1287 24 3-1-1 ABE As Ks Qh Jc 10s
1287 24 3-1-1 ACD As Kh Qs Js 10c
1287 24 3-1-1 ACE As Kh Qs Jc 10s
1287 24 3-1-1 ADE As Kh Qc Js 10s
1287 24 3-1-1 BCD Ah Ks Qs Js 10c
1287 24 3-1-1 BCE Ah Ks Qs Jc 10s
1287 24 3-1-1 BDE Ah Ks Qc Js 10s
1287 24 3-1-1 CDE Ah Kc Qs Js 10s
1287 24 2-2-1 AB/CD As Ks Qh Jh 10c
1287 24 2-2-1 AB/CE As Ks Qh Jc 10h
1287 24 2-2-1 AB/DE As Ks Qc Jh 10h
1287 24 2-2-1 AC/DE As Kc Qs Jh 10h
1287 24 2-2-1 BC/DE Ac Ks Qs Jh 10h
1287 24 2-2-1 AC/BD As Kh Qs Jh 10c
1287 24 2-2-1 AC/BE As Kh Qs Jc 10h
1287 24 2-2-1 AD/BE As Kh Qc Js 10h
1287 24 2-2-1 AD/CE As Kc Qh Js 10h
1287 24 2-2-1 BD/CE Ac Ks Qh Js 10h
1287 24 2-2-1 AD/BC As Kh Qh Js 10c
1287 24 2-2-1 AE/BC As Kh Qh Jc 10s
1287 24 2-2-1 AE/CD As Kh Qc Jh 10s
1287 24 2-2-1 AE/CD As Kc Qh Jh 10s
1287 24 2-2-1 BE/CD Ac Ks Qh Jh 10s
1287 24 2-1-1-1 AB As Ks Qh Jc 10d
1287 24 2-1-1-1 AC As Kh Qc Js 10d
1287 24 2-1-1-1 AD As Kh Qc Js 10d
1287 24 2-1-1-1 AE As Kh Qc Jd 10s
1287 24 2-1-1-1 BC Ah Ks Qs Jc 10d
1287 24 2-1-1-1 BD Ah Ks Qc Js 10d
1287 24 2-1-1-1 BE Ah Ks Qc Jd 10s
1287 24 2-1-1-1 CD Ah Kc Qs Js 10d
1287 24 2-1-1-1 CE Ah Kc Qs Jd 10s
1287 24 2-1-1-1 DE Ah Kc Qd Js 10s
The columns are, from left to right:
The rank breakdown (for example, 2-2-1 means a pair, another pair, and 1 of a third rank; 3-1-1 means a 3 of a kind and two singles)
The number of "unique" hands
The number of actual hands for each unique hand
A description of the suit breakdown - "in 3" means a suit matches a card in the 3 of a kind (for example, "3-1-1, 1s different, both in 3 - As Ah Ac Ks Qh" means a hand with a 3 of a kind and 2 singles where the singles have different suits (one is a spade, the other is a heart) and both suits are in the 3 of a kind; in the hands with five different values, A,B,C,D,E refer to the five cards in order
A sample hand
I appreciate the information. I think it is good for me as start the analysis.
There are a number of good choices here:
https://github.com/christophschmalhofer/poker/tree/master/XPokerEval
Quote: socksWhat does your hand evaluation look like? As in, turning a given hand into a value? That might be a target for improvement.
There are a number of good choices here:
https://github.com/christophschmalhofer/poker/tree/master/XPokerEval
Thanks a lot for the info. I don't use a very advanced programming skill since I am just starting in coding. I have each card labeled as 1, 2, 3, 4, ..., 52. "1", "14", "27" and "40" represents A(Spade), A(Heart), A(Club) and A(Diamond). "13", "26", "39" and "52" represents K(Spade), K(Heart), K(Club) and K(Diamond)
I sort each hand as an array of 5 numbers ranged 1 to 52. And I sort each hand by the mod(value, 13)+1, so all aces will get together first but all kings will get together but appear towards the rear position if available.
I will look at the code in the link you gave. Hopefully I will get some idea but it might take me some times since I don't know that language before :)
Quote: konglifyThanks a lot for the info. I don't use a very advanced programming skill since I am just starting in coding. I have each card labeled as 1, 2, 3, 4, ..., 52. "1", "14", "27" and "40" represents A(Spade), A(Heart), A(Club) and A(Diamond). "13", "26", "39" and "52" represents K(Spade), K(Heart), K(Club) and K(Diamond) ...
This site explains a more advanced representation that lends itself to fast evaluation, http://www.suffecool.net/poker/evaluator.html
I think the method is probably well suited for what your trying to do. It's a fast 5 card method that gives you back a hand value from 1 to 7462 (there are exactly 7462 unique hand values for 5 card hands). Form there, if you just need the hand type, like for video poker, you can check the value against the range you want.
Quote: socksThis site explains a more advanced representation that lends itself to fast evaluation, http://www.suffecool.net/poker/evaluator.html
I think the method is probably well suited for what your trying to do. It's a fast 5 card method that gives you back a hand value from 1 to 7462 (there are exactly 7462 unique hand values for 5 card hands). Form there, if you just need the hand type, like for video poker, you can check the value against the range you want.
That's cool. Thanks a lot for the resource. I read the description of the algorithm carefully, it is quite easy to understand the idea behind. But I think the source code was no longer available for download. I am trying to implement the code myself.Thanks again.
Quote: konglifyThat's cool. Thanks a lot for the resource. I read the description of the algorithm carefully, it is quite easy to understand the idea behind. But I think the source code was no longer available for download. I am trying to implement the code myself.Thanks again.
It's part of the XPokerEval github repo. Just use the link in my original post and look for XPokerEval.CactusKev. The link in your post where you quoted contains an html blockquote tag.
I spent some times to read the materials provided by some of you and finally decide to use Cactus Kev's poker evaluator to calculate the payback for the game. However, I finally get the payback about 1.58 which is definitely wrong for the given payoff table as follows
royal flush 800
straight flush 50
four of a kind 25
full house 9
flush 6
straight 4
three of a kind 3
two pair 2
jacks or better 1
My code is designed in the following ways:
1) I use Kev's evaluator to generate total 7462 unique hands
2) For each hand out of 7462, I pass it into an analysis function and try to build all possible resulting hands with
a) don't replace any card, which will give one payoff based on the pay table
b) replace 1 card, at any 1 to 5 position, with 1 card in the rest 47 cards in the deck. For one position in the hand being pick, there are 47 possible hand comes out, so find the expected payback for that. So total 5 expected payback will be there. Pick the largest one.
c) Similar to b), we could replace 2 cards, 3 cards, 4 cards and 5 cards at a time and find the largest payback
3) So after we consider: replace no card, 1 cards, 2 cards, 3 cards, 4 cards and 5 cards. We find the largest payback as the expected one for the given hand.
4) Repeat 2) - 3) for each of the hand in the unique pool.
5) Adding all result payback will get the overall payback for the game.
I got 1.58 instead. Something wrong but I cannot tell what it is. I have uploaded to code to http://www.freefilehosting.net/pokeranalysis . I will appreciate it if someone could point out the mistakes I made in the code.
NOTE: in Kev's evaluator, he didn't separate jacks or better from two pair, also he didn't separate royal flush from straight flush. I modified his code to accommodate that
here is the modified hand_rank
int hand_rank( short val )
{
if (val > 6185) return(HIGH_CARD); // 1277 high card
if (val > 4205) return(ONE_PAIR); // 2860 one pair (including jacks or better)
if (val > 3325) return(JACKS_BETTER); //
if (val > 2467) return(TWO_PAIR); // 858 two pair
if (val > 1609) return(THREE_OF_A_KIND); // 858 three-kind
if (val > 1599) return(STRAIGHT); // 10 straights
if (val > 322) return(FLUSH); // 1277 flushes
if (val > 166) return(FULL_HOUSE); // 156 full house
if (val > 10) return(FOUR_OF_A_KIND); // 156 four-kind
if (val > 1) return(STRAIGHT_FLUSH); // 10 straight-flushes
return(ROYAL_FLUSH); // royal straight flush
}
with
#define ROYAL_FLUSH 0
#define STRAIGHT_FLUSH 1
#define FOUR_OF_A_KIND 2
#define FULL_HOUSE 3
#define FLUSH 4
#define STRAIGHT 5
#define THREE_OF_A_KIND 6
#define TWO_PAIR 7
#define JACKS_BETTER 8
#define ONE_PAIR 9
#define HIGH_CARD 10
A♥ K♣ Q♣ J♣ 10♣
or
A♥ K♦ Q♣ J♠ 10♠
or several other suit permutations, but these are very different hands when it comes to calculating the EV of the best play for a video poker game.
Analyzing the 134,459 unique hands and weighting their results is probably the best approach.
Quote: JBUsing the 7462 poker hands is no good for video poker. For example, the rank for an Ace-high straight could refer to:
A♥ K♣ Q♣ J♣ 10♣
or
A♥ K♦ Q♣ J♠ 10♠
or several other suit permutations, but these are very different hands when it comes to calculating the EV of the best play for a video poker game.
Analyzing the 134,459 unique hands and weighting their results is probably the best approach.
A 7462-hand table is great for looking up the final result though. No need to even pre-calculate it -- the lookup table can be populated in under a second when your program initializes.
It's also useful for analyzing poker-based table games. I wrote one that I use all the time.
Quote: JBUsing the 7462 poker hands is no good for video poker. For example, the rank for an Ace-high straight could refer to:
A♥ K♣ Q♣ J♣ 10♣
or
A♥ K♦ Q♣ J♠ 10♠
or several other suit permutations, but these are very different hands when it comes to calculating the EV of the best play for a video poker game.
Analyzing the 134,459 unique hands and weighting their results is probably the best approach.
Thanks for the info. But I still don't understand how to enumerate all those 134459 hands.
you and me (both)Quote: konglifyThanks for the info. But I still don't understand how to enumerate all those 134459 hands.
I says we could start here in our studies (no pressure)
https://wizardofodds.com/games/video-poker/methodology/
Sally
The following classes of rank shapes exist when making 5-card hands from a standard 52-card deck:
a) four of a kind + one kicker
b) three of a kind + one pair
c) three of a kind + two kickers
d) two pair + one kicker
e) one pair + three kickers
f) five singletons
For each of those rank shapes, determine the suit shapes that are possible. Don't think in absolute suits (clubs, diamonds, hearts, spades) but instead think in relative suits (suit A, suit B, suit C, suit D) where suit A can be any of the four absolute suits, then once suit A has been assigned, suit B can be any of the remaining three suits, and so on. Start with the largest rank quantity first and work your way down.
For the first class of rank shapes (four of a kind + one kicker), first you have four of a kind, so you know they must occupy all four suits. The kicker must necessarily match one of the suits used in the four of a kind, but it does not matter which suit it claims, so we say it claims suit A with a weight of 4 because suit A could refer to any of the combin(4,1) = 4 suits appearing in the four of a kind.
For the second class of rank shapes (three of a kind + one pair), we know the three of a kind claims three suits, which we'll call ABC and start with a weight of combin(4,3) = 4. For the pair, we have the following two choices:
ABC+AB (both suits match two of the suits used by the three of a kind)
ABC+AD (one suit is used in the three of a kind and the other suit is the final suit)
For ABC+AB, we already know the ABC has a weight of 4, and then the AB uses 2 of those 3 suits = combin(3,2) = 3, so the weight for this suit shape is 4*3 = 12.
For ABC+AD, again ABC = 4, and suit A in the pair can refer to any of the three of a kind's suits, so combin(3,1) = 3, and the D can only refer to the final suit, so the weight for this suit shape is also 4*3 = 12.
For the third class of rank shapes (three of a kind + two kickers), the following suit shapes are possible:
ABC+A+A (both kickers are suited, and that suit appears among the three of a kind's suits)
ABC+A+B (both kickers are unsuited with each other, but both kicker suits appear among the three of a kind's suits)
ABC+A+D (the first kicker is suited with one of the three of a kind, the second kicker uses the final suit)
ABC+D+A (the first kicker uses the final suit, the second kicker matches one of the three of a kind's suits)
ABC+D+D (both kickers are suited with each other, and both use the only suit not used by the three of a kind)
The following suit shapes are duplicates of one of the above suit shapes. The reason why is because we can't assign suit B until suit A has been assigned, and we can't assign suit C until suit B has been assigned. Suit D is already assigned because it is the only suit not appearing among the three of a kind:
ABC+A+C is the same as ABC+A+B
ABC+B+A is the same as ABC+A+B
ABC+B+B is the same as ABC+A+A
ABC+B+C is the same as ABC+A+B
ABC+B+D is the same as ABC+A+D
ABC+C+A is the same as ABC+A+B
ABC+C+B is the same as ABC+A+B
ABC+C+C is the same as ABC+A+A
ABC+C+D is the same as ABC+A+D
ABC+D+B is the same as ABC+D+A
ABC+D+C is the same as ABC+D+A
---
Just apply the same logic for the other classes. Then iterate through each rank shape, and for each rank shape, iterate through each of that class's possible suit shapes, to determine the unique hand shape. When all is said and done you should have the following results:
four of a kind + one kicker: combin(13,1) * combin(12,1) = 156 rank shapes * 1 suit shape = 156 unique hand shapes
three of a kind + one pair: combin(13,1) * combin(12,1) = 156 rank shapes * 2 suit shapes = 312 unique hand shapes
three of a kind + two kickers: combin(13,1) * combin(12,2) = 858 rank shapes * 5 suit shapes = 4290 unique hand shapes
two pair + one kicker: combin(13,2) * combin(11,1) = 858 rank shapes * 8 suit shapes = 6864 unique hand shapes
one pair + three kickers: combin(13,1) * combin(12,3) = 2860 rank shapes * 20 suit shapes = 57200 unique hand shapes
five singletons = combin(13,5) = 1287 rank shapes * 51 suit shapes = 65637 unique hand shapes
and 156 + 312 + 4290 + 6864 + 57200 + 65637 = 134,459 unique hand shapes
Quote: mustangsallyyou and me (both)
I says we could start here in our studies (no pressure)
https://wizardofodds.com/games/video-poker/methodology/
Even if you do enumerate the 134,459 hands, that's only half the problem - you now have to map the 2,598,960 actual hands to the 134,459 unique ones.
What I ended up doing for my Android Video Poker Analyzer app (and as soon as I figure out a way to fit all 52 card buttons onto a phone's screen at once without you needing a toothpick to select them, I'll consider making it public) was, I wrote a separate program in C# that divided the hands into groups (4-1, 3-2, 3-3-1, 2-2-1, 2-1-1-1, 1-1-1-1-1), then in each group, it would go through each unique hand in that group (e.g. for 3-2, there is a group where both suits in the pair are also in the three - e.g. As Ah Ac Ks Kh - and a group where one suit is in the three but the other is not - e.g. As Ah Ac Ks Kd), assign it a unique number from 0 to 134458, and then assign all of the "actual" hands that match that unique hand the same number (so the number assigned to As Ah Ac Ks Kh would also be assigned to As Ah Ac Ks Kc and As Ah Ac Kh Kc).
This is not something that I would recommend somebody just starting out with coding do; it's along the lines of, "Okay, I have learned long division; now, what's the Law of Cosines?"
Sally, if you're seriously interested in how to form the 134,459 hands, go to this post and click on the "Click here" button; that brings up a list of how to generate the 134,459 hands. Let me know if it needs some explanation.
Quote: ThatDonGuyEven if you do enumerate the 134,459 hands, that's only half the problem - you now have to map the 2,598,960 actual hands to the 134,459 unique ones.
I disagree. To compute the return of a game, all that is needed is to iterate through the 134,459 unique hands, determine which hands are possible for each of the 32 ways to play the hand, select the best play, and weigh the results according to the weight factor for the unique hand shape.
Quote: JBI disagree. To compute the return of a game, all that is needed is to iterate through the 134,459 unique hands, determine which hands are possible for each of the 32 ways to play the hand, select the best play, and weigh the results according to the weight factor for the unique hand shape.
Well, if that's all you are trying to do, then yes, that's all you need to do.
Of course, to determine the best way to play the hand, you have to:
(a) average the 1,533,939 ways to draw 5 cards
(b) for each of the 5 ways to keep 1 card, average the 178,365 ways to draw 4
(c) for each of the 10 ways to keep 2 cards, average the 16,215 ways to draw 3
(d) for each of the 10 ways to keep 3 card, average the 1081 ways to draw 2
(e) for each of the 5 ways to keep 4 cards, average the 47 ways to draw 1
(f) plus, of course, compare these against the hand value if you keep all 5 cards
Quote: ThatDonGuyEven if you do enumerate the 134,459 hands, that's only half the problem - you now have to map the 2,598,960 actual hands to the 134,459 unique ones.
What I ended up doing for my Android Video Poker Analyzer app (and as soon as I figure out a way to fit all 52 card buttons onto a phone's screen at once without you needing a toothpick to select them, I'll consider making it public) was, I wrote a separate program in C# that divided the hands into groups (4-1, 3-2, 3-3-1, 2-2-1, 2-1-1-1, 1-1-1-1-1), then in each group, it would go through each unique hand in that group (e.g. for 3-2, there is a group where both suits in the pair are also in the three - e.g. As Ah Ac Ks Kh - and a group where one suit is in the three but the other is not - e.g. As Ah Ac Ks Kd), assign it a unique number from 0 to 134458, and then assign all of the "actual" hands that match that unique hand the same number (so the number assigned to As Ah Ac Ks Kh would also be assigned to As Ah Ac Ks Kc and As Ah Ac Kh Kc).
This is not something that I would recommend somebody just starting out with coding do; it's along the lines of, "Okay, I have learned long division; now, what's the Law of Cosines?"
Sally, if you're seriously interested in how to form the 134,459 hands, go to this post and click on the "Click here" button; that brings up a list of how to generate the 134,459 hands. Let me know if it needs some explanation.
Don,
If you made 3 circles across in the top 2/3 of the long way, you could display 2-3-4-5-6, 7-8-9-10, J-Q-K-A as pie wedges in the 3 circles. Touch one and it displays as a card of that rank with four suit quadrants. Touch the suit and the card drops to the bottom third. Should work for fingertip 2 tap control - you could easily enter a hand in 2 seconds. Then you have the top 2/3 available for analysis with the hand displayed below that. Touch any chosen card and it deletes; one swipe across and the displayed hand's cleared, ready for the next hand.
Not that I know anything about writing an app - I just saw it in my head when I saw what you wrote.
Quote: ThatDonGuyEven if you do enumerate the 134,459 hands, that's only half the problem - you now have to map the 2,598,960 actual hands to the 134,459 unique ones.
What I ended up doing for my Android Video Poker Analyzer app (and as soon as I figure out a way to fit all 52 card buttons onto a phone's screen at once without you needing a toothpick to select them, I'll consider making it public) was, I wrote a separate program in C# that divided the hands into groups (4-1, 3-2, 3-3-1, 2-2-1, 2-1-1-1, 1-1-1-1-1), then in each group, it would go through each unique hand in that group (e.g. for 3-2, there is a group where both suits in the pair are also in the three - e.g. As Ah Ac Ks Kh - and a group where one suit is in the three but the other is not - e.g. As Ah Ac Ks Kd), assign it a unique number from 0 to 134458, and then assign all of the "actual" hands that match that unique hand the same number (so the number assigned to As Ah Ac Ks Kh would also be assigned to As Ah Ac Ks Kc and As Ah Ac Kh Kc).
This is not something that I would recommend somebody just starting out with coding do; it's along the lines of, "Okay, I have learned long division; now, what's the Law of Cosines?"
Sally, if you're seriously interested in how to form the 134,459 hands, go to this post and click on the "Click here" button; that brings up a list of how to generate the 134,459 hands. Let me know if it needs some explanation.
Thanks again. I read that before but I am not sure I fully understand how to generate all of them. For the first 4-1, I think it is rather easy,
keep Ks unchanged, simply replace As with 2s, 3s, ... Qs; Ah with 2h, 3h, ..., Kh; Ac with 2c, 3c, ..., Kc; Ad with 2d, 3d, ..., Kd
So do the same thing while replacing Ks with As, 2s, 3s ... Qs for 4OAK of King? So there are 13 4OAK and 12 possible 1 card, is that why it has 13x12=156 combination? So my question is why we don't count the suit for the very last one? or more generally, in the list you shown in the link, how do I figure out when do I need or not to enumerate the suit while producing all 134459 hands?
Quote: JBFirst you have to look at the possible rank shapes, then for each rank shape, determine the possible suit shapes.
The following classes of rank shapes exist when making 5-card hands from a standard 52-card deck:
a) four of a kind + one kicker
b) three of a kind + one pair
c) three of a kind + two kickers
d) two pair + one kicker
e) one pair + three kickers
f) five singletons
For each of those rank shapes, determine the suit shapes that are possible. Don't think in absolute suits (clubs, diamonds, hearts, spades) but instead think in relative suits (suit A, suit B, suit C, suit D) where suit A can be any of the four absolute suits, then once suit A has been assigned, suit B can be any of the remaining three suits, and so on. Start with the largest rank quantity first and work your way down.
For the first class of rank shapes (four of a kind + one kicker), first you have four of a kind, so you know they must occupy all four suits. The kicker must necessarily match one of the suits used in the four of a kind, but it does not matter which suit it claims, so we say it claims suit A with a weight of 4 because suit A could refer to any of the combin(4,1) = 4 suits appearing in the four of a kind.
For the second class of rank shapes (three of a kind + one pair), we know the three of a kind claims three suits, which we'll call ABC and start with a weight of combin(4,3) = 4. For the pair, we have the following two choices:
ABC+AB (both suits match two of the suits used by the three of a kind)
ABC+AD (one suit is used in the three of a kind and the other suit is the final suit)
For ABC+AB, we already know the ABC has a weight of 4, and then the AB uses 2 of those 3 suits = combin(3,2) = 3, so the weight for this suit shape is 4*3 = 12.
For ABC+AD, again ABC = 4, and suit A in the pair can refer to any of the three of a kind's suits, so combin(3,1) = 3, and the D can only refer to the final suit, so the weight for this suit shape is also 4*3 = 12.
For the third class of rank shapes (three of a kind + two kickers), the following suit shapes are possible:
ABC+A+A (both kickers are suited, and that suit appears among the three of a kind's suits)
ABC+A+B (both kickers are unsuited with each other, but both kicker suits appear among the three of a kind's suits)
ABC+A+D (the first kicker is suited with one of the three of a kind, the second kicker uses the final suit)
ABC+D+A (the first kicker uses the final suit, the second kicker matches one of the three of a kind's suits)
ABC+D+D (both kickers are suited with each other, and both use the only suit not used by the three of a kind)
The following suit shapes are duplicates of one of the above suit shapes. The reason why is because we can't assign suit B until suit A has been assigned, and we can't assign suit C until suit B has been assigned. Suit D is already assigned because it is the only suit not appearing among the three of a kind:
ABC+A+C is the same as ABC+A+B
ABC+B+A is the same as ABC+A+B
ABC+B+B is the same as ABC+A+A
ABC+B+C is the same as ABC+A+B
ABC+B+D is the same as ABC+A+D
ABC+C+A is the same as ABC+A+B
ABC+C+B is the same as ABC+A+B
ABC+C+C is the same as ABC+A+A
ABC+C+D is the same as ABC+A+D
ABC+D+B is the same as ABC+D+A
ABC+D+C is the same as ABC+D+A
---
Just apply the same logic for the other classes. Then iterate through each rank shape, and for each rank shape, iterate through each of that class's possible suit shapes, to determine the unique hand shape. When all is said and done you should have the following results:
four of a kind + one kicker: combin(13,1) * combin(12,1) = 156 rank shapes * 1 suit shape = 156 unique hand shapes
three of a kind + one pair: combin(13,1) * combin(12,1) = 156 rank shapes * 2 suit shapes = 312 unique hand shapes
three of a kind + two kickers: combin(13,1) * combin(12,2) = 858 rank shapes * 5 suit shapes = 4290 unique hand shapes
two pair + one kicker: combin(13,2) * combin(11,1) = 858 rank shapes * 8 suit shapes = 6864 unique hand shapes
one pair + three kickers: combin(13,1) * combin(12,3) = 2860 rank shapes * 20 suit shapes = 57200 unique hand shapes
five singletons = combin(13,5) = 1287 rank shapes * 51 suit shapes = 65637 unique hand shapes
and 156 + 312 + 4290 + 6864 + 57200 + 65637 = 134,459 unique hand shapes
Thanks a lot. This explains more for me. I am drafting a code to verify the hands now. Let's see how far I can go :)
Quote: ThatDonGuyWell, if that's all you are trying to do, then yes, that's all you need to do.
Of course, to determine the best way to play the hand, you have to:
(a) average the 1,533,939 ways to draw 5 cards
(b) for each of the 5 ways to keep 1 card, average the 178,365 ways to draw 4
(c) for each of the 10 ways to keep 2 cards, average the 16,215 ways to draw 3
(d) for each of the 10 ways to keep 3 card, average the 1081 ways to draw 2
(e) for each of the 5 ways to keep 4 cards, average the 47 ways to draw 1
(f) plus, of course, compare these against the hand value if you keep all 5 cards
Several years ago when I was trying to speed up my video poker analysis code (before writing the Wizard's video poker calculator), I did try to find a fast/easy way to do what you mentioned -- taking a random 5-card hand and identifying the unique hand shape which represented it -- but I never found one (I didn't try very hard or for very long). But it worked out because the approach I ended up discovering and using is so fast that there is very little room for improvement, if any.
(This assumes that 1-13 is A,2,...,K of spades, 14-26 is hearts, 27-39 is clubs, and 40-52 is diamonds)
The number to the right of each hand indicates how many times each hand appears in the 2,598,960 hands
Corrected as of 9/6/2014
4-1
A is 1..13
B is 1..13 and != A
--------------------------
A A+13 A+26 A+39 B 4
--------------------------
3-2
A is 1..13
B is 1..13 and != A
--------------------------
A A+13 A+26 B B+13 12
A A+13 A+26 B B+39 12
--------------------------
3-1-1
A is 1..13
B is 1..12 and != A
C is (B+1)..13 and != A
--------------------------
A A+13 A+26 B C 12
A A+13 A+26 B+39 C+39 4
A A+13 A+26 B C+13 24
A A+13 A+26 B+39 C 12
A A+13 A+26 B C+39 12
--------------------------
2-2-1
A is 1..12
B is (A+1)..13
C is 1..13 and != A and != B
--------------------------
A A+13 B B+13 C 12
A A+13 B B+13 C+26 12
A A+13 B B+26 C 24
A A+13 B B+26 C+13 24
A A+13 B B+26 C+26 24
A A+13 B B+26 C+39 24
A A+13 B+26 B+39 C 12
A A+13 B+26 B+39 C+26 12
--------------------------
2-1-1-1
A is 1..13
B is 1..11 and != A
C is (B+1)..12 and !=A
D is (C+1)..13 and !=A
--------------------------
A A+13 B C D 12
A A+13 B+26 C+26 D+26 12
A A+13 B C D+13 12
A A+13 B C+13 D 12
A A+13 B+13 C D 12
A A+13 B C D+26 24
A A+13 B C+26 D 24
A A+13 B+26 C D 24
A A+13 B+26 C+26 D 24
A A+13 B+26 C D+26 24
A A+13 B C+26 D+26 24
A A+13 B+26 C+26 D+39 12
A A+13 B+26 C+39 D+26 12
A A+13 B+39 C+26 D+26 12
A A+13 B C+13 D+26 24
A A+13 B C+26 D+13 24
A A+13 B+26 C D+13 24
A A+13 B C+26 D+39 24
A A+13 B+26 C D+39 24
A A+13 B+26 C+39 D 24
--------------------------
1-1-1-1-1
A is 1..9
B is (A+1)..10
C is (B+1)..11
D is (C+1)..12
E is (D+1)..13
--------------------------
A B C D E 4
A B C D E+13 12
A B C D+13 E 12
A B C+13 D E 12
A B+13 C D E 12
A+13 B C D E 12
A B C D+13 E+13 12
A B C+13 D E+13 12
A B C+13 D+13 E 12
A B+13 C D E+13 12
A B+13 C D+13 E 12
A B+13 C+13 D E 12
A+13 B C D E+13 12
A+13 B C D+13 E 12
A+13 B C+13 D E 12
A+13 B+13 C D E 12
A B C D+13 E+26 24
A B C+13 D E+26 24
A B C+13 D+26 E 24
A B+13 C D E+26 24
A B+13 C D+26 E 24
A B+13 C+26 D E 24
A+13 B C D E+26 24
A+13 B C D+26 E 24
A+13 B C+26 D E 24
A+13 B+26 C D E 24
A B C+13 D+13 E+26 24
A B C+13 D+26 E+13 24
A B C+26 D+13 E+13 24
A B+26 C D+13 E+13 24
A+26 B C D+13 E+13 24
A B+13 C D+13 E+26 24
A B+13 C D+26 E+13 24
A B+13 C+26 D E+13 24
A B+26 C+13 D E+13 24
A+26 B C+13 D E+13 24
A B+13 C+13 D E+26 24
A B+13 C+13 D+26 E 24
A B+13 C+26 D+13 E 24
A B+26 C+13 D+13 E 24
A+26 B C+13 D+13 E 24
A B C+13 D+26 E+39 24
A B+13 C D+26 E+39 24
A B+13 C+26 D E+39 24
A B+13 C+26 D+39 E 24
A+13 B C D+26 E+39 24
A+13 B C+26 D E+39 24
A+13 B C+26 D+39 E 24
A+13 B+26 C D E+39 24
A+13 B+26 C D+39 E 24
A+13 B+26 C+39 D E 24
--------------------------
Quote: ThatDonGuyHere is how to enumerate the 134,459 hands:
(This assumes that 1-13 is A,2,...,K of spades, 14-26 is hearts, 27-39 is clubs, and 40-52 is diamonds)
The number to the right of each hand indicates how many times each hand appears in the 2,598,960 hands
4-1
A is 1..13
B is 1..13 and != A
--------------------------
A A+13 A+26 A+39 B 4
--------------------------
3-2
A is 1..13
B is 1..13 and != A
--------------------------
A A+13 A+26 B B+13 12
A A+13 A+26 B B+39 12
--------------------------
3-1-1
A is 1..13
B is 1..12 and != A
C is (B+1)..13 and != A
--------------------------
A A+13 A+26 B C 12
A A+13 A+26 B+39 C+39 4
A A+13 A+26 B C+13 24
A A+13 A+26 B+39 C 12
A A+13 A+26 B C+39 12
--------------------------
2-2-1
A is 1..12
B is (A+1)..13
C is 1..13 and != A
--------------------------
A A+13 B B+13 C 12
A A+13 B B+13 C+26 12
A A+13 B B+26 C 24
A A+13 B B+26 C+13 24
A A+13 B B+26 C+26 24
A A+13 B B+26 C+39 24
A A+13 B+26 B+39 C 12
A A+13 B+26 B+39 C+26 12
--------------------------
2-1-1-1
A is 1..13
B is 1..11 and != A
C is (B+1)..12 and !=A
D is (C+1)..13 and !=A
--------------------------
A A+13 B C D 12
A A+13 B+26 C+26 D+26 12
A A+13 B C D+13 12
A A+13 B C+13 D 12
A A+13 B+13 C D 12
A A+13 B C D+26 24
A A+13 B C+26 D 24
A A+13 B+26 C D 24
A A+13 B+26 C+26 D 24
A A+13 B+26 C D+26 24
A A+13 B C+26 D+26 24
A A+13 B+26 C+26 D+39 12
A A+13 B+26 C+39 D+26 12
A A+13 B+39 C+26 D+26 12
A A+13 B C+13 D+26 24
A A+13 B C+26 D+13 24
A A+13 B+26 C D+13 24
A A+13 B C+26 D+39 24
A A+13 B+26 C D+39 24
A A+13 B+26 C+39 D 24
--------------------------
1-1-1-1-1
A is 1..9
B is (A+1)..10
C is (B+1)..11
D is (C+1)..12
E is (D+1)..13
--------------------------
A B C D E 4
A B C D E+13 12
A B C D+13 E 12
A B C+13 D E 12
A B+13 C D E 12
A B C D E 12
A B C D+13 E+13 12
A B C+13 D E+13 12
A B C+13 D+13 E 12
A B+13 C D E+13 12
A B+13 C D+13 E 12
A B+13 C+13 D E 12
A B C D E+13 12
A B C D+13 E 12
A B C+13 D E 12
A B+13 C D E 12
A B C D+13 E+26 24
A B C+13 D E+26 24
A B C+13 D+26 E 24
A B+13 C D E+26 24
A B+13 C D+26 E 24
A B+13 C+26 D E 24
A B C D E+26 24
A B C D+26 E 24
A B C+26 D E 24
A B+26 C D E 24
A B C+13 D+13 E+26 24
A B C+13 D+26 E+13 24
A B C+26 D+13 E+13 24
A B+26 C D+13 E+13 24
A B C D+13 E+13 24
A B+13 C D+13 E+26 24
A B+13 C D+26 E+13 24
A B+13 C+26 D E+13 24
A B+26 C+13 D E+13 24
A B C+13 D E+13 24
A B+13 C+13 D E+26 24
A B+13 C+13 D+26 E 24
A B+13 C+26 D+13 E 24
A B+26 C+13 D+13 E 24
A B C+13 D+13 E 24
A B C+13 D+26 E+39 24
A B+13 C+26 D E+39 24
A B+13 C+26 D E+39 24
A B+13 C+26 D+39 E 24
A B C D+26 E+39 24
A B C+26 D E+39 24
A B C+26 D+39 E 24
A B+26 C D E+39 24
A B+26 C D+39 E 24
A B+26 C+39 D E 24
--------------------------
Many thanks. I finally got all 134459 hands :)
Quote: ThatDonGuyHere is how to enumerate the 134,459 hands:
(This assumes that 1-13 is A,2,...,K of spades, 14-26 is hearts, 27-39 is clubs, and 40-52 is diamonds)
The number to the right of each hand indicates how many times each hand appears in the 2,598,960 hands
4-1
A is 1..13
B is 1..13 and != A
--------------------------
A A+13 A+26 A+39 B 4
--------------------------
3-2
A is 1..13
B is 1..13 and != A
--------------------------
A A+13 A+26 B B+13 12
A A+13 A+26 B B+39 12
--------------------------
3-1-1
A is 1..13
B is 1..12 and != A
C is (B+1)..13 and != A
--------------------------
A A+13 A+26 B C 12
A A+13 A+26 B+39 C+39 4
A A+13 A+26 B C+13 24
A A+13 A+26 B+39 C 12
A A+13 A+26 B C+39 12
--------------------------
2-2-1
A is 1..12
B is (A+1)..13
C is 1..13 and != A
--------------------------
A A+13 B B+13 C 12
A A+13 B B+13 C+26 12
A A+13 B B+26 C 24
A A+13 B B+26 C+13 24
A A+13 B B+26 C+26 24
A A+13 B B+26 C+39 24
A A+13 B+26 B+39 C 12
A A+13 B+26 B+39 C+26 12
--------------------------
2-1-1-1
A is 1..13
B is 1..11 and != A
C is (B+1)..12 and !=A
D is (C+1)..13 and !=A
--------------------------
A A+13 B C D 12
A A+13 B+26 C+26 D+26 12
A A+13 B C D+13 12
A A+13 B C+13 D 12
A A+13 B+13 C D 12
A A+13 B C D+26 24
A A+13 B C+26 D 24
A A+13 B+26 C D 24
A A+13 B+26 C+26 D 24
A A+13 B+26 C D+26 24
A A+13 B C+26 D+26 24
A A+13 B+26 C+26 D+39 12
A A+13 B+26 C+39 D+26 12
A A+13 B+39 C+26 D+26 12
A A+13 B C+13 D+26 24
A A+13 B C+26 D+13 24
A A+13 B+26 C D+13 24
A A+13 B C+26 D+39 24
A A+13 B+26 C D+39 24
A A+13 B+26 C+39 D 24
--------------------------
1-1-1-1-1
A is 1..9
B is (A+1)..10
C is (B+1)..11
D is (C+1)..12
E is (D+1)..13
--------------------------
A B C D E 4
A B C D E+13 12
A B C D+13 E 12
A B C+13 D E 12
A B+13 C D E 12
A B C D E 12
A B C D+13 E+13 12
A B C+13 D E+13 12
A B C+13 D+13 E 12
A B+13 C D E+13 12
A B+13 C D+13 E 12
A B+13 C+13 D E 12
A B C D E+13 12
A B C D+13 E 12
A B C+13 D E 12
A B+13 C D E 12
A B C D+13 E+26 24
A B C+13 D E+26 24
A B C+13 D+26 E 24
A B+13 C D E+26 24
A B+13 C D+26 E 24
A B+13 C+26 D E 24
A B C D E+26 24
A B C D+26 E 24
A B C+26 D E 24
A B+26 C D E 24
A B C+13 D+13 E+26 24
A B C+13 D+26 E+13 24
A B C+26 D+13 E+13 24
A B+26 C D+13 E+13 24
A B C D+13 E+13 24
A B+13 C D+13 E+26 24
A B+13 C D+26 E+13 24
A B+13 C+26 D E+13 24
A B+26 C+13 D E+13 24
A B C+13 D E+13 24
A B+13 C+13 D E+26 24
A B+13 C+13 D+26 E 24
A B+13 C+26 D+13 E 24
A B+26 C+13 D+13 E 24
A B C+13 D+13 E 24
A B C+13 D+26 E+39 24
A B+13 C+26 D E+39 24
A B+13 C+26 D E+39 24
A B+13 C+26 D+39 E 24
A B C D+26 E+39 24
A B C+26 D E+39 24
A B C+26 D+39 E 24
A B+26 C D E+39 24
A B+26 C D+39 E 24
A B+26 C+39 D E 24
--------------------------
I have checked all those 134459 hands and try to estimate the payback, I got 1.01972. I wonder why in the list you gave, there is a duplicate hand
I think I mixed the method told by JB and you, that's how I got that 134459 hands. But I read your method given in the quote carefully, I find something that I don't quite understand
1) I find that some hands are duplicated, e.g.
A B+13 C+26 D E+39 24
A B+13 C+26 D E+39 24
A B C D E 12 also appears twice.
2) for some ranking, why some card will enumerate from 1 to 12 instead of 1 to 13, for example
2-2-1
A is 1..12
B is (A+1)..13
C is 1..13 and != A
--------------------------
A A+13 B B+13 C 12
A A+13 B B+13 C+26 12
A A+13 B B+26 C 24
A A+13 B B+26 C+13 24
A A+13 B B+26 C+26 24
A A+13 B B+26 C+39 24
A A+13 B+26 B+39 C 12
A A+13 B+26 B+39 C+26 12
--------------------------
my code is
int counts=0;
for (int A=1; A<=12; A++)
{
hand[1] = A;
hand[2] = A+ 13;
for (int B=A+1; B<=13; B++)
{
for (int C=1; C<=13; C++)
{
if (A!=C)
{
// assign others
counts++;
}
}
}
}
cout << couts << endl;
this code shows 936 hands instead of 858.
Quote: konglifyI have checked all those 134459 hands and try to estimate the payback, I got 1.01972. I wonder why in the list you gave, there is a duplicate hand
I think I mixed the method told by JB and you, that's how I got that 134459 hands. But I read your method given in the quote carefully, I find something that I don't quite understand
1) I find that some hands are duplicated, e.g.
A B+13 C+26 D E+39 24
A B+13 C+26 D E+39 24
A B C D E 12 also appears twice.
The second A B+13 C+26 D E+39 (24) should be A B+13 C D+26 E+39
The second A B C D E (12) should be A+13 B C D E
Quote:
2) for some ranking, why some card will enumerate from 1 to 12 instead of 1 to 13, for example
2-2-1
A is 1..12
B is (A+1)..13
C is 1..13 and != A
this code shows 936 hands instead of 858.
That should read "C is 1..13 and != A and != B"
Quote:
for some ranking, why some card will enumerate from 1 to 12 instead of 1 to 13
That's so, for example, in 2-2-1, you don't count As Ah 2s 2h 3s and 2s 2h As Ah 3s as two different hands.
I also noticed a number of errors in the last part (the hands with no pairs). Go back up to my original list of hands to see the corrected versions.
Quote: ThatDonGuyQuote: konglifyI have checked all those 134459 hands and try to estimate the payback, I got 1.01972. I wonder why in the list you gave, there is a duplicate hand
I think I mixed the method told by JB and you, that's how I got that 134459 hands. But I read your method given in the quote carefully, I find something that I don't quite understand
1) I find that some hands are duplicated, e.g.
A B+13 C+26 D E+39 24
A B+13 C+26 D E+39 24
A B C D E 12 also appears twice.
The second A B+13 C+26 D E+39 (24) should be A B+13 C D+26 E+39
The second A B C D E (12) should be A+13 B C D EQuote:
2) for some ranking, why some card will enumerate from 1 to 12 instead of 1 to 13, for example
2-2-1
A is 1..12
B is (A+1)..13
C is 1..13 and != A
this code shows 936 hands instead of 858.
That should read "C is 1..13 and != A and != B"Quote:
for some ranking, why some card will enumerate from 1 to 12 instead of 1 to 13
That's so, for example, in 2-2-1, you don't count As Ah 2s 2h 3s and 2s 2h As Ah 3s as two different hands.
I also noticed a number of errors in the last part (the hands with no pairs). Go back up to my original list of hands to see the corrected versions.
Thanks for the update. I got all 134459 unique hands now. But after calculating the payback, I got 0.96923 instead of 0.9954 on the so-called "9-6" Jacks or Better
Royal flush 800
Straight flush 50
Four of a kind 25
Full house 9
Flush 6
Straight 4
Three of a kind 3
Two pair 2
Jacks or Better 1
Nothing 0
I checked for long time but still cannot find what cause the difference.
Quote: konglifyI checked for long time but still cannot find what cause the difference.
A good place to start would be to write a debugging function which loops through all 2,598,960 hands, or the 134,459 unique hands with weighting, and count how many times each type of hand occurs to make sure your hand-scoring code is correct. Here are the totals you should see:
Hand | Count |
---|---|
Royal Flush | 4 |
Straight Flush | 36 |
Four of a Kind | 624 |
Full House | 3,744 |
Flush | 5,108 |
Straight | 10,200 |
Three of a Kind | 54,912 |
Two Pair | 123,552 |
Jacks or Better | 337,920 |
All Other | 2,062,860 |
Quote: JBA good place to start would be to write a debugging function which loops through all 2,598,960 hands, or the 134,459 unique hands with weighting, and count how many times each type of hand occurs to make sure your hand-scoring code is correct. Here are the totals you should see:
Hand Count Royal Flush 4 Straight Flush 36 Four of a Kind 624 Full House 3,744 Flush 5,108 Straight 10,200 Three of a Kind 54,912 Two Pair 123,552 Jacks or Better 337,920 All Other 2,062,860
Thanks. I just check my code, they give the exact same result for hit of each hand as yours.
Quote: konglifyI just check my code, they give the exact same result for hit of each hand as yours.
Double-check to make sure you are applying each unique hand's weight factor to its final hand probabilities, otherwise you are effectively treating each of the 134459 hands as being equally likely on the deal, which they are not.
If that's being handled correctly, try spot-checking the draw combination counts for a few hands. Play the Wizard's video poker game and deal a hand, then click the Analyze button. Have your program analyze that same exact hand, and compare your results with those shown in the game.
If you still can't find anything wrong, it will be difficult to pinpoint the problem without seeing your code.
Quote: JBDouble-check to make sure you are applying each unique hand's weight factor to its final hand probabilities, otherwise you are effectively treating each of the 134459 hands as being equally likely on the deal, which they are not.
If that's being handled correctly, try spot-checking the draw combination counts for a few hands. Play the Wizard's video poker game and deal a hand, then click the Analyze button. Have your program analyze that same exact hand, and compare your results with those shown in the game.
If you still can't find anything wrong, it will be difficult to pinpoint the problem without seeing your code.
Hi JB, I took your advice to spot check some hands and figure out the reason causing the wrong payback. I can now obtain the correct payback. By using 134459 hands, I can boost up the algorithm to calculate the payback in 3 hours, which is much faster than the one very first one by considering all 2598960 hands. My algorithm is very introductory. I just wonder how other can make the calculation so fast and calculate the result in 7 seconds like this one http://www.dagblastit.com/vidpoker_story.html
https://wizardofodds.com/games/video-poker/methodology/
Quote: konglifyHi JB, I took your advice to spot check some hands and figure out the reason causing the wrong payback. I can now obtain the correct payback. By using 134459 hands, I can boost up the algorithm to calculate the payback in 3 hours, which is much faster than the one very first one by considering all 2598960 hands. My algorithm is very introductory. I just wonder how other can make the calculation so fast and calculate the result in 7 seconds like this one http://www.dagblastit.com/vidpoker_story.html
wow, 0 to 60 in < 2 wks? Congratulations.
Quote: CrystalMathMustang Sally pointed this out earlier, but it contains the secret to a sub 7 second program. Search for "three-second" and start there.
https://wizardofodds.com/games/video-poker/methodology/
Yes, I got the same info from that link. But some message in the link is kind of confusing. In the algorithm explanation part, it said
Quote:1. Initialize the following arrays:
Array 1: size 2,598,960
Array 2: size 270,725 by 16
Array 3: size 22100 by 16
Array 4: size 1326 by 16
Array 5: size 52 by 16
Array 6: size 16
I think array 1 is used to carry the count of each single possible 5-card hand in a deck, array 2 is used to hold the count for the a hand when 2 cards placed, ... etc. In step two
Quote:
2. Loop through all 2,598,960 combinations of 5 cards out of 52. Do NOT use the 134,459 hand shortcut at this point. For each hand on the deal do the following:
Score it according to its poker value.
Put the score in array0. Put the first hand in element 0 of the array, and increment by 1 for each hand.
For each of the 5 ways to choose 4 out of 5 cards on the deal, translate the four cards into an index number from 0 to 270,724 (I'll explain how to do that later), and increment element [index number][hand score] of array1 by 1.
For each of the 10 ways to choose 3 out of 5 cards on the deal, translate the three cards into an index number from 0 to 22,099, and increment element [index number][hand score] of array2 by 1.
For each of the 10 ways to choose 2 out of 5 cards on the deal, translate the two cards into an index number from 0 to 1,325, and increment element [index number][hand score] of array3 by 1.
For each of the 5 ways to choose 1 out of 5 cards on the deal, translate the card into an index number from 0 to 51, and increment element [index number][hand score] of array4 by 1.
Increment element [hand score] of array5 by 1.
Here I guess array0 is the pay table? But in next item, "for each of the 5 ways to choose 4 out of 5 cards on the deal .... " why it put the count into array1? there it said the index number ranged from 0 to 270, 724 but array1 is of the size 2,598,960 I think.
Let's assume it is just typo. I want to make sure my understanding on the logic is correct. It seems that array1 to array6 is just used to carry the counts for a given hand when no card, 1 card, 2 cards, 3 cards, 4 cards and 5 cards are replaced. Is that correct?
So the next step the article mentioned is something like the following pseudo code?
for each hand in 134,459
begin
for n = each way out of 32 to replace the cards of that hand
begin
calculate the index of the replaced hand
search the table (corresponding array 1 to 6) for that index to find the total # of way
payoff [n] = # of way/total possible way
end
totalpayoff += max{payoff[0] ... payoff[31]}*weight of that hand
end
Array0 holds the evaluation of each possible final hand. I use integers for the hand:
Nothing = 0
Jacks or Better = 1
Two Pair = 2
Three of a Kind = 3
Straight = 4
Flush = 5
Full House = 6
Four of a Kind = 7
Straight Flush = 8
Royal Flush = 9
Array1 holds a count of all the possible 5 card hands that each 4 card hand can draw to.
For instance, take the four cards KS JS TS 2S. This can draw to 9 flushes, 6 jacks or better, and 33 hands of nothing, so the array entry for this four card hand, in Array1 would be [33, 6, 0, 0, 9, 0, 0, 0, 0].
This array gets filled at this step "for each of the 5 ways to choose 4 cards out of five on the deal..."
Later, when you are going through your 134,459 hands, you will use Array1 to Array5 to determine what your hand will draw to instead of looping through each possibility.
Let's say you have the hand KS JS TS 3C 2S (evaluates to nothing), and you want to know what will happen if you throw away the 3. You will look up KS JS TS 2S in Array1, but then you will subtract the current hand from that array (lookup the 5 card hand in Array0), since you cannot draw back to the same hand. So, your hits for tossing the 3 will be [32, 6, 0, 0, 9, 0, 0, 0, 0].
Step #6-9 is the next hurdle, where you must determine exactly what to add and subtract from Array1 to Array5 to get what you are looking for. I just showed the easiest example here.
After you have implemented the combination technique to quickly calculate the distribution of hands on the draw, there are additional optimizations that can be made to speed things up further if you're looking for the fastest execution possible.
Quote: CrystalMathFirst, there is a discrepancy on that page: the arrays are labeled 1...6, but are later referred to as 0...5. I prefer to use arrays 0 to 5.
Array0 holds the evaluation of each possible final hand. I use integers for the hand:
Nothing = 0
Jacks or Better = 1
Two Pair = 2
Three of a Kind = 3
Straight = 4
Flush = 5
Full House = 6
Four of a Kind = 7
Straight Flush = 8
Royal Flush = 9
Array1 holds a count of all the possible 5 card hands that each 4 card hand can draw to.
For instance, take the four cards KS JS TS 2S. This can draw to 9 flushes, 6 jacks or better, and 33 hands of nothing, so the array entry for this four card hand, in Array1 would be [33, 6, 0, 0, 9, 0, 0, 0, 0].
This array gets filled at this step "for each of the 5 ways to choose 4 cards out of five on the deal..."
Later, when you are going through your 134,459 hands, you will use Array1 to Array5 to determine what your hand will draw to instead of looping through each possibility.
Let's say you have the hand KS JS TS 3C 2S (evaluates to nothing), and you want to know what will happen if you throw away the 3. You will look up KS JS TS 2S in Array1, but then you will subtract the current hand from that array (lookup the 5 card hand in Array0), since you cannot draw back to the same hand. So, your hits for tossing the 3 will be [32, 6, 0, 0, 9, 0, 0, 0, 0].
Step #6-9 is the next hurdle, where you must determine exactly what to add and subtract from Array1 to Array5 to get what you are looking for. I just showed the easiest example here.
Thanks. Let's me try again.
Quote: JBDone properly, you can have it analyze a game in less than half a second, provided you're running a fairly modern computer. On my 3GHz computer, the code I used in the Wizard's video poker calculator can analyze Jacks or Better in 0.2 seconds.
After you have implemented the combination technique to quickly calculate the distribution of hands on the draw, there are additional optimizations that can be made to speed things up further if you're looking for the fastest execution possible.
Sounds very promising. I will try ;)
Quote: CrystalMathFirst, there is a discrepancy on that page: the arrays are labeled 1...6, but are later referred to as 0...5. I prefer to use arrays 0 to 5.
Array0 holds the evaluation of each possible final hand. I use integers for the hand:
Nothing = 0
Jacks or Better = 1
Two Pair = 2
Three of a Kind = 3
Straight = 4
Flush = 5
Full House = 6
Four of a Kind = 7
Straight Flush = 8
Royal Flush = 9
Array1 holds a count of all the possible 5 card hands that each 4 card hand can draw to.
For instance, take the four cards KS JS TS 2S. This can draw to 9 flushes, 6 jacks or better, and 33 hands of nothing, so the array entry for this four card hand, in Array1 would be [33, 6, 0, 0, 9, 0, 0, 0, 0].
This array gets filled at this step "for each of the 5 ways to choose 4 cards out of five on the deal..."
Later, when you are going through your 134,459 hands, you will use Array1 to Array5 to determine what your hand will draw to instead of looping through each possibility.
Let's say you have the hand KS JS TS 3C 2S (evaluates to nothing), and you want to know what will happen if you throw away the 3. You will look up KS JS TS 2S in Array1, but then you will subtract the current hand from that array (lookup the 5 card hand in Array0), since you cannot draw back to the same hand. So, your hits for tossing the 3 will be [32, 6, 0, 0, 9, 0, 0, 0, 0].
Step #6-9 is the next hurdle, where you must determine exactly what to add and subtract from Array1 to Array5 to get what you are looking for. I just showed the easiest example here.
I wrote the code but it give me something very odd. I think I mess up the array1 to array5. In your statement, you said ""Array1 holds a count of all the possible 5 card hands that each 4 card hand can draw to." Let's consider the array1 only, to build that I enumerate each of all 2598960 hands, for one hand, I hold 1 card only and try to fill the other 4 with the cards hold in the rest of the deck and I make a index with that 4 cards, which is used to build the table, is that correct?
It is also confusing on array0 and array5. You said Array0 holds the evaluation of each possible final hand, so array0 is of 2598960 size? What about array5?