首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#中的卡片洗牌

C#中的卡片洗牌
EN

Stack Overflow用户
提问于 2009-07-19 19:20:28
回答 9查看 60.6K关注 0票数 16

我正在尝试为一个项目编写一个代码,该代码列出一副纸牌的内容,询问用户想要洗牌多少次,然后再洗牌。它必须使用一种方法通过System.Random类创建两个随机整数。

以下是我的类:

Program.cs:

代码语言:javascript
运行
复制
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Deck mydeck = new Deck();
            foreach (Card c in mydeck.Cards)
            {
                Console.WriteLine(c);
            }
            Console.WriteLine("How Many Times Do You Want To Shuffle?");

        }
    }
}

Deck.cs:

代码语言:javascript
运行
复制
namespace ConsoleApplication1
{
    class Deck
    {    
        Card[] cards = new Card[52];
        string[] numbers = new string[] { "2", "3", "4", "5", "6", "7", "8", "9", "J", "Q", "K" };
        public Deck()
        {
            int i = 0;
            foreach(string s in numbers)
            {
                cards[i] = new Card(Suits.Clubs, s);
                i++;

            }
            foreach (string s in numbers)
            {
                cards[i] = new Card(Suits.Spades, s);
                i++;

            }
            foreach (string s in numbers)
            {
                cards[i] = new Card(Suits.Hearts, s);
                i++;

            }
            foreach (string s in numbers)
            {
                cards[i] = new Card(Suits.Diamonds, s);
                i++;

            }
        }

        public Card[] Cards
        {
            get
            {
                return cards;


            }
        }
    }  
}

Enums.cs:

代码语言:javascript
运行
复制
namespace ConsoleApplication1
{        
    enum Suits 
    {
        Hearts,
        Diamonds,
        Spades,
        Clubs
    }
}

Card.cs:

代码语言:javascript
运行
复制
namespace ConsoleApplication1
{
    class Card
    {
        protected Suits suit;
        protected string cardvalue;
        public Card()
        {
        }
        public Card(Suits suit2, string cardvalue2)
        {
            suit = suit2;
            cardvalue = cardvalue2;
        }
        public override string ToString()
        {
            return string.Format("{0} of {1}", cardvalue, suit);
        }
    }
 }

请告诉我如何让牌洗得像人想要的那样多,然后列出洗过的牌。

EN

回答 9

Stack Overflow用户

发布于 2009-07-19 19:41:15

使用Fisher-Yates shuffle

您的C#代码应该如下所示:

代码语言:javascript
运行
复制
static public class FisherYates
{
    static Random r = new Random();
    //  Based on Java code from wikipedia:
    //  http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
    static public void Shuffle(int[] deck)
    {
        for (int n = deck.Length - 1; n > 0; --n)
        {
            int k = r.Next(n+1);
            int temp = deck[n];
            deck[n] = deck[k];
            deck[k] = temp;
        }
    }
}
票数 52
EN

Stack Overflow用户

发布于 2009-07-19 19:29:34

洗一副牌一开始似乎是微不足道的事情,但通常大多数人提出的算法是不正确的。

杰夫·阿特伍德(Coding Horror)在这个主题上写了几篇非常好的文章:

http://www.codinghorror.com/blog/archives/001008.html

http://www.codinghorror.com/blog/archives/001015.html

(尤其是第二篇是必读的)

票数 17
EN

Stack Overflow用户

发布于 2009-07-19 19:58:58

我认为这是一个你可能过于沉迷于抽象的情况。

在软件中洗牌就是以随机的顺序将一副牌提供给用户。这实际上并不需要你提前洗牌。

初始化你的卡片组。(我通常使用1到52之间的数字来表示卡,并从数学上计算出哪张卡是卡。)

  1. 通过使用随机数生成器从一副可用卡片中挑选一张卡片来发牌。
  2. 将这张卡片与deck.
  3. Decrement末尾的那张卡片交换。计数器指向这副卡片的末尾,以便从一副卡片中取出那张卡片。
  4. 转到步骤1,直到您抽出卡片为止。

编辑:一般来说,如果你有一个好的随机数生成器,通过多次“洗牌”它是不会有任何好处的。

使用您所展示的数据结构应该可以做到这一点。您只需要添加一个"Draw“方法和成员变量来跟踪卡片组的末尾。如果你下定决心提前进行“洗牌”,那么A你的教授是个混蛋,B任何时候你抽出52张牌,这副牌都会被洗牌。一旦你抽出了所有的牌,你需要提供一个"DeckEmpty“方法,以及重置纸牌末端的方法,以再次包含所有的牌。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1150646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档