Sign in to follow this  
Followers 0
spudw2k

Deck of Cards

34 posts in this topic

#21 ·  Posted (edited)

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
EndFuncoÝ÷ ÚËkGºwuÔè©ÝÓ~¡jwtߧ­ÛzÛ«
ëk ¨Æ­zv­{Mú©ÝÓ~j·lwEºwºw¢fâàÞrK4ߧ^rMtߧ^rMzÛ«
ë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."

From my dad

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

 

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



#22 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

#23 ·  Posted (edited)

I like your code. It's inspiring.

LoL @ the 'cut deck' function though :)

Edited by doodydota

Share this post


Link to post
Share on other sites

#24 ·  Posted

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

From my dad

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

 

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

#25 ·  Posted

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

Share this post


Link to post
Share on other sites

#26 ·  Posted (edited)

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

From my dad

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

 

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

#27 ·  Posted

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

From my dad

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

 

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

#28 ·  Posted

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 this post


Link to post
Share on other sites

#29 ·  Posted

Share this post


Link to post
Share on other sites

#30 ·  Posted

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

From my dad

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

 

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

#31 ·  Posted

What do you think of such a code to deal?

#include <Array.au3>
global $set[1]
for $i=1 to 52 
    _ArrayAdd($set,$i);
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 this post


Link to post
Share on other sites

#32 ·  Posted

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?

Share this post


Link to post
Share on other sites

#33 ·  Posted

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 this post


Link to post
Share on other sites

#34 ·  Posted (edited)

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"]
Global $suits[4]=["Spades","Hearts","Clubs","Diamonds"]

$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

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