# Deck of Cards

## Recommended Posts

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).

edit: fixed broken artifacts from forum upgrades

Edited by spudw2k

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

Work fine. Now wait a poker game. >_

When the words fail... music speaks

##### Share on other sites

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."

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

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 on other sites

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

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

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.

```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."

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

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 on other sites

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?

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

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."

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

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 on other sites

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 on other sites

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

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

```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

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

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

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

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 on other sites

Look at BlackJack

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

##### Share on other sites

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()
\$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
For \$value = 2 To 7
Next
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 on other sites

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.

Edited by spudw2k

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

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

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

...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 on other sites

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

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

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 on other sites

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

edit: Moved code to latest post.

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

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

## Create an account

Register a new account

×

• Wiki

• Back

• Git