"JC" <no************ @hotmail.com> wrote in message
news:bk******** **@sun-news.laserlink. net...
I want to shuffle a deck of 52 cards.
This is just for fun, since there has been some discussion about "really random"
and stuff.
This code does not attempt to be truly random; instead, it attempts to simulate
what happens when humans shuffle cards. That is, it splits the deck into two
piles, and then drops cards alternately from the two piles. The initial split is
26 +/- 4 in each pile, and each drop is between 1 to 4 cards. The PNorm function
returns more 1's than 4's, but by a crude mechanism, not a real distribution.
The interesting thing is how much order remains after just one shuffle. Don't
expect real randomization from just one shuffle of a deck!
Steve
---this is the form code for a form with a single button called cmdShuffle.
Option Explicit
Private mDeck(1 To 52) As Integer
Private mNewDeck(1 To 52) As Integer
Private mNewCards As Integer
Private Sub Form_Load()
Dim n As Integer
'open the new pack of cards
For n = 1 To 52
mDeck(n) = n
Debug.Print mDeck(n),
Next n
Debug.Print
'seed the random generator
Randomize Timer
End Sub
Private Sub cmdShuffle_Clic k()
Dim nLeftPile As Integer
Dim nRightPile As Integer
Dim nSplit As Integer
Dim n As Integer
'reset index
mNewCards = 0
'split into approximately two halves
nSplit = 24 + PNorm()
nLeftPile = nSplit
nRightPile = 52 - nLeftPile
'alternately drop some from each pile, till they are all gone
Do Until nLeftPile = 0 And nRightPile = 0
Call DropSome(nLeftP ile, 0)
Call DropSome(nRight Pile, nSplit)
Loop
'copy the new deck into the main deck
For n = 1 To 52
mDeck(n) = mNewDeck(n)
Debug.Print mDeck(n),
Next n
Debug.Print
End Sub
Private Sub DropSome(ByRef Pile As Integer, ByVal Offset As Integer)
Dim nDrop As Integer
Dim n As Integer
If Pile > 0 Then
'decide how many to drop from this pile
nDrop = PNorm()
If nDrop > Pile Then
nDrop = Pile
End If
'drop each card from the "pile" into the new deck
For n = 1 To nDrop
mNewCards = mNewCards + 1
mNewDeck(mNewCa rds) = mDeck(Offset + Pile)
Pile = Pile - 1
Next n
End If
End Sub
Private Function PNorm() As Integer
'a very pseudo normal random number - more like a triangle, actually...
Dim nNum As Integer
'random int from 0 to 9
nNum = CInt(Rnd * 10)
If nNum < 4 Then
'(0 to 3) average 40% of these
PNorm = 1
ElseIf nNum < 7 Then
'(4 to 6) average 30% of these
PNorm = 2
ElseIf nNum < 9 Then
'(7 to 8) average 20% of these
PNorm = 3
Else
'(9) average 10% of these
PNorm = 4
End If
End Function