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 ObjectByVal As System.EventArgs) Handles Me.Load
        unshuffledDeck 
= New List(Of Card)
        
For suitCounter As Integer = To 3
            
For cardCounter As Integer = 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 = To deck.Count - 1
            
nextCard deck(cardCounter)
            carddisplay.Append(
"<td>" & nextCard.GetCardInColor & "</td>")

            
If (cardCounter Mod 13 12And (cardCounter > 1And (cardCounter < deck.Count - 1Then
                
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 ObjectByVal 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 = 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 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 < 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 As Integer = To shuffleArraySize - 1
            
shuffledDeck.Add(Nothing)
        
Next

        For 
cardCounter 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 As Integer = To shuffleArraySize - 1
            
shuffledDeck.Add(Nothing)
        
Next

        For 
cardCounter 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 As Integer = 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 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 As Integer = 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