使用随机数选择一个列表中的项目并将其移动到另一个列表

我正在设计一款名为Snap的卡片游戏(Heres一个链接显示规则http://boardgames.about.com/od/cardgames/a/snap.htm ),在我的版本中,播放器将不得不点击中间,如果一对出现。 我目前有4个class级,一个用于卡片(一个名为cardValue_的int),一个用于玩家手牌,一个用于原始牌组,一个用于中间牌。 所以Deck,Pile和Hand课程中都有一张卡片列表。 我现在正在尝试为Deck类编写一个shuffle方法,其中包含一个Cards列表。 这将挑选一张随机卡并将其移至新列表,直到所有卡被挑选,然后将它们移回原始列表,从而进行简单的随机播放。 到目前为止我的方法看起来像这样……

public List Shuffle(List cardDeck) { int index = 0; Random randomCard = new Random(); List newDeck = new List(); while (index < cardDeck.Count) { int ran = randomCard.Next(0, cardDeck.Count); foreach (Card card in cardDeck) { } } } 

我想弄清楚在foreach循环中应该去做什么(除非整个方法都错了),但现在我想我已经在错误的地方宣布了我的所有卡片,所有52张卡片当前都在表格中声明,或者应该我要在甲板课上宣布他们?

你在哪里接近我将如何解决它,我会做的是随机复制出源列表,直到它是空的,然后只需重新填充它。 您不需要返回列表,因为这只会改变您传入的列表。

 //Move this out of the function, if you are wondering why search SO for "Not random" and choose any of the 100's of people asking "why is random not random?" :) private static Random randomCard = new Random(); //Not thread safe, if multi-threading use locks!!! public static void Shuffle(List cardDeck) { int index = 0; List tempDeck = new List(); while (cardDeck.Count > 0) { int removal = randomCard.Next(0, cardDeck.Count); Card tempCard = cardDeck[removal]; cardDeck.RemoveAt(removal); tempDeck.Add(tempCard); } //cardDeck is empty at this point, now we refill it with our randomized deck. cardDeck.AddRange(tempDeck); } 

如果您不想修改原始列表,并且确实需要新的随机列表,请先复制源列表。

 public static List Shuffle(List cardDeck) { int index = 0; List tempDeck = new List(); List localCopy = new List(cardDeck); //Creates a shallow copy of the list. while (localCopy.Count > 0) { int removal = randomCard.Next(0, cardDeck.Count); Card tempCard = localCopy[removal]; localCopy.RemoveAt(removal); tempDeck.Add(tempCard); } return tempDeck; } 

我建议使用Richard的方法 。 它简单得多。

阅读Jeff的博客,了解所有细节。

 public List Shuffle(List cards) { return new List(cards) .OrderBy(a => Guid.NewGuid()); } 

更新

斯科特建议Guid可能不够随意,Crypto RNG会更好。 所以使用BigInteger因为它实现了IComparable,我们得到:

 RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); public List Shuffle(List cards) { var r = new byte[32]; return new List(cards) .OrderBy(a => new BigInteger(rng.GetBytes(r)); }