洗牌不同的甲板为两者提供相同的牌组?

时间:2017-06-11 17:26:37

标签: c# .net

我在Deck类中有这种改组方法:

public Card[] deck = new Card[DECK_AMOUNT];
public void shuffleCards()
{
    Random randInt = new Random();

    for (int i = 0; i < 52; i++)
    {
        int firstCard = i;
        int secondCard = randInt.Next(0, 51);

        int tempFirstCard = firstCard;

        deck[i] = deck[secondCard];
        deck[secondCard] = deck[i];

    }
}

当我制作这些属性时:

private Deck computerCards;
private Deck playerCards;

并使用这些方法

private void shuffleDecks(){
 computerCards.shuffleCards();
 playerCards.shuffleCards();
}

他们在相同位置都有相同的牌。为什么会发生这种情况?如何解决?

如果我要做的话

private void shuffleDecks(){
 computerCards.shuffleCards();
 playerCards.shuffleCards();
 playerCards.shuffleCards();
}

它们都不同。

2 个答案:

答案 0 :(得分:2)

从手册:

  

默认种子值源自系统时钟并具有有限的分辨率。因此,通过调用默认构造函数紧密连续创建的不同Random对象将具有相同的默认种子值,因此将生成相同的随机数集。使用单个Random对象生成所有随机数可以避免此问题。您还可以通过修改系统时钟返回的种子值,然后将此新种子值显式提供给Random(Int32)构造函数来解决此问题。有关更多信息,请参阅Random(Int32)构造函数。

答案 1 :(得分:1)

您的交换算法错误

override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

让我们举一个具体的例子,让我们打两张牌deck[i] = deck[secondCard]; // Now deck[i] and deck[secondCard] have the same value (i.e. card). deck[secondCard] = deck[i]; // This doesn't change anything since both are the same now. A

B

// Initialize the example deck[i] = A; deck[secondCard] = B; // Now start swapping deck[i] = deck[secondCard]; // Here deck[i] is B and deck[secondCard] is B. // We lost card A! 的旧值保存到临时变量:

deck[i]

您的语句Card temp = deck[i]; // Now temp is A deck[i] = deck[secondCard]; // Now deck[i] is B deck[secondCard] = temp; // Now deck[secondCard] is A 仅保存索引,而不是此索引处的卡片。

命名可以促进清晰度。它们可以命名为int tempFirstCard = firstCard;,而不是命名索引somethingCard。但是,由于哪个是第一个或第二个并不重要,因此可以简单地命名为somethingIndexi。在数学中为索引使用这些名称是很常见的。