Visual basic 2008 - Do...While until infinite loop when shuffling 52 card deck

Visual basic 2008 - Do...While until infinite loop when shuffling 52 card deck

我开始用 VB2008 制作红心大战。目前我坚持交易:

 For q = 0 To 51
        Do
            Randomize()
            dealrand = Int(Rnd() * 51)
            cards(q).Image = pics(dealrand)
        Loop Until dealused(dealrand) = False
        dealused(dealrand) = True
    Next

我想做的是检查该卡是否已被使用并生成一张不同的卡,这样就不会有人得到同一张卡。

当我按下按钮时,程序崩溃了。我认为这是一个无限循环,因为当我将cards(q).Image = pics(dealrand)更改为cards(q).hide时,它隐藏了一张卡并崩溃了。

P.S:

我认为问题可能是您错过了 Rnd return 介于 0(含)和 1(不含)之间的值,这意味着当转换为整数时,它永远不会 return上限值。所以你需要将上限扩展到 52 以确保索引 #51 最终是 'found'.

您也可以通过在找到下一个空索引后仅分配第 q 张卡片来节省一些工作,我相信播种 Randomize 一次就足够了:

    Dim q As Integer
    Dim dealrand As Integer
    Dim dealused = Enumerable.Range(0, 52).Select(Function(x) False).ToArray
    Randomize()
    For q = 0 To 51
        Do
            dealrand = Int(Rnd() * 52)
        Loop Until dealused(dealrand) = False
        cards(q).Image = pics(dealrand)
        dealused(dealrand) = True
    Next

编辑

我相信洗牌例程可以在一个循环中完成,而无需尝试找到未使用的牌的命中或失败方法,方法是投射所有 52 张可用牌 (0..51),然后消除一旦从牌组中抽出一张随机牌,它们就会出现。它利用了 List 也有一个索引运算符这一事实。

    Dim dealrand As Integer
    Dim cardsAvailable = Enumerable.Range(0, 52).ToList()
    Dim q As Integer = 0
    Randomize()
    While (cardsAvailable.Any())
        dealrand = Int(Rnd() * cardsAvailable.Count)
        cards(q).Image = pics(cardsAvailable(dealrand))
        cardsAvailable.RemoveAt(dealrand)
        q = q + 1
    End While