主题:  [C#请指点]_一副扑克牌(共52张牌,无大小怪)的类库

dreamexpress_5d

职务:普通成员
等级:1
金币:10.0
发贴:2229
#12005/4/7 10:29:30
using System;
using System.Collections;
namespace CardLib
{
	public enum Suit
	{
		黑桃,红心,梅花,方块
	}
	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 override string ToString()
		{
			return ""+suit+rank;
		}

		private Card()
		{
			//默认构造函数设为私有,这样初始化时将不执行默认的构造函数
		}
		public Card(Suit newSuit,Rank NewRank)//具有花色和大小的一张牌
		{
			suit=newSuit;
			rank=NewRank;
		}


	}

	public class Cards:CollectionBase//定义牌集合,以便于按集合的方法来操作
	{
		public Cards()
		{

		}


		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)//牌集深度COPY
		{
			targetCards.Clear();

			for (int i=0;i<this.Count;i++)
			{
				targetCards.Add(this[i]);
			}
		}

		public bool Contains(Card aCard)//判断牌集中是否有某张牌
		{
			return InnerList.Contains(aCard);
		}

	}


	public class Deck//定义一副牌
	{
		private  Cards cards=new Cards();//一副牌的牌集,此牌集不对外公开,要得到其中的内容,必须使用取牌的方法
	
		public Deck()//构造函数,使得牌集中包含一副52张的标准牌(按花色和大小顺序排放)
		{
			cards=this.stdCards();
		}

		private Cards stdCards()//产生一副未洗的牌(标准牌),它共有52张牌,按黑红梅方顺序,由小到大地摆放
		{
			Cards tempcards=new Cards();

			for (int suit_i=0;suit_i<4;suit_i++)
			{
				for (int rank_j=1;rank_j<14;rank_j++)
				{
					tempcards.Add(new Card((Suit)suit_i,(Rank)rank_j));
				}
			}
			return tempcards;
		}



		public void Shuffle()//洗牌,即打乱牌集中的牌的顺序
		{
			Cards newDeck=new Cards();//空牌集合,准备产生一副洗过的牌
			
						
			Random sourGen=new Random();//随机变量,准备产生随机数
			
			int RemainCards=cards.Count;//记录标准牌cards中的牌的张数

			for(int i=0;i<cards.Count;i++)
			{
				//从标准牌tempcards中每次取走一张牌,加入空牌集合newDeck中
				//同时,标准牌tempcards的张数RemainCards自减1

				int cardNum=sourGen.Next(RemainCards--);//随机取得牌号

				newDeck.Add(cards[cardNum]);//将得到的牌加到空牌集合中
				
				cards.RemoveAt(cardNum);//从标准牌中移除得到的牌
		
			}//此时,newDeck中已存放洗过的一副牌了,tempcards中无任何牌
			
			newDeck.CopyTo(cards);//将得到的牌复制到cards中

		}

		
		public Card GetOneCard(int cardNum)//取牌的方法,cardNum为要取的牌号[0~51间的整数]
		{
			if (cardNum>=0 && cardNum<cards.Count)
				return cards[cardNum];
			else
				throw(new System.ArgumentOutOfRangeException("cardNum",cardNum,"cardNum的值应在0-51之间!"));
		}

		private Card getOneCard(int cardNum,Cards aCards)//从aCards牌集中取一张牌
		{
			if (cardNum>=0 && cardNum<aCards.Count)
				return aCards[cardNum];

			else
				throw(new System.ArgumentOutOfRangeException("cardNum",cardNum,"cardNum的值超出范围!"));
		}

		public Cards GetRndCards(int cardNums)//随机取cardNums张牌
		{	
			Cards targetDeck=new Cards();//targetcards牌集准备放CardNums张牌
			
			Cards tempDeck=new Cards();

			cards.CopyTo(tempDeck);

			Random sourGen=new Random();

			if (cardNums>=1 && cardNums<=cards.Count)
			{
				

				for (int i=0;i<cardNums;i++)
				{
					
						int cardNum=sourGen.Next(tempDeck.Count);
						Card gotCard=getOneCard(cardNum,tempDeck);
						targetDeck.Add(gotCard);
						tempDeck.Remove(gotCard);
					
				}
				return targetDeck;
			}
				
			else
				throw(new System.ArgumentOutOfRangeException("cardNums",cardNums,"cardNums的值应在1-52之间!"));

		}



		
	}
}



dreamexpress_5d

职务:普通成员
等级:1
金币:10.0
发贴:2229
#22005/4/7 10:35:54
应用例子:

[找同花]:
从一副牌里随机取出5张牌,列出这5张牌,5张牌是同花色的,就不找了,如不是就按原牌顺序放好,再重新找,直到找到为止。


using System;
using CardLib;
namespace ConsoleApplication1
{
	/// <summary>
	/// Class1 的摘要说明。
	/// </summary>
	class Class1
	{
		/// <summary>
		/// 应用程序的主入口点。
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{  
			Deck myDeck=new Deck();
			myDeck.Shuffle();
			myDeck.Shuffle();
			bool samesuit=false;
			int cardNums=3;
			
			Cards GotCards=new Cards();
			do
			{
				
				GotCards=myDeck.GetRndCards(cardNums);
				foreach(Card aCard in GotCards)
				{
					Console.WriteLine(aCard.ToString());
				}
Console.WriteLine("=========================================");


				Suit cardSuit=GotCards[0].suit;
				int i;

				for(i=1;i<cardNums;i++)
				{
					if (GotCards[i].suit==cardSuit)
					{
						continue;

					}
					else
					{
						break;
					}
				}
				

				if (i==cardNums)
				{
					samesuit=true;
				}

				
			}while(samesuit==false);

	
		}
	}
}



dreamexpress_5d

职务:普通成员
等级:1
金币:10.0
发贴:2229
#32005/4/7 10:39:29
程序运行结果:
图片如下:



5D非线性编辑版主

职务:版主
等级:7
金币:29.0
发贴:6498
#42005/4/11 20:09:51
这个是什么意思?

想指点什么啊?

Wrox 出版的 Beginning C# 就有现成的例子,而且还有3次的升级
你可以看看去,看起来基本一样