C# 为什么洗牌两个不同的牌组会产生相同的结果?

C# 为什么洗牌两个不同的牌组会产生相同的结果?,c#,random,shuffle,C#,Random,Shuffle,首先我在这里上甲板课。我刚刚介绍了一些基本方法,用于测试目的。这是我第一次尝试创建卡片程序 public class Deck { private int deckCounter = 0; private List<Card> deckSize = new List<Card>(); private List<Card> shuffledDeck = new List<Card>(); private Ran

首先我在这里上甲板课。我刚刚介绍了一些基本方法,用于测试目的。这是我第一次尝试创建卡片程序

    public class Deck
{
    private int deckCounter = 0;
    private List<Card> deckSize = new List<Card>();
    private List<Card> shuffledDeck = new List<Card>();
    private Random random = new Random();

    public Deck()
    {
    }

    public void Build()
    {
        for (int i = 1; i < 5; i++)
        {
            for (int k = 1; k < 14; k++)
            {
                deckSize.Add(new Card(k.ToString(), i));
            }
        }
    }

    public void Add(Card card)
    {
        deckSize.Add(card);
        deckCounter++;
    }

    public Card RemoveCard()
    {
            Card cardToRemove = deckSize.First();
            deckSize.RemoveAt(0);
            return cardToRemove;
    }

    public void ShowContainedCards()
    {
        int cardCount = 0;
        foreach (Card c in deckSize)
        {
            Console.WriteLine(c.ReturnCardInfo());
            cardCount++;
        }
        Console.WriteLine(cardCount);
    }

    public void Shuffle()
    {
        while (deckSize.Count != 0)
        {
            int i = random.Next(deckSize.Count);
            shuffledDeck.Add(deckSize[i]);

            deckSize.RemoveAt(i);
        }
        deckSize = shuffledDeck;
    }

    public bool IsEmpty()
    {
        if (deckSize.Any())
        {
            return false;
        }
        else return true;
    }

    public List<Card> GetCardList()
    {
        return deckSize;
    }
}
在那之后,我得到了完全相同的洗牌,对于deck1和deck2。为什么呢?另外,如果你不知道的话,我是个新手:

在两个甲板实例中使用相同的随机类实例:

Random random = new Random();
Deck deck1 = new Deck(random);
Deck deck2 = new Deck(random);
因此,在构造函数中:

public class Deck
{
    private int deckCounter = 0;
    private List<Card> deckSize = new List<Card>();
    private List<Card> shuffledDeck = new List<Card>();
    private Random random;

    public Deck(Random random)
    {
        this.random = random;
    }
代码当前的问题是,创建的两个Random实例的种子相同。这使它们产生相同的结果。使用相同的随机实例意味着第二次洗牌将建立在第一次洗牌的种子结果之上。

来自:

默认种子值源自系统时钟,具有有限分辨率。因此,通过调用默认构造函数连续创建的不同随机对象将具有相同的默认种子值,因此将生成相同的随机数集

这些文件还提出了一个解决方案:

通过使用单个随机对象生成所有随机数,可以避免此问题

因此,一种可能的解决方案是将随机生成器设置为静态,以便所有甲板实例共享相同的随机实例:

private static Random random = new Random();
这样,您甚至可以避免更改Deck类的公共接口的任何部分。

计算机本身不是随机的,因此任何随机数生成器实际上都将使用算法生成看起来随机的输出。这件事的关键是总有一个起点,如果你知道起点在哪里,你就可以预测结果。因此,随机数生成器有一个种子,告诉它从哪里开始。同一种子总是会给出相同的随机数序列

这两次,您都在使用newrandom,它使用默认种子。在某些语言中,建议您将当前时间作为种子传递,但C会为您这样做。然而,如果你在一起创建两个随机对象,它们很可能得到相同的时间,这就是这里发生的事情


如果将随机数设为静态,那么所有随机数都将来自同一个源,因此两个组将获得连续的随机数,而不是并行的相同随机数。

它说:通过调用默认构造函数连续创建的不同随机对象将具有相同的默认种子值,因此,将生成相同的随机数集。作为旁注,请参见,这是一个合适的洗牌算法。关闭是因为基本问题是相同的,现有的问题很好地解释了它。您的洗牌例程也不是很安全-我会使shuffledDeck成为一个局部变量,而不是一个字段,并始终使用shuffle中的新列表初始化它。目前,您不能以正常的方式调用Shuffle两次,因为在第一次调用之后,deckSize和shuffledDeck引用同一个列表。这解决了我的问题!非常感谢你的解释,我很感激!
private static Random random = new Random();