3

私はスナップと呼ばれるカードゲームを設計しています(ここにルールを示すリンクがありますhttp://boardgames.about.com/od/cardgames/a/snap.htm)、私のバージョンでは、プレーヤーはの山をクリックする必要がありますペアが表示された場合は真ん中。私は現在4つのクラスを持っています。1つはカード(cardValue_と呼ばれるint)、1つはプレイヤーの手、1つは元のカードのデッキ、もう1つは真ん中のカードの山です。したがって、デッキ、パイル、ハンドのクラスには、カードのリストが含まれています。カードのリストを含むDeckクラスのシャッフルメソッドを作成しようとしています。これはランダムなカードを選び、すべてのカードが選ばれるまでそれを新しいリストに移動し、次にそれらを元のリストに戻し、単純なシャッフルを行います。これまでの私の方法は次のようになります...

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枚のカードすべてが現在フォームで宣言されているか、またはすべきであると考えています私はデッキクラスでそれらを宣言していますか?

4

2 に答える 2

2

私がそれを解決する方法にかなり近いところで、私がすることは、ソースリストが空になるまでランダムにコピーしてから、それを補充することです。渡したリストをシャッフルするだけなので、リストを返す必要はありません。

//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;
}

リチャードの方法を使用することをお勧めします。それははるかに簡単です。

于 2013-02-08T04:58:38.770 に答える
2

詳細については、シャッフルに関するJeffのブログをご覧ください。

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

アップデート

スコットは、Guidが十分にランダムではない可能性があり、CryptoRNGの方が優れていると示唆しました。したがって、IComparableを実装しているためBigIntegerを使用すると、次のようになります。

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));
}
于 2013-02-08T05:15:38.673 に答える