在Visual Basic中洗牌?

时间:2017-10-23 03:30:07

标签: vb.net list random

这是我的来源:

Public Class Deck

    Dim deckList As New List(Of Card)

    Sub ShuffleDeck()
        'creates a new deck to copy to, a list of random numbers, and a randomizer object to make random number in a range
        Dim tempDeck As New List(Of Card)
        Dim listOfRandomNumbers As New List(Of Integer)
        Dim randomizer As New Random
        Dim randomNumber As Integer

        'this generates a random number then adds it to the list of random numbers if there is no others already like it in the list of random numbers
        Do While (listOfRandomNumbers.Count() < 52)

            randomNumber = randomizer.Next(0, 51)

            If listOfRandomNumbers.Contains(randomNumber) = False Then
                listOfRandomNumbers.Add(randomNumber)
            End If

        Loop

        Dim index As Integer
        Do While (index < 51)
            'this adds a card to the tempDeck at a random index of the deck list
            tempDeck.Add(deckList(listOfRandomNumbers(index)))
            index = index + 1
        Loop

        'assigning the deck from the ordered one to the shuffled one
        deckList = tempDeck

    End Sub

End Class

我正在尝试洗牌一副牌,但是当我试图让我的listOfRandomNumbers包含不重复的唯一值时,我会陷入无限循环。

Do While (listOfRandomNumbers.Count() < 52)

     randomNumber = randomizer.Next(0, 51)

     If listOfRandomNumbers.Contains(randomNumber) = False Then
          listOfRandomNumbers.Add(randomNumber)
     End If

Loop

对此有何想法?

4 个答案:

答案 0 :(得分:1)

在我看来,最简单的选择是这样的:

Private ReadOnly randomizer As New Random

Private Sub SuffleDeck()
    Dim values = deckList.ToArray()
    Dim keys = values.Select(Function(value) randomizer.NextDouble()).ToArray()

    Array.Sort(values, keys)

    deckList.Clear()
    deckList.AddRange(values)
End Sub

请注意,Random变量是成员。

答案 1 :(得分:1)

您的代码存在的问题是,对randomizer.Next(0, 51)的调用会产生从050的数字。如果您希望包含51,则需要使用randomizer.Next(0, 52)进行调用。

实际应该是:

randomNumber = randomizer.Next(0, listOfRandomNumbers.Count())

总的来说,你最好这样做:

Dim randomizer As New Random

Sub ShuffleDeck()

    Dim listOfRandomNumbers = _
        Enumerable _
            .Range(0, 52) _
            .OrderBy(Function (x) randomizer.Next()) _
            .ToList()

答案 2 :(得分:1)

当我查看您的代码时,尝试并调试它。我将所有randomNumber放在listBox中以查看存储的整数 你的代码:

Do While (listOfRandomNumbers.Count() < 52)

    randomNumber = randomizer.Next(0, 51)

    If listOfRandomNumbers.Contains(randomNumber) = False Then
         listOfRandomNumbers.Add(randomNumber)
    End If

Loop

它不会停止循环,因为randomizer.Next(0, 51)包含0到50之间的数字。因此listOfRandomNumbers.Count()等于51

你有这一行:

If listOfRandomNumbers.Contains(randomNumber) = False Then

这会导致无限循环,因为数字0 - 50已经添加到listOfRandomNumbers(如randomizer.Next(0,51)中所声明的那样,因此它将始终返回true

使用randomNumber = randomizer.Next(0, 52)包含51 无限循环中的问题将得到解决。

答案 3 :(得分:0)

第一个循环创建了一副牌。

第二个循环从临时牌组中的可用牌中挑选一张随机牌,并在原始牌组中迭代并放置随机选择的牌。在该循环中,挑选的卡片将从临时套牌中移除。

要挑选的卡片的随机数在临时套牌中剩余的卡片数量范围内,因此您永远不会获得任何重复的选择,并且您只需要进行52次迭代

Sub ShuffleDeck()
    'creates a new deck to copy to, a list of random numbers, and a randomizer object to make random number in a range
    Dim tempDeck As New List(Of Card)
    Dim randNum As New Random
    For i As Integer = 0 To 51
        tempDeck.Add(deckList(i))
    Next

    For i As Integer = 0 To 51
        Dim randCardNum As Integer = randNum.Next(0, tempDeck.Count)
        deckList(i) = tempDeck(randCardNum)
        tempDeck.Remove(tempDeck(randCardNum))
    Next
End Sub