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