3

我正在用 C# 编写一个纸牌游戏,一种二十一点游戏,用户按下一个按钮并发牌,该牌的价值被添加到一个文本框中。如果文本框的值超过 21,则用户输了。

我在处理卡片时遇到问题,我生成一个随机数,比如生成 5 显示钻石 5,将钻石 5 的值添加到分数文本框并显示图片框(5钻石扑克牌)。但是,一旦生成了 5,我就无法再次生成该卡,我对需要发生的事情有逻辑,我只是​​不确定实际代码本身,因为我是初学者。

到目前为止,iv 尝试了 2 种不同的方法,一个列表和一个布尔值数组,我仍在努力,任何人都可以在代码方面指出我正确的方向。

List<int> Diamonds = new List<int>();
        Random random = new Random();
        genRandom = random.Next(0, 5);


        while (Diamonds.Contains(genRandom))
        {
            genRandom = random.Next(0, 5);
            break;
        } 


        while (!Diamonds.Contains(genRandom))

        if (genRandom == 0)
        {
            Diamonds.add(0);
            score = score += 2;
            scoreTextBox.Text = score.ToString();
            diamonds2.Show();

        }

在此先感谢,对语法错误感到抱歉!

4

6 回答 6

4

我会采取相反的方法,通过创建一个包含所有可能卡片的集合,然后从集合中随机抽取它们。

假设您有一个名为 的类Deck,它代表一副牌。Card用类填充它。现在,当您开始抽牌时,在集合中随机选择一个数字并将该牌从Deck. 下次抽到相同的随机数时,它会从牌堆中抽出不同的牌,因为您移除了使用过的牌。

只要记住生成一个在牌组大小范围内的随机数,每次抽牌后随机数会减少。

于 2013-04-16T10:06:55.617 回答
4

你现在的问题是你没有卡池。您应该有一张可以抽牌的卡片列表,一旦选择了一张牌,它就会从可用选项中删除,并且不能再次抽牌。

List<Card> deck = new List<Card>();

deck.Add(new Card(1, CardType.Diamonds));
deck.Add(new Card(2, CardType.Diamonds));

...

Card nextCard = deck[Random.Next(0, deck.Count - 1)];
deck.Remove(nextCard);

在哪里:

struct Card
{
    public int number;
    public CardType type;

    public Card(int number, CardType type)
    {
        this.number = number;
        this.type = type;
    }
}

enum CardType
{
    Diamonds,
    Spades,
    Hearts,
    Clubs
}

这是一种非常简单的面向对象的方法,其中每张卡片都被明确定义为一个独特的容器。这可能不是最佳方式,但可能更容易理解。

于 2013-04-16T10:09:09.300 回答
1

有很多方法可以做到这一点,我最常用的方法如下:

List<int> available = new List<int>(5000);
for(int i=1; i<=5; i++)
available.Add(i);

上面的代码将生成所有随机数。

现在您可以从它们中进行如下选择:

List<int> result = new List<int>(5000);
while(available.Count > 0)
{
 int index = random.Next(availableCount);
 result.Add(available[index]);
 available.RemoveAt(index);
}
return result;

由于您在获得后将其删除,因此它们将永远不会重复。

于 2013-04-16T10:08:59.500 回答
1

你可以这样做:

List<int> Diamonds = new List<int>();
for(int i = 1; i <= 10; i++) //10 is just an example..dk how many cards :P
{
    Diamonds.Add(i);
}

Random random = new Random();
int index = random.Next(0, Diamonds.Count - 1);
int nr = Diamonds[index];
Diamonds.Remove(index);
于 2013-04-16T10:09:42.793 回答
0

从概念上讲,最简单的方法是拥有一个表示一副牌的数组,然后从中发牌。

理想情况下,您会为此使用堆栈,但不幸的是,您不能洗牌!

因此,最好的办法是使用 a List<Card>,其中 'Card' 是代表卡片的类。该类Card将有两个属性:aSuite和从 1(Ace)到 13 的等级,其中 11 是 Jack,12 是 Queen,13 是 King。

你会用所有 52 张可能的牌填充你List<Card>的牌组,然后你可以使用Fisher-Yates shuffle的实现来洗牌。

这是一个完整的示例:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var deck = new List<Card>();

            for (int rank = 1; rank <= 13; ++rank)
                foreach (Suite suite in Enum.GetValues(typeof(Suite)))
                    deck.Add(new Card {Rank = rank, Suite = suite});

            var shuffler = new Shuffler();

            shuffler.Shuffle(deck);

            // Deal the top 10 cards.

            for (int i = 0; i < 10; ++i)
                Console.WriteLine(deck[i]);
        }
    }

    public enum Suite
    {
        Clubs,
        Diamonds,
        Hearts,
        Spades
    }

    public sealed class Card
    {
        public Suite Suite;
        public int Rank;

        public override string ToString()
        {
            string rank;

            switch (Rank)
            {
                case 1:  rank = "Ace";   break;
                case 11: rank = "Jack";  break;
                case 12: rank = "Queen"; break;
                case 13: rank = "King";  break;
                default: rank = Rank.ToString(); break;
            }

            return string.Format("{0} of {1}", rank, Suite);
        }
    }

    public sealed class Shuffler
    {
        public Shuffler()
        {
            _rng = new Random();
        }

        public void Shuffle<T>(IList<T> array)
        {
            for (int n = array.Count; n > 1; )
            {
                int k = _rng.Next(n);
                --n;
                T temp = array[n];
                array[n] = array[k];
                array[k] = temp;
            }
        }

        private readonly Random _rng;
    }
}

当然,真实代码应该验证 Rank 和 Suite。此外,您最好编写一个封装了洗牌和发牌的 Deck 类(它可以在发牌结束List<Card>时移除牌)。

于 2013-04-16T10:27:45.317 回答
0

最简单的做法是对整个列表进行随机排序(按 排序Rand() - 0.5),然后每次您想要一张“随机”卡片时,取出第一个并将其从列表中删除。这些牌是随机顺序的,因此在统计上与每次随机选择一张牌的效果相同,并且您不会在给定的游戏中两次选择同一张牌。

于 2013-04-16T10:06:05.387 回答