Search code examples
c#imageclassfor-looppicturebox

C# card shuffle in card deck 52 cards


there is a project for Windows application that I'm still working on and is about a set of card deck. The application utilizes 52 cards which consist of 4 suits and 13 face values such as 2 of Clubs, Jack of Hearts, and so forth. The part that I'm working is that I also have to use five pictureboxes to display each random card so I click on a "Deal" button. I'm aware that I would have to use a "Random" keyword along with using a for-loop to do the shuffle.

Therefore, I'm not too sure how would I display each picturebox with different random cards and display each card's name accordingly.

Beneath of this contain screenshots of what the windows application looks like and my code for the project.

    List<PlayingCard> cardDeckList = new List<PlayingCard>();

    private void buttonDeal_Click(object sender, EventArgs e)
    {

        int integer = 0;
        Random picRandom = new Random();
        int n = 0;

        integer = picRandom.Next(0, imageListCards.Images.Count);

        for( n = 0; n < cardDeckList.Count; n++)
        {
            pictureBox_Card1.Image = cardDeckList[integer].CardImage;
            pictureBox_Card2.Image = cardDeckList[integer].CardImage;
            pictureBox_Card3.Image = cardDeckList[integer].CardImage;
            pictureBox_Card4.Image = cardDeckList[integer].CardImage;
            pictureBox_Card5.Image = cardDeckList[integer].CardImage;

        }

        listBoxOutput.Items.Add(cardDeckList[integer].ToString());

    }


    private void FormShuffleCardDeck_Load(object sender, EventArgs e)
    {
        try
        {

            string[] suitList = { "Clubs", "Diamonds", "Hearts", "Spades" };

            string[] faceList = new string[13];


            List<int> pointValues = new List<int>();

            pointValues.Add(2);
            pointValues.Add(3);
            pointValues.Add(4);
            pointValues.Add(5);
            pointValues.Add(6);
            pointValues.Add(7);
            pointValues.Add(8);
            pointValues.Add(9);
            pointValues.Add(10);
            pointValues.Add(10);
            pointValues.Add(11);

            string suit = "";
            string face = "";
            int counter = 0;
            int i = 0;
            int k = 0;

            for (i = 0; i < 4; i++)
            {
                suit = i.ToString();

                switch (suit)
                {
                    case "0":
                        suit = "Clubs";
                        break;

                    case "1":
                        suit = "Diamonds";
                        break;

                    case "2":
                        suit = "Hearts";
                        break;

                    case "3":
                        suit = "Spades";
                        break;
                }

                for (k = 0; k < 13; k++)
                {
                    face = k.ToString();

                    switch (k)
                    {
                        case 0:
                            face = "2";
                            break;

                        case 1:
                            face = "3";
                            break;

                        case 2:
                            face = "4";
                            break;

                        case 3:
                            face = "5";
                            break;

                        case 4:
                            face = "6";
                            break;

                        case 5:
                            face = "7";
                            break;

                        case 6:
                            face = "8";
                            break;

                        case 7:
                            face = "9";
                            break;

                        case 8:
                            face = "10";
                            break;

                        case 9:
                            face = "Ace";
                            break;

                        case 10:
                            face = "King";
                            break;

                        case 11:
                            face = "Jack";
                            break;

                        case 12:
                            face = "Queen";
                            break;
                    }


                    cardDeckList.Add(new PlayingCard(suit, face, imageListCards.Images[counter],2));
                    counter++;
                }


            }

            //for (int l = 0; l < cardDeckList.Count; l++)
            //{
            //    listBoxOutput.Items.Add(cardDeckList[l].ToString());
            //    //MessageBox.Show(cardDeckList.Count.ToString());              

            //}

        }



        catch(Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }

Windows App Program


Solution

  • I'm not sure how your PlayingCard class is coded, but it seems like a large portion of your problems stem from its design. Take this implementation for example:

    PlayingCard Class

    public class PlayingCard : IComparable<PlayingCard>
    {
        private int value;
        private int suit;
        private Bitmap cardImage;
    
        public int Value => value;
        public string ValueName => ValueToName(value);
    
        public int Suit => suit;
        public string SuitName => SuitToName(suit);
    
        public Bitmap CardImage => cardImage;
    
        public PlayingCard(int value, int suit, Bitmap cardImage)
        {
            this.value = value;
            this.suit = suit;
            this.cardImage = cardImage;
        }
    
        private string ValueToName(int n)
        {
            switch (n)
            {
                case 0:
                    return "Ace";
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                    return (n+1).ToString();
                case 10:
                    return "Jack";
                case 11:
                    return "Queen";
                case 12:
                    return "King";
                default:
                    throw new ArgumentException("Unrecognized card value.");
    
            }
        }
    
        private string SuitToName(int s)
        {
            switch (s)
            {
                case 0:
                    return "Clubs";
                case 1:
                    return "Diamonds";
                case 2:
                    return "Spades";
                case 3:
                    return "Hearts";
                default:
                    throw new ArgumentException("Unrecognized card suit");
            }
        }
    
        public int CompareTo(PlayingCard other)
        {
            int result = this.Suit.CompareTo(other.Suit);
    
            if (result != 0)
                return result;
    
            return this.Value.CompareTo(other.Value);
        }
    
        public override string ToString()
        {
            return String.Format("{0} of {1}", ValueName, SuitName);
        }
    }
    

    It has all the comparison and value conversion coded within it, so you don't have to worry about creating highly specialized methods to do extraneous conversions. You can use it in a deck like so:

    Array Implementation

    // How to initialize deck
    PlayingCard[] deck = Enumerable.Range(0, 52)
                            .Select(x => new PlayingCard(x % 13, x / 13, imageListCards[x]))
                            .ToArray();
    
    
    // How to shuffle deck
    Random r = new Random();
    Array.Sort(deck, (a, b) => r.Next(0, 2) == 0 ? -1 : 1);
    
    // How to reset deck
    Array.Sort(deck);
    
    // How to display top five cards
    pictureBox_Card1.Image = deck[0].CardImage;
    pictureBox_Card2.Image = deck[1].CardImage;
    pictureBox_Card3.Image = deck[2].CardImage;
    pictureBox_Card4.Image = deck[3].CardImage;
    pictureBox_Card5.Image = deck[4].CardImage;
    

    List Implementation

    // How to initialize deck
    List<PlayingCard> deck = Enumerable.Range(0, 52)
                            .Select(x => new PlayingCard(x % 13, x / 13, imageListCards[x]))
                            .ToList();
    
    
    // How to shuffle deck
    Random r = new Random();
    deck.Sort((a, b) => r.Next(0, 2) == 0 ? -1 : 1);
    
    // How to reset deck
    deck.Sort();
    
    // How to display top five cards
    pictureBox_Card1.Image = deck[0].CardImage;
    pictureBox_Card2.Image = deck[1].CardImage;
    pictureBox_Card3.Image = deck[2].CardImage;
    pictureBox_Card4.Image = deck[3].CardImage;
    pictureBox_Card5.Image = deck[4].CardImage;
    

    EDIT:

    Manual Shuffling

    If you want to do a shuffle manually, there's a simple algorithm called the Fisher-Yates Shuffle that will do the trick:

    private static Random r = new Random();
    static void Shuffle<T>(T[] array)
    {
        for (int i = 0; i < array.Length; i++)
        {
            int idx = r.Next(i, array.Length);
            T temp = array[idx];
            array[idx] = array[i];
            array[i] = temp;
        }
    }
    

    (List Implementation)

    private static Random r = new Random();
    static void Shuffle<T>(List<T> list)
    {
        for (int i = 0; i < list.Count; i++)
        {
            int idx = r.Next(i, list.Count);
            T temp = list[idx];
            list[idx] = list[i];
            list[i] = temp;
        }
    }