Public Enum ShuffleType
ArrayChop
BigArray
RandomInsert
ArraySwap
End Enum
Private unshuffledDeck As List(Of Card)
Private cardDisplay, timerDisplay As StringBuilder
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
unshuffledDeck = New List(Of Card)
For suitCounter As Integer = 0 To 3
For cardCounter As Integer = 0 To 12
unshuffledDeck.Add(New Card(suitCounter, cardCounter))
Next
Next
End Sub
Protected Sub DisplayDeck(ByRef deck As List(Of Card), ByRef carddisplay As StringBuilder, ByVal label As String)
carddisplay.Append("<tr>")
carddisplay.Append("<td class='blank'>" & label & "</td>")
Dim nextCard As Card
For cardCounter As Integer = 0 To deck.Count - 1
nextCard = deck(cardCounter)
carddisplay.Append("<td>" & nextCard.GetCardInColor & "</td>")
If (cardCounter Mod 13 = 12) And (cardCounter > 1) And (cardCounter < deck.Count - 1) Then
carddisplay.Append("</tr><tr><td class='blank'> </td>")
End If
Next
carddisplay.Append("</tr>")
carddisplay.Append("<tr><td class='blank'></td></tr>")
End Sub
Public Sub Shuffle(ByVal sender As Object, ByVal e As EventArgs)
Dim buttonPressed As Button = CType(sender, Button)
Dim shuffleType As ShuffleType
Select Case buttonPressed.ID
Case "buttonShuffle1"
shuffleType = Global.Shuffle.ShuffleType.ArrayChop
Case "buttonShuffle2"
shuffleType = Global.Shuffle.ShuffleType.RandomInsert
Case "buttonShuffle3"
shuffleType = Global.Shuffle.ShuffleType.BigArray
Case "buttonShuffle4"
shuffleType = Global.Shuffle.ShuffleType.ArraySwap
Case Else
End Select
labelShuffleType.Text = Global.Shuffle.ShuffleType.BigArray.ToString()
cardDisplay = New StringBuilder()
timerDisplay = New StringBuilder()
cardDisplay.Append("<br/><table>")
DisplayDeck(unshuffledDeck, cardDisplay, "Unshuffled")
' Suggestion for writing a timer: http://msdn2.microsoft.com/en-us/library/ms998579.aspx
Dim myTimer As New QueryPerfCounter
Dim totalTime As Double = 0
myTimer.Start()
Dim shuffledDeck As List(Of Card)
For shuffleCounter As Integer = 0 To 4
If shuffleType = Global.Shuffle.ShuffleType.ArrayChop Then
shuffledDeck = Shuffle_ArrayChop(unshuffledDeck)
End If ' ArrayChop
If shuffleType = Global.Shuffle.ShuffleType.RandomInsert Then
shuffledDeck = Shuffle_RandomInsert(unshuffledDeck)
End If ' Random Insert
If shuffleType = Global.Shuffle.ShuffleType.BigArray Then
shuffledDeck = Shuffle_BigArray(unshuffledDeck)
End If ' Big Array
If shuffleType = Global.Shuffle.ShuffleType.ArraySwap Then
shuffledDeck = Shuffle_ArrayChop(unshuffledDeck)
End If ' ArraySwap
' Copy shuffled deck back to unshuffled deck so it can be
' shuffled again.
unshuffledDeck.Clear()
For Each o As Object In shuffledDeck
unshuffledDeck.Add(o)
Next
myTimer.Stop()
Dim result As Double = myTimer.Duration(1)
totalTime += result
timerDisplay.Append("<br/>Shuffle " & (shuffleCounter + 1).ToString() & ": " & result.ToString("F"))
DisplayDeck(shuffledDeck, cardDisplay, "Shuffle " & (shuffleCounter + 1).ToString())
If shuffleCounter < 4 Then
shuffledDeck.Clear()
End If
Next
cardDisplay.Append("</table>")
labelOutput.Text = cardDisplay.ToString()
timerDisplay.Append(String.Format("<br/><br/>Total time = {0:N}", totalTime))
labelTimings.Text = timerDisplay.ToString()
End Sub
Protected Function Shuffle_RandomInsert(ByVal unshuffledDeck As List(Of Card)) As List(Of Card)
Dim shuffleArraySize As Integer = unshuffledDeck.Count
Dim shuffledDeck As New List(Of Card)(shuffleArraySize)
Dim done As Boolean
Dim nextRandomNumber, cardCounter As Integer
Dim rnd As New Random(System.Environment.TickCount)
For i As Integer = 0 To shuffleArraySize - 1
shuffledDeck.Add(Nothing)
Next
For cardCounter = 0 To unshuffledDeck.Count - 1
done = False
While Not done
nextRandomNumber = rnd.Next(0, shuffleArraySize)
If shuffledDeck(nextRandomNumber) Is Nothing Then
shuffledDeck(nextRandomNumber) = unshuffledDeck(cardCounter)
done = True
End If
End While
Next
Return shuffledDeck
End Function
Protected Function Shuffle_BigArray(ByVal unshuffledDeck As List(Of Card)) As List(Of Card)
Dim shuffleArraySize As Integer = unshuffledDeck.Count * 5
Dim shuffledDeck As New List(Of Card)(shuffleArraySize)
Dim done As Boolean
Dim nextRandomNumber, cardCounter As Integer
Dim rnd As New Random(System.Environment.TickCount)
For i As Integer = 0 To shuffleArraySize - 1
shuffledDeck.Add(Nothing)
Next
For cardCounter = 0 To unshuffledDeck.Count - 1
done = False
While Not done
nextRandomNumber = rnd.Next(0, shuffleArraySize)
If shuffledDeck(nextRandomNumber) Is Nothing Then
shuffledDeck(nextRandomNumber) = unshuffledDeck(cardCounter)
done = True
End If
End While
Next
' Crunch down sparse shuffled array
Dim crunchedShuffledDeck As New List(Of Card)
For i As Integer = 0 To shuffledDeck.Count - 1
If Not shuffledDeck(i) Is Nothing Then
crunchedShuffledDeck.Add(shuffledDeck(i))
End If
Next
Return crunchedShuffledDeck
End Function
Protected Function Shuffle_ArrayChop(ByVal unshuffledDeck As List(Of Card)) As List(Of Card)
Dim shuffledDeck As New List(Of Card)
Dim done As Boolean
Dim nextRandomNumber As Integer
Dim rnd As New Random(System.Environment.TickCount)
done = False
While Not done
nextRandomNumber = rnd.Next(0, unshuffledDeck.Count)
shuffledDeck.Add(unshuffledDeck(nextRandomNumber))
unshuffledDeck.RemoveAt(nextRandomNumber)
If unshuffledDeck.Count = 0 Then
done = True
End If
End While
Return shuffledDeck
End Function
Protected Function Shuffle_ArraySwap(ByVal unshuffledDeck As List(Of Card)) As List(Of Card)
' This approach suggested by Julian (see http://mikepope.com/blog/AddComment.aspx?blogid=1851#1851_1859)
Dim nextRandomNumber As Integer
Dim rnd As New Random(System.Environment.TickCount)
Dim nextCard As Card
' Go through deck, swapping each card with a randomly selected card elsewhere in the deck.
For i As Integer = 0 To unshuffledDeck.Count - 1
nextRandomNumber = rnd.Next(0, unshuffledDeck.Count)
nextCard = unshuffledDeck(i)
unshuffledDeck(i) = unshuffledDeck(nextRandomNumber)
unshuffledDeck(nextRandomNumber) = nextCard
Next
Return unshuffledDeck
End Function
Colorized by: CarlosAg.CodeColorizer