# Deck of Cards

## Recommended Posts

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

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

While 1
\$newhand = _DrawCards(\$newdeck,5)
_ArrayDisplay(\$newhand,"Five Cards Drawn")
If _ArraySearch(\$newhand,"12~3") <> -1 Then ExitLoop
WEnd

Exit

Func _InitializeDeck(\$faces=0,\$suits=0,\$decks=1)
If Not IsArray(\$faces) Then Dim \$faces[13]=[1,2,3,4,5,6,7,8,9,10,11,12,13]
If Not IsArray(\$suits) Then Dim \$suits[4]=[0,1,2,3]
Dim \$deck[4]
Dim \$suit = 0
Dim \$card = 0
For \$i = 1 to \$decks
For \$x = 0 To UBound(\$faces)-1
ReDim \$deck[\$card+4]
Do
\$deck[\$card] = \$suits[\$suit] & \$faces[\$x]
\$card += 1
\$suit +=1
Until \$suit >= 4
\$suit = 0
Next
Next
Return \$deck
EndFunc

Func _ShuffleDeck(\$deck)
SRandom(Random(0,10))
For \$x = 0 To 50
_ArraySwap(\$deck[Random(\$x,51,1)],\$deck[\$x])
Next
For \$x = 51 To 1 Step -1
_ArraySwap(\$deck[Random(0,\$x,1)],\$deck[\$x])
Next
Return \$deck
EndFunc

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

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

Func _PlayCards(ByRef \$hand,\$cards)
Dim \$played[UBound(\$cards)]
For \$i = 0 To UBound(\$played)-1
\$card = _ArraySearch(\$hand,\$cards[\$i])
\$played[\$i] = \$hand[\$card]
_ArrayDelete(\$hand,\$card)
Next
Return \$played
ëk ¨Æ­zv­{Múuç\$×Múuç\$ØIÝéÜþËkGv+HÁ«%¢"­+^¶¦ßÛ.®```

do you see where 012 = 12? or 013 = 13 ect...

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

I think the prob is with the creation of the deck. Notice how when the _DrawCards() func is caled the first line recreates the deck if not enough cards are in it. The default _InitializeDeck does not match your card naming scheme.

Edited by spudw2k

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

I like your code. It's inspiring.

LoL @ the 'cut deck' function though

Edited by doodydota

##### Share on other sites

I think the prob is with the creation of the deck. Notice how when the _DrawCards() func is caled the first line recreates the deck if not enough cards are in it. The default _InitializeDeck does not match your card naming scheme.

I think I found the issue - your code only deals the card but does not shuffle after each deal? So after the 52 cards are dealt out the cards reinialize and then the potential for double cards. Does that fit your tests?

Let me know what you find.

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

I think I found the issue - your code only deals the card but does not shuffle after each deal? So after the 52 cards are dealt out the cards reinialize and then the potential for double cards. Does that fit your tests?

Let me know what you find.

Yeah, i'm not too sure what doubles you are finding. Each time the deck is "initialized" it starts from scratch and I've never seen the deck creation process produce doubles.

```\$deck = _NewDeck()
_ArrayDisplay(\$deck)

Func _NewDeck()
Dim \$faces[13]=[12,13,14,15,16,17,18,19,20,21,22,23,24]
Dim \$suits[4]=[1,2,3,4]
Return _CutDeck(_ShuffleDeck(_InitializeDeck(\$faces,\$suits)))
EndFunc```

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

Yeah, i'm not too sure what doubles you are finding. Each time the deck is "initialized" it starts from scratch and I've never seen the deck creation process produce doubles.

```\$deck = _NewDeck()
_ArrayDisplay(\$deck)

Func _NewDeck()
Dim \$faces[13]=[12,13,14,15,16,17,18,19,20,21,22,23,24]
Dim \$suits[4]=[1,2,3,4]
Return _CutDeck(_ShuffleDeck(_InitializeDeck(\$faces,\$suits)))
EndFunc```
Here test my code - newest version 2.6 - I left the array displays in place - each time you press the deal it should start the deck over.

So to test - press deal then clear, then deal and clear, then deal and clear, the third time you should see the array display again, before all the cards have been dealt. Let me know what you think. I am also thinking that each card has been dealt 1 time only as if the cards had never been shuffled.

EDIT

I found the same with your code - if you run yours 10 times you will not get a dupe card, but once you start the 11th time you will get 3 dupes. I think what the issue is, is the deck is not getting shuffled after each deal.

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

EDIT

I found the same with your code - if you run yours 10 times you will not get a dupe card, but once you start the 11th time you will get 3 dupes. I think what the issue is, is the deck is not getting shuffled after each deal.

I reread my first edit and it makes no sense - in your code you deal 5 cards, if you continue to deal out 5 cards you will never see the same card twice until the 11th time you deal the cards. That should be impossible as the same card should have a chance of showing up on the very next deal - your code deals one card one time and never deals it again until all the cards have been dealt one time. I hope that I have explained it better, if not let me know.

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

I think I know what you mean: you are trying to simulate having 2 decks together in one large deck, but the way the code is now, it's like using 2 decks separately, where you won't see the 2nd deck till all cards are dealt from the first deck.

Easiest solution: initialize a bigger deck, with 2 copies of everything. Or 3, or however many you want. The deal code deals all cars from a deck before creating a brand new deck, and dealing from it. So, by creating a bigger deck to start with, that will do what your looking for it to do.

##### Share on other sites

the third var in the Init func is how many decks to create (in one deck)

`_InitializeDeck(\$faces,\$suits,2)`

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

the third var in the Init func is how many decks to create (in one deck)

`_InitializeDeck(\$faces,\$suits,2)`
I am not sure I quite understand, but I changed the third var to 2 and found that there was really no random hands, a lot of the times there was 4 cards of the same suite over and over again. Do you see the same thing?

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

What do you think of such a code to deal?

```#include <Array.au3>
global \$set[1]
for \$i=1 to 52
Next
;_ArrayDisplay(\$set,"")

for \$i=1 to 52
\$j=int(random(\$i-1,52))
\$prev=\$set[\$j]
for \$k=\$j to 1+\$i Step -1
\$set[\$k]=\$set[\$k-1]
Next
\$set[\$i]=\$prev
Next
_ArrayDisplay(\$set,"")```

It operates a simple permutation over [1..52]. You have no more to do than give a correspondance between [1..52] and the cards.

I don't know if it is really uniformly random but I imagine it is if random is uniform over (min..max).

Regards

##### Share on other sites

What do you think of such a code to deal?

You mean shuffle right? It seems random enough, but for some reason this method creates doubles. Can you confirm?

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

Yes you are right, the code is wrong.

Line 9 should be \$j=Int(random(\$i-1,52))+1 because int truncates (we need an integer between 1 and 52).

That way it seems to be OK with no double.

##### Share on other sites

Yes you are right, the code is wrong.

Line 9 should be \$j=Int(random(\$i-1,52))+1 because int truncates (we need an integer between 1 and 52).

That way it seems to be OK with no double.

Cool, looks better. It seemed to be about a efficient as the current shuffle, so I combined the two methods and updated the code.

```#include <Array.au3>
Global \$faces[13]=["Ace","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Jack","Queen","King"]

\$newdeck = _ShuffleDeck(_InitializeDeck(\$faces,\$suits))
_ArrayDisplay(\$newdeck)

\$newdeck = _CutDeck(\$newdeck)
\$hand = _DrawCards(\$newdeck,5)
_ArrayDisplay(\$hand)

Exit

Func _InitializeDeck(\$faces=0,\$suits=0,\$decks=1)
If Not IsArray(\$faces) Then Dim \$faces[13]=[1,2,3,4,5,6,7,8,9,10,11,12,13]
If Not IsArray(\$suits) Then Dim \$suits[4]=[0,1,2,3]
Dim \$deck[4]
Dim \$suit = 0
Dim \$card = 0
For \$i = 1 to \$decks
For \$x = 0 To UBound(\$faces)-1
ReDim \$deck[\$card+4]
Do
\$deck[\$card] = \$faces[\$x] & " of " & \$suits[\$suit] ;Should be tailored to your formatting needs,
\$card += 1
\$suit +=1
Until \$suit >= 4
\$suit = 0
Next
Next
Return \$deck
EndFunc

Func _ShuffleDeck(\$deck)
SRandom(Random(0,1024))
For \$x = 0 To 50
_ArraySwap(\$deck[Random(\$x,51,1)],\$deck[\$x])
Next
SRandom(Random(0,1024))
For \$x = 51 To 1 Step -1
_ArraySwap(\$deck[Random(0,\$x,1)],\$deck[\$x])
Next
SRandom(Random(0,1024))
For \$i=0 To 51
\$j=Int(Random(\$i,51))+1
\$prev=\$deck[\$j]
For \$k=\$j To 1+\$i Step -1
\$deck[\$k]=\$deck[\$k-1]
Next
\$deck[\$i]=\$prev
Next
Return \$deck
EndFunc

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

Func _DrawCards(ByRef \$deck,\$count)
If Ubound(\$deck) < \$count Then \$deck = _CutDeck(_ShuffleDeck(_InitializeDeck(\$faces,\$suits))) ;Don't forget to tailor Initilize to meet your formatting scheme
_ArrayReverse(\$deck)
Dim \$cards[\$count]
For \$i = 0 to \$count-1
\$cards[\$i] = \$deck[UBound(\$deck)-1]
_ArrayPop(\$deck)
Next
_ArrayReverse(\$deck)
Return \$cards
EndFunc

Func _PlayCards(ByRef \$hand,\$cards)
Dim \$played[UBound(\$cards)]
For \$i = 0 To UBound(\$played)-1
\$card = _ArraySearch(\$hand,\$cards[\$i])
\$played[\$i] = \$hand[\$card]
_ArrayDelete(\$hand,\$card)
Next
Return \$played
EndFunc```
Edited by spudw2k

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

## Create an account

Register a new account