如何生成随机然后再不显示随机

时间:2013-04-16 10:02:38

标签: c# list

我正在用二十一点游戏C#写一个纸牌游戏,用户按下一个按钮然后处理一张卡片,该卡片的价值会被添加到一个文本框中。如果文本框的值超过21,则用户丢失。

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

到目前为止,我尝试了两种不同的方式,一个List和一个布尔值数组,我仍在苦苦挣扎,任何人都可以指出我在代码方面的正确方向。

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

        }

提前致谢,抱歉语法不好!

6 个答案:

答案 0 :(得分:4)

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

假设您有一个名为Deck的班级,代表卡片组。填写Card个类。现在,当您开始绘制卡片时,随机选择一个集合中的数字并从Deck中删除该卡片。下次绘制相同的随机数时,它将从卡组中抽取不同的卡,因为您删除了用过的卡。

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

答案 1 :(得分: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
}

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

答案 2 :(得分: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;

因为你在获取后正在移除它们永远不会重复。

答案 3 :(得分: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);

答案 4 :(得分:0)

最简单的方法是随机排序整个列表(按Rand() - 0.5排序),然后每次需要“随机”卡时,取出第一张卡并将其从列表中删除。这些牌是随机顺序的,所以它在统计上与每次选择一张随机牌相同,并且在给定的游戏中你不会选择相同的牌两次。

答案 5 :(得分:0)

概念上最简单的方法是使用一个代表一副牌的阵列,然后从中处理卡片。

理想情况下,你会使用一个堆栈,但不幸的是你无法改变堆栈!

因此,您最好的选择是使用List<Card>,其中'卡'是代表卡的类。 Card类有两个属性:一个Suite和一个从1(Ace)到13的等级,其中11是杰克,12是女王,13是国王。

您可以使用所有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类,它封装了shuffling和处理(它可以在处理时从List<Card>的末尾删除卡片。)