Sign in to follow this  
Followers 0

Deck of Cards

34 posts in this topic

#1 ·  Posted (edited)

?do=embed' frameborder='0' data-embedContent>

Was bored so I started this script to be a starting basis for a card game. My shuffle code doesn't work as well as I had hoped. any community suggestions on how to improve?

#include <Array.au3>
$newdeck = _ShuffleDeck(_InitializeDeck())

While 1
    $newhand = _DrawCards($newdeck,5)
    _ArrayDisplay($newhand,"Five Cards Drawn")
WEnd

Func _InitializeDeck()
    Dim $deck[52]
    $card = 1
    $suit = 0
    For $x = 0 to 51
        $deck[$x] = $card & "|" & $suit
        $suit += 1
        If $suit >= 4 Then
            $suit = 0
            $card += 1
        EndIf
    Next
    Return $deck
EndFunc

Func _ShuffleDeck($deck,$degree = 1024)
    SRandom(Random(1,64))
    For $x = 1 to $degree
        _ArraySwap($deck[Random(0,51,1)],$deck[Random(0,51,1)])
    Next
    Return $deck
EndFunc

Func _DrawCards(ByRef $deck,$count)
    If Ubound($deck) <= $count Then $deck = _ShuffleDeck(_InitializeDeck())
    Dim $cards[$count]
    For $i = 0 to $count-1
        $cards[$i] = $deck[UBound($deck)-1]
        _ArrayPop($deck)
    Next
    Return $cards
EndFunc

Func _CutDeck($deck,$count=0)
    If $count <= 0 Or $count >= 51 Then $count = Random(13,39,1)
    For $i = 1 to $count
        _ArrayPush($deck,$deck[51],1)
    Next
    Return $deck
EndFunc

I tried increase the $degree and stacking the shuffle func

_ShuffleDeck(_ShuffleDeck(_InitializeDeck()))
but it doesn't seem to have a great effect.

Adding SRandom(Random(0,64)) to the first line of the shuffle func improves it. *added to code.

I removed the card value translation. Now the card value is accurate and the suit is zero-base indexed. That way I can still do actual calculation against the values. I'll translate the values to faces in the game (when one's made).

?do=embed' frameborder='0' data-embedContent>

Edited by spudw2k

Share this post


Link to post
Share on other sites



#2 ·  Posted

Work fine. Now wait a poker game. :) >_


When the words fail... music speaks

Share this post


Link to post
Share on other sites

#3 ·  Posted

You look at the code in my script?

Texas Holdem Trainer


 

All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

Windows_error.gif

 

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

You look at the code in my script?

Texas Holdem Trainer

I'm having difficulty finding a "deck" in your script. It appears to just select random cards from what I see.

Very nice looking script though. :)

Edited by spudw2k

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I'm having difficulty finding a "deck" in your script. It appears to just select random cards from what I see.

The hundred number is the suit and the number that follows is the card 124 would be A of spades 112 is the 2 of spades - they match with the gif file of the card file name.

edit added the following function

Func _NewCard() ; taken from another program on texas holdem - credit Rizzet
    Local $Card, $Card1, $Card2
    Do
        $Card1 = Random(1, 4, 1) * 100
        $Card2 = Random(12, 24, 1)
        $Card = $Card1 + $Card2
        _ArraySearch($iCard, $Card)
        For $i = 1 To 5
            If @error = $i Then
                MsgBox(1, "error", "error = " & $i)
                ExitLoop
            EndIf
        Next
    Until @error = 6
    If $TESTING Then
        Return 112
    EndIf
    Return $Card
EndFunc   ;==>_NewCard
Edited by nitekram

 

All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

Windows_error.gif

 

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Share this post


Link to post
Share on other sites

#6 ·  Posted

Yes, I understand the whole picture thing. Let me rephrase. From what I can tell, you are picking random cards and putting them in an array rather than starting with an entire deck of cards and drawing from it. Is that correct?

Share this post


Link to post
Share on other sites

#7 ·  Posted

Yes, I understand the whole picture thing. Let me rephrase. From what I can tell, you are picking random cards and putting them in an array rather than starting with an entire deck of cards and drawing from it. Is that correct?

I reread your code and now I understand your question. You are creating a deck of cards and then using a shuffle funtion and then drawing the cards from there to create your array. I never thought of doing it that way, and I wonder if you get the same type of randomness with my way - yours seem better, may I try and use the same idea for my script?

I of course am doing what you thought. Creating an array from random numbers to create my dealt cards.


 

All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

Windows_error.gif

 

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Share this post


Link to post
Share on other sites

#8 ·  Posted

Here's what I thought of for my own card type game I thought of:

Func _ShuffleDeck($deck)    
    For $x = 0 To 50 ; Not To 51, as Random(51, 51, 1) would give an error
        $select = Random($x, 51, 1)
        $temp = $deck[$select]
        $deck[$select] = $deck[$x]
        $deck[$x] = $temp
    Next
    For $x = 51 To 1 Step -1 ; Not To 0, as Random(0, 0, 1) would give an error (it'd be 0, which is what we want, but it's still an error)
        $select = Random(0,$x,1)
        $temp = $deck[$select]
        $deck[$select] = $deck[$x]
        $deck[$x] = $temp
    Next
    Return $deck
EndFunc

Worked pretty well for my tastes, see how you like it.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Worked pretty well for my tastes, see how you like it.

That's pretty good. Thanks for the input. I adapted your method to mine.

Func _ShuffleDeck($deck)
    SRandom(Random(1,128))
    For $x = 0 to 50
        _ArraySwap($deck[Random($x,51,1)],$deck[Random(0,51-$x,1)])
    Next
    Return $deck
EndFunc
Edited by spudw2k

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

*Another Function Added. _CutDeck.

Func _CutDeck($deck,$count=0)
    If $count <= 0 Or $count >= 51 Then $count = Random(13,39,1)
    For $i = 1 to $count
        _ArrayPush($deck,$deck[51],1)
    Next
    Return $deck
EndFunc

I'm rethinking the _InitializeDeck function. Ideally i'd like these basic functions to be able to work with any game that uses standard playing cards. As such, not all games use a complete deck and some games use multiple decks. I'll post when I get something laid out.

Edited by spudw2k

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

edit: Latest code on POST #20

Updated code. Here's all the latest code. I also changed the _InitializeDeck() func so I can build decks that are not "standard" (52 cards).

I also adjusted the _DrawCards Func to draw from the top of the deck, not the bottom (_ArrayReverse). and Made the shuffle so it is dynamic based on the deck.

edit: Fixed shuffle method based on SkinnyWhiteGuy's recommendations.

edit: Latest code on POST #20

Edited by spudw2k

Share this post


Link to post
Share on other sites

#12 ·  Posted

Not to burst your bubble, but I did the _ShuffleDeck() function the way I did for a reason. By picking 2 random numbers to be swapped, you end up with more cards left in the same position as before, unshuffled/untouched, whereas if you pick a card at random, move it to the end/beginning, and do it again for the remaining cards, you end up with a more randomized deck. In my tests, after shuffling once, your method resulted in around 16% of the cards staying exactly where they were before being shuffled, while the method I show above only results in around 1%. Now, not knowing how realistic you want the card simulations being, I just thought you'd like to know this information.

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

I needed to make a similar code for my bot.

Here is a simple code, It will create a deck with 40 cards, Shuffle, and the deal them 1 by 1 without using the same card twice.

#include <Array.au3>

Global $cards[41] ; 0 Will store the index
_Init_cards()
_ArrayDisplay($cards, "New Deck")
_Shuffle_Deck()
_ArrayDisplay($cards, "Shuffled")
For $x = 1 To 40
    ConsoleWrite(@CRLF & "Deal card #: " & $x & "  " & _deal_card())
Next

Func _Shuffle_Deck()
    Local $Sec_Deck[41], $dice ;The sec_deck is used to shuffle and reshuffle, and the $dice will be a random card
    $Sec_Deck[0] = $cards[0]
    For $i = 1 To 40
        If $cards[0] > 1 Then
            $Dice = Random(1, $cards[0], 1) ; Random a dice
        Else
            $Dice = 1
        EndIf
        $Sec_Deck[$i] = $cards[$dice] ; Attrib a random card to the second array
        For $Swap = $Dice To $cards[0]-1 ;+ 1
            $cards[$Swap] = $cards[$Swap + 1] ; array swap
        Next
        $cards[0] -= 1
    Next
    ;_ArrayDisplay($Sec_Deck,"sec")
    ;now do the same from sec_deck to original deck
    $cards[0] = 0
    For $i = 1 To 40
        If $Sec_Deck[0] > 1 Then
            $Dice = Random(1, $Sec_Deck[0], 1) ; Random a dice
        Else
            $Dice = 1
        EndIf
        $cards[$i] = $Sec_Deck[$dice] ; Attrib a random card to the second array
        For $Swap = $Dice To $Sec_Deck[0]-1 ;+ 1
            $Sec_Deck[$Swap] = $Sec_Deck[$Swap + 1] ; array swap
        Next
        $Sec_Deck[0] -= 1
        $cards[0] +=1 
    Next
EndFunc

Func _deal_card()
    If $cards[0] < 1 Then 
        Return "No cards left"
    Else
        $cards[0] -= 1
        Return $cards[$cards[0]+1]
    EndIf
EndFunc
Func _Init_cards()
    Local $add = 1, $Deck
    $cards[0] = 40
    For $_temp = 0 To 3
        If $_temp = 0 Then $Deck = " s";Spades
        If $_temp = 1 Then $Deck = " h";Hearts
        If $_temp = 2 Then $Deck = " c";Clubs
        If $_temp = 3 Then $Deck = " d";diamonds
        $cards[$add] = "A" & $Deck
        $add += 1
        For $value = 2 To 7
            $cards[$add] = $value & $Deck
            $add += 1
        Next
        $cards[$add] = "J" & $Deck
        $add += 1
        $cards[$add] = "Q" & $Deck
        $add += 1
        $cards[$add] = "K" & $Deck
        $add += 1
    Next
EndFunc   ;==>_Init_cards
Edited by Linux

You can help! Donate to AutoIt! or, visit ClimatePREDICTION.netMy posts:Travian Bot Example (100+ servers) BETAHow to Host you code/app for free! (unlimited team number) (Public or Private)"Sir, we're surrounded!" "Excellent. We can attack in any direction!"

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Look at BlackJack

There is used standard Windows cards.dll for drawing of cards.

Very cool, and useful. I'll prob stick to a no dll scenario if possible....although since this is only for Windows, they (user) should have the card.dll. :)

I needed to make a similar code for my bot.

Here is a simple code, .....

Pretty interesting.

Not to burst your bubble, but I did the _ShuffleDeck() function the way I did for a reason. By picking 2 random numbers to be swapped, you end up with more cards left in the same position as before, unshuffled/untouched, whereas if you pick a card at random, move it to the end/beginning, and do it again for the remaining cards, you end up with a more randomized deck. In my tests, after shuffling once, your method resulted in around 16% of the cards staying exactly where they were before being shuffled, while the method I show above only results in around 1%. Now, not knowing how realistic you want the card simulations being, I just thought you'd like to know this information.

Very useful. I'll do some tests. No bubble to burst friend. I never claimed this to be great code. Just fun. >_<

thanks SKW. I changed the shuffle after comparing the shuffles. Your method works better and I now see why. Thanks. :idiot:

Edited by spudw2k

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

I've thought of the next set of functions to write.

_PlayCards()

_Deal()

_SortHand()

edit: I removed the SplitDeck func. I can just deal the deck instead.

edit: Removed Discard func. Same thing as PlayCards essentially.

...There is an edit button and you can reply to several posts in one...

noted. Edited by spudw2k

Share this post


Link to post
Share on other sites

#17 ·  Posted

...There is an edit button and you can reply to several posts in one...


[quote name='PsaltyDS' post='635433' date='Jan 27 2009, 07:04 AM']Larry is a mass murderer?! It's always the quiet, clean cut, bald guys... [/quote]

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

SkinnyWhiteGuy

Any idea why running the shuffle func on a deck that has been shuffled doesn't seem to do anything? Maybe how I'm testing is wrong.

edit: Doh! I figured it out. It was returnng the same array twice. Duh. :) Thanks for checking it out.

Edited by spudw2k

Share this post


Link to post
Share on other sites

#19 ·  Posted

Works fine for me, the two decks (pre and post shuffle) are randomized pretty well. What are you seeing, that they stay the same?

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

Latest Code edit: removed AddToHand and CombineDecks. Can just use _ArrayConcatenate()

edit: Moved code to latest post.

Func _AddToHand($hand,$cards)

Return _ArrayConcatenate($hand,$cards)

EndFunc

Func _CombineDecks($deck1,$deck2)

Return _ArrayConcatenate($deck1,$deck2)

EndFunc

edit: The shuffle func still isn't the best. I find that deck repeats shuffle patterns. I increase the range of the Ransom Seed which helps but still doesn't prevent duplicate shuffle patterns.

edit: I was looking at nitekram's Texas Holdem Trainer script after a recent update and I noticed that he left a comment in his code reffering to some deck methods I just happen to have created here; also remembering him mention implementing it, I decided to give it a go. I only had to make two slightly-significant (How's that for an oxymoron) changes.

  • Change card structure to meet requirements of nitekram's script. (suit then face, no ~)
  • Alter his _NewCard function to Return _DrawCard instead
Otherwise, just the declare a Global var for the Deck and Customize the deck as appropriate. Edited by spudw2k

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