1. 程式人生 > >C#:撲克牌遊戲(1):規劃CardLib類庫開發撲克牌遊戲

C#:撲克牌遊戲(1):規劃CardLib類庫開發撲克牌遊戲

(一):前言

        這是《C#入門經典(第七版)》的學習筆記,接下來會通過一個撲克牌程式學習關於C#相關知識。

(二):前期思考過程

        建立一個類庫,命名應該為CardLib,不過按照書上的安排,該類庫是在第十章第一次使用,在此命名為Ch10CardLib。

        容易想到,我們平時玩撲克牌的時候,總是會說,一副兩副,因此我們考慮建立一個類Deck代表“一副牌”。

        如果不考慮大小王,一副牌中共有52張牌,因此我們建立一個類Card代表”一張牌”。

        每張牌有”花色”和“數字”,顯然花色和數字都可以使用列舉來表示,因此建立一個代表花色的列舉Suit,一個代表數字的列舉Rank。

        Card類代表著“一張牌”,而一張牌又有著花色和數字,花色和數字是牌的特性,因此我們可以在Card類中新增欄位rank和suit,這樣就建立起了Card類和列舉Suit,列舉Rank之間的關係。

        一副牌裡有52張牌,我們可以在Deck類中新增Card陣列型別的欄位cards,這樣就建立了Deck類和Card類之間的關係。

(三):初步實現

        1:在列舉Suit中輸入程式碼

public enum Suit
    {
        Club,
        Diamond,
        Heart,
        Spade
    }

        2:在列舉Rank中輸入程式碼

 public enum Rank
    {
        Ace = 1,
        Deuce,
        Three,
        Four,
        Five,
        Six,
        Seven,
        Eight,
        Nine,
        Ten,
        Jack,
        Queen,
        King
    }

        3:在Card類中新增欄位rank和suit

 public Suit suit;
 public Rank rank;

        4:在Deck類中新增Card陣列型別的欄位cards

 private Card[] cards;

(四):對於具體功能的進一步思考

        1:Card類的建構函式

        這裡使用了新的建構函式

public Card(Suit newSuit, Rank newRank)
        {
            suit = newSuit;
            rank = newRank;
            //throw new System.NotImplementedException();
        }

        2:Card類的ToString()函式

        當我們希望得到一個Card物件的訊息時,我們希望知道它的花色和數字,因此我們重寫ToString()函式

public override string ToString()
        {
            return "The " + rank + " of " + suit + "s";
            
        }

        3:Deck類的建立函式

        一副牌內有52張牌,因此我們需要建立51個Card物件,在這裡,我們暫且使用一個數組來儲存這51個物件

 public Deck()
        {
            cards = new Card[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);
            }            
        }

        4:Deck類的洗牌函式

        作為一個紙牌類遊戲,當然要有洗牌的功能了。

        /// <summary>
        /// 洗牌
        /// </summary>
        public void Shuffle()
        {
            Card[] newDeck = new Card[52];
            bool[] assigned = new bool[52];
            Random sourceGen = new Random();
            for(int i=0;i<52;i++)
            {
                int destCard = 0;
                bool foundCard = false;
                while(foundCard==false)
                {
                    destCard = sourceGen.Next(52);
                    if(assigned[destCard]==false)
                        foundCard = true;
                }
                assigned[destCard] = true;
                newDeck[destCard] = cards[i];
            }
            newDeck.CopyTo(cards, 0);            
        }

(五):驗證

        上面寫出來的是一個類庫,需要使用一個客戶程式來驗證是否正確,因此使用一個新的客戶程式

        首先在資源管理器試圖下右擊解決方案,選擇新建專案,建立一個新的控制檯程式命名為Ch10CardClient。建立完成後右擊專案名稱,選擇“新增-引用”然後選擇Ch10CardLib後點確定。再然後右擊專案名稱,選擇“設為啟動專案”,在主函式中輸入如下程式碼。

static void Main(string[] args)
        {
            Deck myDeck = new Deck();
            myDeck.Shuffle();
            for(int i=0;i<52;i++)
            {
                Card tempCard = myDeck.GetCard(i);
                Write(tempCard.ToString());
                if (i != 51)
                    Write(",");
                else
                    WriteLine();

            }
            ReadKey();
        }

(六):效果

        

(七):原始碼

        Ch10CardLib類庫中

        Suit.cs

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

namespace Ch10CardLib
{
    public enum Suit
    {
        Club,
        Diamond,
        Heart,
        Spade
    }
}

        Rank.cs

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

namespace Ch10CardLib
{
    public enum Rank
    {
        Ace = 1,
        Deuce,
        Three,
        Four,
        Five,
        Six,
        Seven,
        Eight,
        Nine,
        Ten,
        Jack,
        Queen,
        King
    }
}

        Card.cs

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

namespace Ch10CardLib
{
    public class Card
    {
        public Suit suit;
        public Rank rank;

        private Card()
        {
            //throw new System.NotImplementedException();
        }

        public Card(Suit newSuit, Rank newRank)
        {
            suit = newSuit;
            rank = newRank;
            //throw new System.NotImplementedException();
        }

        public override string ToString()
        {
            return "The " + rank + " of " + suit + "s";
            //throw new System.NotImplementedException();
        }
    }
}

        Deck.cs

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

namespace Ch10CardLib
{
    public class Deck
    {
        private Card[] cards;

        public Deck()
        {
            cards = new Card[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);
            }            
        }

        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"));
            //throw new System.NotImplementedException();
        }

        /// <summary>
        /// 洗牌
        /// </summary>
        public void Shuffle()
        {
            Card[] newDeck = new Card[52];
            bool[] assigned = new bool[52];
            Random sourceGen = new Random();
            for(int i=0;i<52;i++)
            {
                int destCard = 0;
                bool foundCard = false;
                while(foundCard==false)
                {
                    destCard = sourceGen.Next(52);
                    if(assigned[destCard]==false)
                        foundCard = true;
                }
                assigned[destCard] = true;
                newDeck[destCard] = cards[i];
            }
            newDeck.CopyTo(cards, 0);            
        }
    }
}

        Ch10CardClient專案中

        Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ch11CardLib;
using static System.Console;

namespace Ch10CardClient
{
    class Program
    {
        static void Main(string[] args)
        {
            Deck myDeck = new Deck();
            myDeck.Shuffle();
            for(int i=0;i<52;i++)
            {
                Card tempCard = myDeck.GetCard(i);
                Write(tempCard.ToString());
                if (i != 51)
                    Write(",");
                else
                    WriteLine();

            }
            ReadKey();
        }
    }
}