C# 卡片组 52 张卡片中的卡片洗牌

C# card shuffle in card deck 52 cards

有一个 Windows 应用程序的项目我仍在处理,它是关于一套卡片组的。该应用程序使用 52 张牌,其中包含 4 套花色和 13 个面值,例如 2 张梅花、红心杰克等。我正在工作的部分是我还必须使用五个图片框来显示每张随机卡片,因此我单击 "Deal" 按钮。我知道我必须使用 "Random" 关键字以及使用 for 循环来进行随机播放。

因此,我不太确定如何用不同的随机卡片显示每个图片框并相应地显示每张卡片的名称。

在此下方包含 windows 应用程序的屏幕截图以及我的项目代码。

    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

我不确定你的 PlayingCard class 是如何编码的,但你的问题似乎很大一部分源于它的设计。以这个实现为例:

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

它包含所有比较和值转换代码,因此您不必担心创建高度专业化的方法来进行无关的转换。您可以像这样在套牌中使用它:

数组实现

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

列表实现

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

编辑:

手动洗牌

如果您想手动进行随机播放,可以使用一种名为 Fisher-Yates Shuffle 的简单算法来解决问题:

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

(列表实现)

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