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 :D
Landern, i really hope that you will answer almost after 5 years, but do u know if the Code files from your 1st link supposed to be in one, huge, single file? Thanks, AiRiBeX.
Answer by EmHuynh · Mar 08, 2016 at 11:20 PM
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 );
}
}
}
Hey, i Known that it has been almost 5 years but, do you set the implementation and the 1st code as spererate codes?
Answer by jgodfrey · Mar 08, 2016 at 08:10 PM
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.
Honestly, I thought of doing that, but I thought I read somewhere that you couldn't remove things from an array (as you mention to be the "smarter" way of doing point three of yours.) Is that possible?
I looked into Lists but that went a bit over my head (granted, I didn't look too far into it, I'm trying to keep it simple.)