Mischiare la carta in C #

Sto cercando di scrivere un codice per un progetto che elenca il contenuto di un mazzo di carte, chiede quante volte la persona vuole mescolare il mazzo e poi mescolarle. Deve usare un metodo per creare due numeri interi casuali usando la class System.Random.

Queste sono le mie classi:

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

Per favore dimmi come fare a mescolare le carte tanto quanto la persona vuole e quindi elencare le carte mescolate.

Usa la mescolanza di Fisher-Yates .

Il tuo codice C # dovrebbe assomigliare a questo:

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

Mischiare un mazzo di carte è qualcosa che all’inizio sembra banale, ma di solito l’algoritmo che la maggior parte delle persone crea non è corretto.

Jeff Atwood ( Coding Horror ) ha scritto alcuni ottimi articoli sull’argomento:

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

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

(in particolare la seconda è una lettura obbligata)

Penso che questo sia un caso in cui potresti essere troppo preso dall’astrazione.

Mischiare un mazzo di carte nel software è una questione di fornire il mazzo all’utente in un ordine casuale. Questo in realtà non richiede di rimescolarli prima del tempo.

Inizia il tuo mazzo. (Di solito uso un numero da 1 a 52 per rappresentare la carta e calcolare matematicamente quale carta è.)

  1. Distribuisci una carta usando un generatore di numeri casuali per prelevare una carta dal mazzo delle carte disponibili.
  2. Scambia quella carta con quella alla fine del mazzo.
  3. Decrementa un segnalino che punta verso la fine del mazzo, per rimuovere quella carta dal mazzo.
  4. Vai al passaggio 1 fino a quando non hai finito di disegnare le carte.

Edit : E in generale, se si dispone di un buon generatore di numeri casuali non si ottiene nulla con “Shuffling” più volte.

Questo dovrebbe essere ansible usando le strutture di dati che hai mostrato. Devi solo aggiungere un metodo “Disegna” e una variabile membro per tenere traccia della fine del mazzo. Se sei deciso a eseguire lo “shuffle” in anticipo, allora un tuo professore è un idiota, B ogni volta che peschi 52 carte il mazzo sarà mescolato. Una volta pescate tutte le carte, è necessario fornire un metodo “DeckEmpty” e un metodo per reimpostare la Fine del Deck per includere di nuovo tutte le carte.

per rimescolare correttamente un mazzo non si dovrebbe usare SOLO la class Random, il seme è solo 2 ^ 32, il che significa che il tuo object Random può darti solo 2 ^ 32 (supposto) ordine diverso dove c’è 52! (fattoriale 52) modo di mettere in discussione un mazzo di vita reale.

sto usando 2 guid per creare 32 byte di dati casuali -> 8 semi di 4 byte e mescolo le carte con 8 semi differenti

poi per seme ottengo un certo numero di carte [5,5,6,6,6,7,8,9]

ecco il codice che uso

  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 cards = new List(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); } } } 

Il tuo Shuffle potrebbe funzionare, ma non è veramente efficiente e non realistico. Dovresti provare in questo modo:

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

In questo modo potresti ottenere una riproduzione più realistica con meno iterazioni

Il mischiare dovrebbe funzionare in questo modo:

Prendi due carte a caso nel mazzo (l’indice della carta nel mazzo è il numero casuale) e scambia le posizioni delle due carte. Ad esempio, prendi la carta nell’indice 2 e la carta nell’indice 9 e falli cambiare posto.

E ciò può essere ripetuto un certo numero di volte.

L’algoritmo dovrebbe assomigliare a questo:

 int firstNum = rnd.Next(52); int secondNum = rnd.Next(52); Card tempCard = MyCards[firstNum]; MyCards[firstNum] = MyCards[secondNum]; MyCards[secondNum] = tempCard; 

In generale, direi guardare ogni mazzo come un object che contiene una serie di oggetti Card, che ogni object Card contiene ciascuno un valore e una proprietà int suite, che può essere applicato a un Enum di valori e suite per raccogliere la versione nominata come per il tipo di mazzo che stai utilizzando. (Ciò consentirebbe a questo bit di codice di essere più versatile e consentire confronti più facili dei valori 3 <11 ​​(jack)! ~) Il tuo stile funzionerà per un progetto scolastico, sto solo ottenendo OCD con esso!

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

Questo presuppone che tu abbia usato una class Base Deck, quindi la erediti dal tipo di mazzo che vuoi (facendolo così puoi applicare lo stesso codice ai deck Uno o quant'altro.) Codice per il tipo normale di class del mazzo.

 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 (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++; } } } } 

Ho creato un programma che contiene 7 carte, poi mischia e spero di poterlo aiutare per aiutarle.

programma di class {

 static void Main(string[] args) { Random random = new Random(); var cards = new List(); //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 } 

}

 static void Shuffle(List cards) { Console.WriteLine(""); Console.WriteLine("Shuffling"); Console.WriteLine("---------"); cards = cards.OrderBy(x => Guid.NewGuid()).ToList(); foreach (var card in cards) { Console.WriteLine(card.ToString()); } }