CardLib 添加 Cards 集合

  第 10 章创建了一个类库项目 Ch10CardLib,它包含一个表示扑克牌的 Card 类和一个表示一副扑克牌的 Deck 类,这个 Deck 类是 Card 类的集合,且实现为一个简单数组。

  本章给这个库添加一个新类,并将类库重命名为 Ch11CardLib。这个新类 CardsCard 对象的一个定制集合,并拥有本章前面介绍的各种功能。在 C:\BegVCSharp\Chapter11 目录中创建于给新类库 Ch11CardLib。然后删除自动生成的 Class1.cs 文件,再使用 Project | Add Existing Item 选择 C:\BegVCSharp\Chapter10\Ch10CardLib\Ch10CardLib 目录中的 Card.csDeck.csSuit.csRank.cs 文件,把它们添加到项目中。与第 10 章介绍的这个项目的上一个版本相同,这里也不使用标准的 “试一试” 格式介绍这些变化。

  如果要自己创建这个项目,就应该添加一个新类 Cards,修改 Cards.cs 中的代码,如下所示:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace Ch11CardLib
    {
        public class Cards : CollectionBase
        {
            public void Add(Card newCard)
            {
                List.Add(newCard);
            }

            public void Remove(Card oldCard)
            {
                List.Remove(oldCard);
            }

            public Card this[int cardIndex]
            {
                get {
                    return (Card)List[cardIndex];
                }
                set {
                    List[cardIndex] = value;
                }
            }

            public void CopyTo(Cards targetCards)
            {
                for (int index = 0; index < this.Count; index++)
                {
                    targetCards[index] = this[index];
                }
            }

            public bool Contains(Card card)
            {
                return InnerList.Contains(card);
            }
        }
    }

  然后需要修改 Deck.cs,以利用这个新集合,而不是数组:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace Ch11CardLib
    {
        public class Deck
        {
            private Cards cards = new Cards();

            public Deck()
            {
                for (int suitVal = 0; suitVal < 4; suitVal++)
                {
                    for (int rankVal = 1; rankVal < 14; rankVal++)
                    {
                        cards.Add(new Card((Suit)suitVal, (Rank)rankVal));
                    }
                }
            }

            public Card GetCard(int cardNum)
            {
                if (cardNum >=0 && cardnum <= 51)
                    return cards[cardNum];
                else
                    throw (new System.ArgumentOutOfRangeException("cardNum", cardNum, "Value must be between 0 and 51."));
            }

            public void Shuffle()
            {
                Cards newDeck = new Cards();
                bool[] assigned = new bool[52];
                Random sourceGen = new Random();
                for (int i = 0; i < 52; i++)
                {
                    int sourceCard = 0;
                    bool foundCard = false;
                    while (foundCard == false)
                    {
                        sourceCard = sourceGen.Next(52);
                        if (assigned[sourceCard] == false)
                            foundCard = true;
                    }
                    assigned[sourceCard] = true;
                    newDeck.Add(cards[sourceCard]);
                }
                newDeck.CopyTo(cards);
            }
        }


    }

  在此不需要做很多修改。其中大多数修改都涉及改变洗牌逻辑,才能把 cards 中随机的一张牌添加到新 Cards 集合 newDeck 的开头,而不是把 cards 集合中顺序位置的一张牌添加 newDeck 集合的随机位置上。

  Ch10CardLib 解决方案的客户控制台应用程序 Ch10CardClient 可以使用这个新库得到与以前相同的结果,因为 Deck 的方法签名没有改变。这个类库的客户程序现在可以使用 Cards 集合类,而不是依赖 Card 对象数组,例如,在扑克牌游戏应用程序中定义一手牌。

🔚