# Question about "shuffling" a deck of cards

I’m completely new to coding and this is my very first game. In the game, I have a deck of forty cards that contains four types of cards, ten of each type. I came up with this method of drawing a card at random and since I’m new, and am just trying to “brute force” it for the sake of learning.

``````string cardDraw ()
{
int generatedNumber = Random.Range (1, maxCards);

if (generatedNumber >= 1 && generatedNumber <= cardamt1)
{
drawnCard = "Card 1";
cardamt1--;
}
else if (generatedNumber > cardamt1 && generatedNumber <= cardamt1 + cardamt2)
{
drawnCard = "Card 2";
cardamt2--;
}
else if (generatedNumber > cardamt1 + cardamt2 && generatedNumber <= cardamt1 + cardamt2 + cardamt3)
{
drawnCard = "Card 3";
cardamt3--;
}
else if (generatedNumber > cardamt1 + cardamt2 + cardamt3 && generatedNumber <= cardamt1 + cardamt2 + cardamt3 + cardamt4)
{
drawnCard = "Card 4";
cardamt4--;
}

Debug.Log(cardamt1);
Debug.Log(cardamt2);
Debug.Log(cardamt3);
Debug.Log(cardamt4);
return drawnCard;
}
``````

I’ve read several thing about different shuffling algorithms like the Yates … something or other, and I was just wondering if there was any negative to doing it this way? From what I can tell, it should be random and the chance of drawing a certain type of card gets lower with every one that’s drawn.

P.S. If there’s a more concise way of doing this, feel free to chime in with that as well

Hello, @UncannyCloud. We can create a struct/class to define a card and a class to define the Deck, which contains an array/list of cards. The class should have a function to shuffle the cards.

Here is a working example:

``````using System.Collections;
using System.Collections.Generic;

[ System.Serializable ]
public struct Card {
public enum Type { Type1 = 0, Type2, Type3, Type4 } // 4 types.
public Type type; // For defining the card's type.
};

[ System.Serializable ]
public class Deck
{
public List< Card > cards; // List of cards/

public Deck() { cards = new List< Card >(); } // Default constructor to initialize the list.

// Method to create 10 cards of each type.
public void Generate()
{
Card newCard = new Card();

for( int i = 0; i != 4; i ++ ) {
newCard.type = ( Card.Type )i;
for( int j = 0; j != 10; j ++, this.cards.Add( newCard ) );
}
}

// Method to shuffle a Deck using Fisher-Yates shuffle.
public static void Shuffle( Deck deck )
{
System.Random random = new System.Random();

for( int i = 0; i < deck.cards.Count; i ++ ) {
int j = random.Next( i, deck.cards.Count );
Card temporary = deck.cards[ i ];
deck.cards[ i ] = deck.cards[ j ];
deck.cards[ j ] = temporary;
}
}
};
``````

Here is the implementation:

``````public class Example: MonoBehaviour {
public Deck myDeck;

void Start () {
myDeck = new Deck();
myDeck.Generate();
}

// Update is called once per frame
void Update () {
if( Input.GetKey( KeyCode.Space ) ) {
Deck.Shuffle( myDeck );
}
}
}
``````

Why not simply…

• Store the cards in a 40-element array
• Randomly select x numbers in the range of 0-39
• If you choose a number that’s already been chosen, choose again
• Once you have chosen x unique numbers, use them to access the cards at those indices.

Depending on our needs, you could be smarter about step #3 above. For instance, you could remove chosen cards from the array as they are chosen, and then only choose from the remainder each time.

Without more details, it’s hard to suggest much more. However, I’d say your current method is much more complex than necessary.