使用随机数在一个列表中选择一个项目,然后将其移动到另一个列表

本文关键字:一个 列表 然后 移动 另一个 项目 随机数 选择 | 更新日期: 2023-09-27 17:58:21

我正在设计一款名为Snap的纸牌游戏(以下是显示规则的链接http://boardgames.about.com/od/cardgames/a/snap.htm),在我的版本中,如果出现一对,玩家必须点击中间的堆。我目前有4个类,一个用于卡片(这是一个名为cardValue_的int),一个为玩家手牌,一个针对原始牌组,一个面向在中间的牌堆。因此,甲板、桩和手类都有一个卡片列表。我现在正试图为Deck类编写一个shuffle方法,该类包含一个纸牌列表。它将随机选择一张牌,并将其移动到一个新的列表中,直到所有的牌都被选中,然后将它们移回原始列表,从而进行简单的洗牌。到目前为止,我的方法是这样的。。。

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

我正在努力计算foreach循环中应该包含什么(除非整个方法都是错误的),但现在我想我已经在错误的地方声明了我的所有卡,所有52张卡目前都在Form中声明,或者我应该在Deck类中声明它们?

使用随机数在一个列表中选择一个项目,然后将其移动到另一个列表

你知道我将如何解决它,我会做的是从源列表中随机复制出来,直到它为空,然后再重新填充。你不需要返回列表,因为这只会打乱你传入的列表。

//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<Card> cardDeck)
{
    int index = 0;
    List<Card> tempDeck = new List<Card>();
    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<Card> Shuffle(List<Card> cardDeck)
{
    int index = 0;
    List<Card> tempDeck = new List<Card>();
    List<Card> localCopy = new List<Card>(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关于shuffling的博客,了解所有细节。

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

更新

Scott建议Guid可能不够随机,加密RNG会更好。所以使用BigInteger,因为它实现了IComparable,我们得到:

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