locked
《C#入门经典》第十章关于扑克牌的程序 怎么也看不懂 RRS feed

  • 問題

  • using System;
    using System.Collections.Generic;
    using System.Text;

    namespace Ch10CardLib
    {
        public enum Suit
        {
            Club,
            Diamond,
            Heart,
            Spade,
        }
        public enum Rank
        {
            Ace = 1,
            Deuce,
            Three,
            Four,
            Five,
            Six,
            Seven,
            Eight,
            Nine,
            Ten,
            Jack,
            Queen,
            King,
        }
        public class Card
        {
            public readonly Suit suit;
            public readonly Rank rank;

            public  Card(Suit newSuit,Rank newRank)
            {
                this.suit = newSuit;
                this.rank = newRank;
            }

            private Card() { }

            public override string ToString()
            {
                return "The " + rank + " of " + suit + "s";
            }
        }
      public class Deck
      {
        private Card[] cards;  //声明类数组

        public Deck()
        {
          cards = new Card[52];  //创建52个对象
          for (int suitVal = 0; suitVal < 4; suitVal++)
          {
            for (int rankVal = 1; rankVal < 14; rankVal++)
            {
              cards[suitVal * 13 + rankVal - 1] = new Card((Suit)suitVal,(Rank)rankVal); //实例化52个对象,并且通过构造函数给suit和rank赋值,问题来了。。类不是引用类型的吗,这样赋值suit和rank不是都是一样的吗?
            }
          }
        }

        public Card GetCard(int cardNum)  //这里声明的这个方法是干什么的啊??不太明白。
        {
          if (cardNum >= 0 && cardNum <= 51)
            return cards[cardNum ];  //这里是返回对象里的ToString方法里的内容吗,因为类是引用类型的,这里只代表了cards[cardNum]的指针,返回的结果不都是一样的吗?怎么都不理解!!!
          else
            throw (new System.ArgumentOutOfRangeException("cardNum", cardNum, "数字在0-51间"));
        }

        public void Shuffle()
        {
          Card[] newDeck = new Card[52]; //声明了52个类数组
          bool[] assigned=new bool[52]; //声明了52个bool类型的变量
          Random sourceGen = new Random();  //实例化一个随机数对象
          for (int i = 0; i < 52; i++)
          {
            int destCard = 0;
            bool foundCard = false; //声明一个bool变量为假
            while (foundCard == false) //如果为假就循环
            {
              destCard = sourceGen.Next(52); //赋一个1-52之间的随机数给destCard
              if (assigned[destCard] == false) //前面都没给assigned赋值,这里怎么就出现了个如果为假执行下面的代码那???
                foundCard = true; //等于真,跳出循环
            }
            assigned[destCard] = true;
            newDeck[destCard] = cards[i];
          }
          newDeck.CopyTo(cards ,0);
        }
      }
    }

             1;类数组是怎么存储的啊? cards[suitVal * 13 + rankVal - 1] = new Card((Suit)suitVal,(Rank)rankVal); 这里的cards[suitVal * 13 + rankVal - 1]是52个指针,指针同时都指向Card类,Card类不管有什么变化这52个对象都指向Card类,这段代码我就不明白了,要是照这样循环下去的话不就成了:cards的这0—51个指针不同时都指向Card((Suit)3,(Rank)13),这怎么对那?我该怎么理解这句话那?

             2;这里返回的是Card类对象,它的返回类型定义的是Card,怎么可能返回string类型呢。这句话能不能举个例子啊?呵呵,我运行程序后,发现return出来的就是ToSring里的内容啊?而且自己也做了个小例子,证明就是ToSring在发挥作用啊?

             非常渴望得到答案,真是麻烦你们了,谢谢了

    本人属于业余爱好者,可能基础东西搞的不是很清楚,但是真心的喜欢编程,望各位高手多多帮助,谢谢了

    2011年1月10日 5:19

解答

  • 1) Try to following the code and run in your mind,

    when SuitVal = 0, foreach rankVal from 1 to 13, then
        i)    cards[0*13+1-1] = cards[0] = Card((Suit) 0, (Rank) 1)
        ii)   cards[0*13+2-1] = cards[1] = Card((Suit) 0, (Rank) 2)
        iii)  cards[0*13+3-1] = cards[2] = Card((Suit) 0, (Rank) 3)
        ...
        xiii)  cards[0*13+13-1] = cards[12] = Card((Suit) 0, (Rank) 13)
    Then now SuitVal = 1, foreach rankVal from 1 to 13,
        xiv) cards[1*13+1-1] = cards[13] = Card
    ((Suit) 1, (Rank) 1)
        xiv) cards[1*13+2-1] = cards[14] = Card((Suit) 1, (Rank) 2)

    it does not fall into what you were asking in the question.

    2) Read Carefully, It return Card type(public Card GetCard............cards[cardNum ]; ) , it is not returning String. If you create another method, and it return string type, then you will see the message "The " + rank + " of " + suit + "s"


    public String GetCard(int cardNum)  
        {
          if (cardNum >= 0 && cardNum <= 51)
            return cards[cardNum ].ToString() ;  
          else
            throw (new System.ArgumentOutOfRangeException("cardNum", cardNum, "数字在0-51间"));
        }


    大家一齊探討、學習和研究,謝謝!
    Microsoft MVP, Microsoft Community Star(TW & HK), MCT,
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD
    2011年1月11日 3:45