Sign in to follow this  
Followers 0
JRowe

Random 7 card poker hand

13 posts in this topic

#1 ·  Posted (edited)

I wrote a little function to deal a random 7 card poker hand. It works just fine, it's not slow, and I'm generally happy with it, except for one thing... how the heck can I nest the While loops to clean up the tests against existing cards?

Here's my code:

Func DealAHand()

        dim $generatedHand[7]
        $DealtCard1 = Random(0, 51, 1)
        $DealtCard2 = Random(0, 51, 1)
        $DealtCard3 = Random(0, 51, 1)
        $DealtCard4 = Random(0, 51, 1)
        $DealtCard5 = Random(0, 51, 1)
        $DealtCard6 = Random(0, 51, 1)
        $DealtCard7 = Random(0, 51, 1)
        
        While $DealtCard2 = $DealtCard1
            $DealtCard2 = Random(0, 51, 1)
        WEnd
        While $DealtCard3 = $DealtCard1 Or $DealtCard3 = $DealtCard2
            $DealtCard3 = Random(0, 51, 1)
        WEnd
        While $DealtCard4 = $DealtCard1 Or $DealtCard4 = $DealtCard2 Or $DealtCard4 = $DealtCard3
            $DealtCard4 = Random(0, 51, 1)
        WEnd
        While $DealtCard5 = $DealtCard1 Or $DealtCard5 = $DealtCard2 Or $DealtCard5 = $DealtCard3 Or $DealtCard5 = $DealtCard4
            $DealtCard5 = Random(0, 51, 1)
        WEnd
        While $DealtCard6 = $DealtCard1 Or $DealtCard6 = $DealtCard2 Or $DealtCard6 = $DealtCard3 Or $DealtCard6 = $DealtCard4 Or $DealtCard6 = $DealtCard5
            $DealtCard6 = Random(0, 51, 1)
        WEnd    
        While $DealtCard7 = $DealtCard1 Or $DealtCard7 = $DealtCard2 Or $DealtCard7 = $DealtCard3 Or $DealtCard7 = $DealtCard4 Or $DealtCard7 = $DealtCard5 Or $DealtCard7 = $DealtCard6
            $DealtCard7 = Random(0, 51, 1)
        WEnd

        $generatedHand[0] = $DealtCard1
        $generatedHand[1] = $DealtCard2
        $generatedHand[2] = $DealtCard3
        $generatedHand[3] = $DealtCard4
        $generatedHand[4] = $DealtCard5
        $generatedHand[5] = $DealtCard6
        $generatedHand[6] = $DealtCard7
        
    Return $generatedHand
        
EndFunc

I know there's got to be a way to wrap it up more cleanly than this, and I know it's easy, but I've forgotten how to nest loops efficiently.

Thanks for any help!

edit: changed Random range to 0,51, instead of 0, 52. Oops :P

Edited by jrowe

Share this post


Link to post
Share on other sites



It seems to be pretty darn fast, btw. I can generate 1 million random hands in about 50 seconds. Since my evaluator function takes .3 milliseconds per hand, the generator should be the only bottleneck for monte carlo simulation.

Once I understand nesting, things should proceed nicely :P

Share this post


Link to post
Share on other sites

Something like this:

Func DealAHand()
    Local $GeneratedHand[7]
    
    For $i = 1 To 7
        Assign("DealtCard" & $i, Random(0, 52, 1), 1)
    Next
    
    For $i = 2 To 7
        For $j = $i-1 To 1 Step -1
            While Eval("DealtCard" & $i) = Eval("DealtCard" & $j)
                Assign("DealtCard" & $i, Random(0, 52, 1))
            WEnd
        Next
    Next
    
    $GeneratedHand[0] = $DealtCard1
    $GeneratedHand[1] = $DealtCard2
    $GeneratedHand[2] = $DealtCard3
    $GeneratedHand[3] = $DealtCard4
    $GeneratedHand[4] = $DealtCard5
    $GeneratedHand[5] = $DealtCard6
    $GeneratedHand[6] = $DealtCard7
    
    Return $GeneratedHand 
EndFunc

?

:P


 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

Absolutely, much thanks! Although, it takes about twice as long, probably because of the eval. Now that I see the logic, though, it won't be a big leap to the next step. $DealtCardX is probably redundant, so I'll just post cards directly to $generatedHand[].

Thanks man!

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Or better:

#include <Array.au3>

$aRet = DealAHand(52, 0)

_ArrayDisplay($aRet)

Func DealAHand($iMax=52, $iMin=0)
    Local $GeneratedHand[7]
    
    For $i = 0 To 6
        While 1
            $GeneratedHand[$i] = Random($iMin, $iMax, 1)
            
            For $j = 0 To 6
                If $j = $i Then ContinueLoop
                
                If $GeneratedHand[$j] = $GeneratedHand[$i] Then ContinueLoop 2
            Next
            
            ExitLoop
        WEnd
    Next
    
    Return $GeneratedHand 
EndFunc
Edited by MrCreatoR

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

Awesome, getting better. Also, the iMin and iMax should be 0 to 51, not 52.

Unless, of course, you have a joker in the deck.

22 seconds to generate 100,000 hands with this func, 8 to deal 100,000 with the original. Any idea how to improve performance? And a big thank you! I appreciate the help.

Share this post


Link to post
Share on other sites

I don't really see where you can think of it getting much faster. The while's are basically conditional statements, and a lot of the times you won't be in but a couple if any of them at all. Anything else added or attempted is just a waste of resources IMHO.


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Yeah, I've spent about 3 hours on it now, and the fastest I can generate hands is by placing the generator function in a For..To..Step/Next loop.

28 seconds for a million hands, not bad. :P

I'm working on evaluation now, and then I'll post a little poker package in the example scripts section.

Share this post


Link to post
Share on other sites

Yeah, I've spent about 3 hours on it now, and the fastest I can generate hands is by placing the generator function in a For..To..Step/Next loop.

28 seconds for a million hands, not bad. :P

I'm working on evaluation now, and then I'll post a little poker package in the example scripts section.

I have an Array shuffler that I thought may give a run for the money... even after manipulating that ... I proved to myself it had it's own purpose (to shuffle arrays lol). It's faster than the examples above other than yours, but for this task, not quite fast enough (2 x's slower than yours).

Yours over 1 million hands averaged .0007 seconds per cycle.

My array shufller over 1 million hands averaged .0015 seconds per cycle.

On your evaluator, are you going to use a hash?


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

I'm using the "2 + 2" evaluator, using cactus kev notation, http://www.codingthewheel.com/archives/pok...tor-roundup#2p2

I've already got it in a plugin, and I'm tidying up the source and UDF-afying the implementation.

On just a wonky little test I did just now, I generated, enumerated, and evaluated 1,000,000 hands in 41 seconds (40.606543 seconds, to be exact.)

Granted, that isn't doing a hand vs hand range comparison or any real heavy lifting, but I think I'm a little excited about the potential.

Share this post


Link to post
Share on other sites

I'm using the "2 + 2" evaluator, using cactus kev notation, http://www.codingthewheel.com/archives/pok...tor-roundup#2p2

I've already got it in a plugin, and I'm tidying up the source and UDF-afying the implementation.

On just a wonky little test I did just now, I generated, enumerated, and evaluated 1,000,000 hands in 41 seconds (40.606543 seconds, to be exact.)

Granted, that isn't doing a hand vs hand range comparison or any real heavy lifting, but I think I'm a little excited about the potential.

That actually looks like impressive speeds for the tools being used.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

It should get faster. I'm going to first do monte carlo evaluation vs ranges of hands, and then figure out how to use math to get an absolute evaluation for a given hand across all possible hands of a particular range. I'm guessing that I can plugin-ify the absolute evaluation, and I'll want to do analysis of the Hole cards, Flop + Hole, Flop- Hole, and so forth to the river, to keep a realtime absolute Odds analysis. I can use the Odds to calculate pot odds, pot equity, range equity, and so forth, to build models of opponent strategies and also create optimal strategies for any stage in online poker games.

:P

Yeah, I *could* have had a top-ten hands or bust bot built by now, but what I really want is to learn the math behind hold-em. All I gotta say is "WOW." That's a helluva lot of numbers for a simple-seeming game.

Share this post


Link to post
Share on other sites

Well, I'm forsaking neatly readable for speedy and somewhat readable. As for the other poker stuff, well, my code currently looks like this:

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $DealButton
            $begin = TimerInit()
                $myHand = DealAHandOptimum()
                $Analysis = AnalyzeHand($myHand[0], $myHand[1], $myHand[2], $myHand[3], $myHand[4], $myHand[5], $myHand[6])
            $HandCategory = BitShift($Analysis, 12)
            $HandRankWithinCategory = BitAND($Analysis, 0x00000FFF)
            
        ;$k = $Category[$HandCategory] - $HandRankWithinCategory
        ;;;;;;;;;;;;;;;;;;;;;FUNCIFY THIS ONE. GETS HAND INFORMATION FROM INDEX;;;;;;;;;;;;;;;;;;;;
            For $j = 8 to $HandCategory-1 step -1
                $k = $k + $Category[$j]
            Next
            $position = $k - $HandRankWithinCategory + 1
        ;;;;;;;;;;;;;;;;;;;;;FUNCIFY THIS ONE. GETS HAND INFORMATION FROM INDEX;;;;;;;;;;;;;;;;;;;;
            
            $dif = TimerDiff($begin)
            $HandString = $cardsList[$myHand[0]-1] & ", " & $cardsList[$myHand[1]-1] & ", " & $cardsList[$myHand[2]-1] & ", " & $cardsList[$myHand[3]-1] & ", " & $cardsList[$myHand[4]-1]& ", " & $cardsList[$myHand[5]-1] & ", " & $cardsList[$myHand[6]-1]
MsgBox(0,"1", $HandString & @CRLF &"Type of Hand:"&$HandRanksArray[$position][0] &@CRLF& "Best 5 Card Hand:"& $HandRanksArray[$position][2] &@CRLF& "Generated and evaluated Hand in :" & $dif & " milliseconds.")
            $k=0
    EndSwitch
WEnd

There's around 30,000 lines of code, one 123 MB database file, some extremely convoluted benchmarking junk, and around 80 different versions of the code I made this thread for, all of it ugly, except for MrCreators.

Also, an abortive experiment in saving the information in an array as a file for quick $myArrayVariable = FileRead(array.data)

Anyway, fun stuff and thanks for all the help!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0