![]() |
|
#61
|
|||
|
|||
|
gotchya, my ".type" uses the similar type of suit compression that you are doing in your lookup tables. Basically signalling when suits can be ignored.
|
|
#62
|
|||
|
|||
|
nah, i ran it with the checksum counters to make sure i got the same checksum results. Promise my timings are legit. I did comment out the checksums though to get the faster time. I did test empty loops too, i get about 4.2-8.5 biilion a second. Hard to get an exact read, because seems timer increments in .015XXXX intervals
Only commented out the "select case" portion to determine what type of hand was made. but still have an assignment to the variable "rank". |
|
#63
|
|||
|
|||
|
[ QUOTE ]
how big are the LU tables combined under this method? [/ QUOTE ] Just one large table... Exactly 127,499,424 bytes used as 31,874,856 32-bit integers. The 1st 206 bytes were for error catching. (entering the same card twice) but since they don't catch all of the possibilities, they are pretty much wasted space. |
|
#64
|
|||
|
|||
|
As you can see its speed is primarily due to being able to solve for many hands in one lookup
Yeah, There's a distinct difference between lumping evals together and a fast generic evaluator. You can certainly do evals rather quickly if you are able to "share results" across cases. Under specific circumstances this is a fairly straightforard process. In general, it's rather difficult. How fast can you get the generic evaluator to go? - Andrew |
|
#65
|
|||
|
|||
|
[ QUOTE ]
nah, i ran it with the checksum counters to make sure i got the same checksum results. Promise my timings are legit. I did comment out the checksums though to get the faster time. I did test empty loops too, i get about 4.2-8.5 biilion a second. Hard to get an exact read, because seems timer increments in .015XXXX intervals Only commented out the "select case" portion to determine what type of hand was made. but still have an assignment to the variable "rank". [/ QUOTE ] This is exactly what I was talking about. Just becuase you have code that assigns a value to rank, doesn't mean that code will be executed. Optimizers can detect that you aren't using the value assigned to rank, and therefore eliminate the code that does the assigning. "I did test empty loops too, i get about 4.2-8.5 biilion a second." Ok I see what's happening... since you "looped" 133 millions times in 1 time unit (approx 0.01573936) you divide 133 million by 0.01573936 giving the 8.5 billion. That makes the code being eliminated by the optimizer even more likely. |
|
#66
|
|||
|
|||
|
I get 4.2 to 8.5 billion with empty loops on an AMD Athlon 64 fx-60 dual 2gigs.
Anyways, when i add back in the commented out checksums i drop from 279 million a second, to 102 million a second. Now is that because rank was being optimized out...hard to say, because right now most calculations are simply a array lookups. Comparisons such as If X > Y only occur when a problem gets flagged as difficult. Adding 9 range comparisons (if x between 0 and 3000) should definately slow it down a bit...so i'm thinking that the 239 million is correct as is. But at any rate, 102 million with time to process checksums included. I hate select case, and if..then operations in vbasic b/c they are slow....which is why i avoid them whenever i can. |
|
#67
|
|||
|
|||
|
[ QUOTE ]
There's a distinct difference between lumping evals together and a fast generic evaluator. You can certainly do evals rather quickly if you are able to "share results" across cases. Under specific circumstances this is a fairly straightforard process. In general, it's rather difficult. How fast can you get the generic evaluator to go? [/ QUOTE ] This is true, my program "cheats." But for pretty much all my purposes I need a cheating algorithm cause its faster. Game theory is all working backwards from specific flops-turns-rivers (FTRs) and unknown strategies or distributions. Thus, rarely will i just want to know the value of one two-card holding for any given flop, but how one distribution compares to another. Even normal applications, such as calculating rankings for multiple players on the same flop can benefit from a cheating algorithm. I mean do we really need to look up hand values if all your opponents have already folded? So cheating algorithms are faster for me.... But your point is understood. Anyways, if i put everything inside all 7 for loops i get about 65 million games a second. It could probably be optimized a bit more for these conditions. For instance, if five cards on the board, my code will look up a corresponding array for those 5 cards, and then compute values using only the final two cards. No need to do this if that 5 card array is only going to be used once. |
|
#68
|
|||
|
|||
|
This is true, my program "cheats."
I wouldn't call that cheating. But it's an important distinction. If people want to make comparisons, it's useful to agree on what you're comparing. PokerStove can do over 1.5 billion evals/sec by grouping evals together. But that's different from a generic evaluation. - Andrew |
|
#69
|
|||
|
|||
|
Tried my luck at a Lexographical version:
This one i'll share all ...b/c largely inspired by posts here. I don't yet have a sorting algorithm for it yet. Gull you said you had a good one? Pre-sorted, its 209 million a second (140 million with checksums), but i suspect most the work will be done sorting it once someone adds that feature. It so happens that the for loops gull wanted us to use for the test...are pre-sorted in ascending order, which is what this lexographic index requires. Once you include sort time, i would think Mykey's would have to be faster. His puts the cards in order, and reduce by equivalence classes with each lookup, as well as assigning a unique index. If i get time i'll try to add that feature, but sounds tough. Mykey, if i make those improvements, do u want me to post em or no? Probably wouldn't have thought of em, if not for u, so let me know if you'd prefer me not posting those methods. Main Function: Dim index As Long Dim rank As Integer Dim c1 As Integer Dim c2 As Integer Dim c3 As Integer Dim c4 As Integer Dim c5 As Integer Dim c6 As Integer Dim c7 As Integer date1 = Timer For c1 = 1 To 46 For c2 = c1 + 1 To 47 For c3 = c2 + 1 To 48 For c4 = c3 + 1 To 49 For c5 = c4 + 1 To 50 For c6 = c5 + 1 To 51 For c7 = c6 + 1 To 52 'insert a sort algorithm here c1....through c7 index = A_Sum1(c1) + A_Sum2(c1, c2) + A_Sum3(c2, c3) + A_Sum4(c3, c4) + A_Sum5(c4, c5) + A_Sum6(c5, c6) + (c7 - c6) rank = Rank_Array(index) Next c7 Next c6 Next c5 Next c4 Next c3 Next c2 Next c1 date2 = Timer This is code necessary to generate the arrays: Run it once, store the arrays in a file, and load them. Open "C:\Program Files\DevStudio\VB\Poker5\Rank_Array.bin" For Binary As #5 Get #5, , Rank_Array vindex = 51 For i = 1 To 46 P_Sum1(i) = Combin(vindex, 6) vindex = vindex - 1 Next i vindex = 50 For i = 2 To 47 P_Sum2(i) = Combin(vindex, 5) vindex = vindex - 1 Next i vindex = 49 For i = 3 To 48 P_Sum3(i) = Combin(vindex, 4) vindex = vindex - 1 Next i vindex = 48 For i = 4 To 49 P_Sum4(i) = Combin(vindex, 3) vindex = vindex - 1 Next i vindex = 47 For i = 5 To 50 P_Sum5(i) = Combin(vindex, 2) vindex = vindex - 1 Next i vindex = 46 For i = 6 To 51 P_Sum6(i) = Combin(vindex, 1) vindex = vindex - 1 Next i For i = 1 To 46 For j = 1 To i - 1 A_Sum1(i) = A_Sum1(i) + P_Sum1(j) Next j Next i For i = 1 To 46 For j = i + 2 To 47 For k = i + 1 To j - 1 A_Sum2(i, j) = A_Sum2(i, j) + P_Sum2(k) Next k Next j Next i For i = 2 To 47 For j = i + 2 To 48 For k = i + 1 To j - 1 A_Sum3(i, j) = A_Sum3(i, j) + P_Sum3(k) Next k Next j Next i For i = 3 To 48 For j = i + 2 To 49 For k = i + 1 To j - 1 A_Sum4(i, j) = A_Sum4(i, j) + P_Sum4(k) Next k Next j Next i For i = 4 To 49 For j = i + 2 To 50 For k = i + 1 To j - 1 A_Sum5(i, j) = A_Sum5(i, j) + P_Sum5(k) Next k Next j Next i For i = 5 To 50 For j = i + 2 To 51 For k = i + 1 To j - 1 A_Sum6(i, j) = A_Sum6(i, j) + P_Sum6(k) Next k Next j Next i //////Need this function to calculate permutations//// Private Function Combin(n As Byte, r As Byte) As Long Dim t As Byte Dim u As Double Dim v As Double If r > n Then Combin = 0 Else If r = n Then Combin = 1 Else u = 1 For t = (n - r) + 1 To n u = u * t Next t Rem Permutation(n,r) is calculated as above v = 1 For t = 1 To r v = v * t Next t Rem r! is calculated as above Rem r!= 1*...*(r-1)*r Combin = (u / v) Rem Combination = n! / ((n-r)! * r!) Rem Combination(n,r) = Permutation(n,r) / r! Rem (n!)/(n-r!) = ((n-r)+1)*((n-r)+2)*....*n End If End If End Function |
|
#70
|
|||
|
|||
|
I know poker stove pre-flop is all tabled out...extremely fast. But once u specify part of the flop, it starts working off tables (or at least not as fast)...from about 1.7 billion(on my comp) to between 3 to 16 million (with wide player distributions so not as to run into the narrow distribution problem). So i do think these algorithm's do have a lot of merit for partial flop analysis.
Again not knocking p-stove, but i think these algorithms shine in the right conditions. |
![]() |
|
|