Tarjeta barajando en C #

Intento escribir un código para un proyecto que enumera el contenido de una baraja de cartas, pregunta cuántas veces la persona quiere barajar la baraja y luego las baraja. Tiene que usar un método para crear dos enteros aleatorios usando la clase System.Random.

Estas son mis clases:

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

Por favor dígame cómo hacer que las cartas se mezclen tanto como la persona quiera y luego enumere las cartas barajadas.

Use la mezcla de Fisher-Yates .

Su código C # debería verse más o menos así:

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

Mezclar una baraja de cartas es algo que parece trivial al principio, pero por lo general el algoritmo que la mayoría de la gente presenta es incorrecto.

Jeff Atwood ( Coding Horror ) escribió algunos muy buenos artículos sobre el tema:

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

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

(especialmente el segundo es una lectura obligada)

Creo que este es un caso en el que puedes estar demasiado atrapado en la abstracción.

Mezclar un mazo de cartas en el software es una cuestión de proporcionar el mazo al usuario en un orden aleatorio. En realidad, esto no requiere que barajes antes de tiempo.

Inicia tu mazo. (Por lo general, uso un número del 1 al 52 para representar la carta y calcular matemáticamente qué carta es).

  1. Reparte una carta usando un generador de números aleatorios para elegir una carta de la baraja de cartas disponibles.
  2. Cambia esa carta con la que está al final del mazo.
  3. Disminuya un contador que apunta al extremo de la baraja, para quitar esa carta de la baraja.
  4. Vaya al paso 1 hasta que termine de dibujar las cartas.

Editar : Y en términos generales, si tiene un buen generador de números aleatorios, no se gana nada “Mezcándolo” varias veces.

Esto debería ser posible usando las estructuras de datos que ha mostrado. Solo necesita agregar un método “Dibujar” y una variable miembro para realizar un seguimiento del final del mazo. Si estás empeñado en realizar el “shuffle” antes de tiempo, entonces A tu profesor es un idiota, B cada vez que saques 52 cartas, se barajará el mazo. Una vez que haya dibujado todas las cartas, debe proporcionar un método “DeckEmpty” y un método para restablecer End of Deck para incluir nuevamente todas las cartas.

para correlacionar aleatoriamente una baraja, NO deberías utilizar SOLAMENTE la clase Aleatoria, la semilla es solo 2 ^ 32 lo que significa que tu objeto Random puede darte solo 2 ^ 32 (supuesto) orden diferente donde hay 52! (factorial 52) forma de agendar un mazo de la vida real.

Estoy usando 2 guid para crear 32bytes de datos aleatorios -> 8 semillas de 4bytes y mezclo las cartas con esas 8 semillas diferentes

luego, por semilla, obtengo una cierta cantidad de cartas [5,5,6,6,6,7,8,9]

aquí está el código que 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); } } } 

Su Shuffle podría funcionar, pero no es realmente eficiente y no es realista. Deberías intentarlo de esta manera:

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

De esta forma, es posible que obtenga una mezcla más realista con menos iteraciones

La mezcla debería funcionar de esta manera:

Tomas dos cartas aleatorias en el mazo (el índice de la carta en el mazo son los números aleatorios) Y intercambias posiciones de las dos cartas. Por ejemplo, tome la tarjeta en el índice 2 y la tarjeta en el índice 9 y haga que cambien de lugar.

Y eso se puede repetir una cierta cantidad de veces.

El algoritmo debería verse más o menos así:

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

En general, diría que mire cada mazo como un objeto que contiene una matriz de objetos de Tarjeta, cada uno de los cuales contiene un valor y una propiedad suite int, que se puede aplicar a un Enum de valores y suites para reunir la versión nombrada como por el tipo de cubierta que estás usando. (Esto permitiría que este pedacito de código sea más versátil y permita comparaciones de valores más fáciles 3 <11 ​​(jack)! ~) Tu estilo funcionará para un proyecto escolar, ¡solo estoy obteniendo TOC con él!

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

Eso supone que utilizaste una clase de Deck base, y luego la heredaste al tipo de mazo que deseas (lo que hace que puedas aplicar este mismo código a Decks o lo que sea). Código para el tipo normal de clase de mazo.

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

Hice un progtwig que contiene 7 cartas, luego baraja y espero aprovechar para ayudarlos.

Progtwig de clase {

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