2009-07-19 10 views
13

私は、デッキの内容をリストし、そのデッキをシャッフルする回数を質問し、それらをシャッフルするプロジェクトのコードを書こうとしています。 System.Randomクラスを使用して2つのランダムな整数を作成するメソッドを使用する必要があります。カードのシャッフルC#

これらは私のクラスです:

のProgram.cs:

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Deck mydeck = new Deck(); 
      foreach (Card c in mydeck.Cards) 
      { 
       Console.WriteLine(c); 
      } 
      Console.WriteLine("How Many Times Do You Want To Shuffle?"); 

     } 
    } 
} 

Deck.cs:

namespace ConsoleApplication1 
{ 
    class Deck 
    {  
     Card[] cards = new Card[52]; 
     string[] numbers = new string[] { "2", "3", "4", "5", "6", "7", "8", "9", "J", "Q", "K" }; 
     public Deck() 
     { 
      int i = 0; 
      foreach(string s in numbers) 
      { 
       cards[i] = new Card(Suits.Clubs, s); 
       i++; 

      } 
      foreach (string s in numbers) 
      { 
       cards[i] = new Card(Suits.Spades, s); 
       i++; 

      } 
      foreach (string s in numbers) 
      { 
       cards[i] = new Card(Suits.Hearts, s); 
       i++; 

      } 
      foreach (string s in numbers) 
      { 
       cards[i] = new Card(Suits.Diamonds, s); 
       i++; 

      } 
     } 

     public Card[] Cards 
     { 
      get 
      { 
       return cards; 


      } 
     } 
    } 
} 

Enums.cs:

namespace ConsoleApplication1 
{   
    enum Suits 
    { 
     Hearts, 
     Diamonds, 
     Spades, 
     Clubs 
    } 
} 

Card.cs:

namespace ConsoleApplication1 
{ 
    class Card 
    { 
     protected Suits suit; 
     protected string cardvalue; 
     public Card() 
     { 
     } 
     public Card(Suits suit2, string cardvalue2) 
     { 
      suit = suit2; 
      cardvalue = cardvalue2; 
     } 
     public override string ToString() 
     { 
      return string.Format("{0} of {1}", cardvalue, suit); 
     } 
    } 
} 

カードのシャッフルを自分の望むだけにして、シャッフルしたカードをリストする方法を教えてください。

+0

はあなたのための書式を修正しました。 –

+2

宿題のようなもののための標準的な質問...何を試しましたか? –

+2

ちょうど興味がありません、どのようにあなたはスーツの列挙型を使用していますが、カードランクでもありませんか? – Kirschstein

答えて

14

カードのデッキをシャッフルすることは、最初は些細なことですが、通常はほとんどの人が思い付くアルゴリズムが間違っています。

http://www.codinghorror.com/blog/archives/001008.html

http://www.codinghorror.com/blog/archives/001015.html

+0

これは私が探しているものではありません。私が使用しているコードを使ってカードをシャッフルする方法を教えてくれる人を探しています –

+6

コードを書く人を探しているのですか? (これが課題であると仮定すると、あなたが自分で書くと、あなたはクラスをより多く得ることができます。割り当てを行わないと、通常はテストに失敗します) – NoMoreZealots

41

使用Fisher-Yates shuffle(特に二つ目は必読です):

ジェフ・アトウッド(Coding Horror)は、件名にいくつかの非常に良い記事を書きました。

あなたのC#のコードは次のようになります。

static public class FisherYates 
{ 
    static Random r = new Random(); 
    // Based on Java code from wikipedia: 
    // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle 
    static public void Shuffle(int[] deck) 
    { 
     for (int n = deck.Length - 1; n > 0; --n) 
     { 
      int k = r.Next(n+1); 
      int temp = deck[n]; 
      deck[n] = deck[k]; 
      deck[k] = temp; 
     } 
    } 
} 
+1

FisherYates?うーん、私はそれの名前があったのか分からなかった。私が最初に実装したのはBasicの8ビットAtariでした!私は8年生だったと思う。 – NoMoreZealots

+0

Deck.csクラスで使用すると、これらのエラーが発生します Deckと言われているすべての場所(はい、私のコードと一致するように大文字にしました)には、 '型'と表示されていますが、 '変数'として使用されています。 Deck.Lengthと言うと、私のアプリケーションに 'length'の定義がありません。 –

+1

クラス名に一致するように変数名 'deck'を大文字にするべきではありません。そうすれば、変数をクラスと混同するので、エラーが発生します。 その他は何をするか、あなたに言った: - カードを扱う配列 からトップINTを削除して - - 整数は シャッフル - カードは文字列として表現されている[0..51]までの 52個の整数の配列を作成します整数値をカード+スーツに変換することによって 幸運。 – hughdbrown

5

私は、これはあなたがあまりにも抽象化に巻き込まれるケースだと思います。

ソフトウェアでカードのデッキをシャッフルすることは、ランダムな順序でデッキをユーザーに提供することです。これは、実際にあなたがそれらをシャッフルする必要はありません。

あなたのデッキを起動します。 (私は、典型的には、カードを表し、mathmaticallyあるカード計算するために1から52まで番号を使用する。)

  1. フィットネスエクササイズカードのデッキからカードを選択するために乱数発生器を使用してカードを扱っています。
  2. デッキの最後のカードと交換してください。
  3. デッキの末尾を指すカウンタをデクリメントして、そのカードをデッキから取り外します。
  4. カードを作成するまでステップ1に進みます。

編集:そして、あなたは良い乱数ジェネレータの何も、それを複数回「シャッフル」により得られません持っている場合は、一般的に言えば。

これは、表示されたデータ構造を使用して行う必要があります。デッキの終わりを追跡するために、 "Draw"メソッドとメンバ変数を追加するだけです。あなたが実際に "シャッフル"を実際に実行しているのであれば、あなたの教授は変態者です。Bカードを52枚引くと、デッキはシャッフルされます。すべてのカードを作ったら、「DeckEmpty」メソッドを提供し、すべてのカードを再度組み込むためにDeck Endをリセットする必要があります。

-1

シャッフルは、このように動作するはずです:

あなたはデッキ(デッキ内のカードの指数乱数である)2枚のカードの とスワップ位置に2枚のランダムカードを取ります。 たとえば、インデックス2のカードを、インデックス9のカードを取り出し、場所を変更します。

これは、特定の回数繰り返すことができます。

アルゴリズムは次のようになります。

int firstNum = rnd.Next(52); 
int secondNum = rnd.Next(52); 

Card tempCard = MyCards[firstNum]; 
MyCards[firstNum] = MyCards[secondNum]; 
MyCards[secondNum] = tempCard; 
+1

これは公正なシャッフルを実行しません。 – dkarp

+0

なぜでしょうか? rnd.Next関数が1から52の間の完全にランダムな値を与えると仮定します。 – Rohit

+0

「十分にランダム」になるにはどれくらいの時間をシャッフルする必要がありますか? –

2

あなたのシャッフルはうまくいくかもしれないが、それは本当に効率的かつリアルなではないではありません。あなたはこの方法を試してみてください:

//The shuffle goes like this: you take a portion of the deck, then put them in random places 
private void Shuffle() 
{ 
int length = DeckofCards.Count; 
int level = 20; //number of shuffle iterations 

List<Card> Shuffleing; //the part of the deck were putting back 
Random rnd = new Random(); 
int PickedCount, BackPortion; //the last used random number 

for (int _i = 0; _i < level; _i++) 
{ 
    PickedCount = rnd.Next(10, 30); //number of cards we pick out 
    Shuffleing = DeckofCards.GetRange(0, PickedCount); 
    DeckofCards.RemoveRange(0, PickedCount); 

    while (Shuffleing.Count != 0) 
    { 
    PickedCount = rnd.Next(10, DeckofCards.Count - 1); //where we place a range of cards 
    BackPortion = rnd.Next(1, Shuffleing.Count/3 + 1); //the number of cards we but back in one step 
    DeckofCards.InsertRange(PickedCount, Shuffleing.GetRange(0, BackPortion)); //instering a range of cards 
    Shuffleing.RemoveRange(0, BackPortion); //we remove what we just placed back 
    } 
} 
} 

あなたはcorreclyあなたは種子がわずか2^32で、ランダムクラスを使用する必要がありますだけでなく、デッキをシャッフルするために以下の反復

3

でよりリアルなシャッフルを得る可能性があります。この方法これは、あなたの無作為のオブジェクトが、あなたが52のところに2^32(仮定した)異なる順序を与えることができることを意味します!現実のデッキをアグリゲーションする(階乗52)方法。

私は、ランダムなデータの32バイトを作成するために、2のGUIDを使用しています - 私は、5 [カードの一定数を取得シードによって、その後

を4バイトの> 8シードと私はthoses 8つの異なる種で カードをシャッフルここ5,6,6,6,7,8,9]

私は

public void Shuffle(Guid guid1, Guid guid2) 
    { 
     int[] cardsToGet = new int[] { 5, 5, 6, 6, 6, 7, 8, 9 }; 
     byte[] b1 = guid1.ToByteArray(); 
     byte[] b2 = guid2.ToByteArray(); 

     byte[] all = new byte[b1.Length + b2.Length]; 
     Array.Copy(b1, all, b1.Length); 
     Array.Copy(b2, 0, all, b1.Length, b2.Length); 

     List<Card> cards = new List<Card>(this); 
     Clear(); 

     for (int c = 0; c < cardsToGet.Length; c++) 
     { 
      int seed = BitConverter.ToInt32(all, c * 4); 
      Random random = new Random(seed); 
      for (int d = 0; d < cardsToGet[c]; d++) 
      { 
       int index = random.Next(cards.Count); 
       Add(cards[index]); 
       cards.RemoveAt(index); 
      } 
     } 
    } 
+0

暗号クラスが擬似乱数ジェネレータを解決するでしょうか? – ppumkin

+0

_ "あなたのランダムなオブジェクトは、あなたに2^32(想定)の異なる順序を与えることができます" _実際には、負のシードが決して使用されないので、実際より悪いです。負のシードをコンストラクタに渡すと、絶対値が使用されます。だからあなたは「ただ」2^31の可能な配列を持っています。それでも、私は、ほとんどの目的のために、20億の可能な配列がたくさんあるので、「悪い」と「唯一の」を引用符で囲みます。 –

-1

を使用するコードは、全体的に私は、カードオブジェクトの配列を含むオブジェクトとして各デッキを見て言うと思いますです各Cardオブジェクトには値とスイートintプロパティが含まれています。これはapplie dを値とスイートの列挙型に変換して、使用しているデッキのタイプごとに名前付きバージョンを集めます。 (これにより、このコードはより汎用性があり、値の比較が容易になります3 < 11(jack)!〜)あなたのスタイルは学校のプロジェクトで効果があります。

その後、あなたがしたいデッキの種類にそれを継承する、あなたは基本デッキクラスを使用することを想定している
class Card 
{ 
    public int value 
    { get; set; } 

    public int suite 
    { get; set; } 
} 


abstract class Deck 
{ 
    public Card[] cards 
    { get; set; } 

    public void ShuffleCards(int timesToShuffle) 
    { 
     Card temp; 
     Random random = new Random(); 
     // int timesToShuffle = random.Next(300, 600); #Had it setup for random shuffle 
     int cardToShuffle1, cardToShuffle2; 

     for (int x = 0; x < timesToShuffle; x++) 
     { 
      cardToShuffle1 = random.Next(this.cards.Length); 
      cardToShuffle2 = random.Next(this.cards.Length); 
      temp = this.cards[cardToShuffle1]; 

      this.cards[cardToShuffle1] = this.cards[cardToShuffle2]; 
      this.cards[cardToShuffle2] = temp; 
     } 
    } 
} 

(あなたは宇野デッキや、これまで何にこの同じコードを適用することができるようにそれを作る。)コードノーマルタイプ用デッキクラスの

class NormalDeck : Deck 
{ 
    // This would go in the NormalGame class to apply the enumerators to the values as a cipher. 
    // Need int values for logic reasons (easier to work with numbers than J or K !!! 
    // Also allows for most other methods to work with other deck<Type> (ex: Uno, Go Fish, Normal cards) 
    public enum Suites 
    { 
     Hearts, 
     Diamonds, 
     Spades, 
     Clover 
    }; 

    // Same comment as above. 
    public enum Values 
    { Ace, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King }; 

    public void NewNormalDeck() 
    { 
     // Clear the deck of cards 
     if (this.cards != null) 
     { 
      Array.Clear(this.cards, 0, this.cards.Length); 
     } 

     //Set Value to length of Normal deck of Cards without Jokers 
     cards = new Card[52]; 

     // to keep count of which card we are. 
     int curNumofCards = 0; 

     // Cycle through all of the suites listed in "suites" then all the values of  that suite 
     for (int x = 0; x < Enum.GetValues(typeof(Suites)).GetLength(0); x++) 
     { 
      for (int y = 0; y < Enum.GetValues(typeof(Values)).GetLength(0); y++) 
      { 
       Card newCard = new Card(); 
       newCard.suite = x; 
       newCard.value = y; 
       this.cards[curNumofCards] = newCard; 
       curNumofCards++; 
      } 
     } 
    } 
} 
-1

私は7枚のカードを含むプログラムを作った後、シャッフルして助けてもらいたいと思います。

クラスプログラム {

static void Main(string[] args) 
{ 
    Random random = new Random(); 
    var cards = new List<string>(); 
    //CARDS VECRTOR 
    String[] listas = new String[] { "Card 1", "Card 2", "Card 3", "Card 4", "Card 5", "Card 6", "Card 7"}; 


    for (int i = 0; i<= cards.Count; i++) 
    { 

     int number = random.Next(0, 7); //Random number 0--->7 


     for (int j = 0; j <=6; j++) 
     { 
      if (cards.Contains(listas[number])) // NO REPEAT SHUFFLE 
      { 

       number = random.Next(0, 7); //AGAIN RANDOM 

      } 
      else 
      { 
       cards.Add(listas[number]); //ADD CARD 
      } 
     } 

    } 

    Console.WriteLine(" LIST CARDS"); 

    foreach (var card in cards) 
    { 
     Console.Write(card + " ,"); 


    } 

    Console.WriteLine("Total Cards: "+cards.Count); 

    //REMOVE 

    for (int k = 0; k <=6; k++) 
    { 
     // salmons.RemoveAt(k); 
     Console.WriteLine("I take the card: "+cards.ElementAt(k)); 
     cards.RemoveAt(k); //REMOVE CARD 
     cards.Insert(k,"Card Taken"); //REPLACE INDEX 
     foreach (var card in cards) 
     { 
      Console.Write(card + " " + "\n"); 

     } 


    } 


    Console.Read(); //just pause 

} 

}