c# 构架WPF 纸牌游戏(斗地主2)
在上一节中我们将资源全部都制作好了,现在开始构架游戏。为了不让代码那么难看,我们很有必要加入设计模式和面向对象思想。
首先,我们可以将扑克的花色抽象为6个类:方块类(CardDiamond)、红桃类(CardHeart)、黑桃类(CardClub)、梅花类(CardSpader)、小王类(CardSmallJoker)、大王类(CardBigJoker),让他们全部继承抽象类CardBase。在基类中,CardType属性和SetCard()方法定义为抽象类型。CardType是一个枚举类型,在子类中必须指定当前扑克的花色。SetCard()是读取扑克的正面图片资源,一旦执行,扑克便可以显示出正面(发牌阶段为背面),此处定义为抽象方法后可以利用工厂模式进行调用,使用者不需要具体知道它内部是如何实现的。CardNumber为扑克点数从1到13。定义一个UserControl的属性,就是Card,通过初始化相关的控件,可以动态增加到主程序容器中去。注意:初始化的时候所有的扑克都是背面朝上的,因此可以将这一动作抽象出来放到基类的构造函数中去。
这里唯一需要解决的技术问题就是,如何动态的将图片资源对象到每一张牌。参考如下代码,通过设置Background可以实现,但是需要通过FindResource来找到对应的图片资源名称(在上节中生成资源字典的时候会生成此名称)
Brush brush = m_Card.FindResource("ImageBrushFaceDown") as Brush;
m_Card.Background = brush;
在CardHelper类中,负责生成新牌和洗牌操作。我的思想是这样的,先通过算法按顺序生成54张牌,然后随机抽取这些牌,被抽取的牌从原来集合中删除,直到所有的牌都被抽取完毕为止,从而达到洗牌的目的。参考如下代码:可以看出生成新牌的时候使用了策略模式
{
/// <summary>
/// 初始化牌,并洗牌,通过此函数可以获得一副随机的扑克牌。
/// </summary>
/// <returns></returns>
public static List<CardBase> GetCardCollection()
{
List<CardBase> cardCollection = new List<CardBase>();
for (int i = 0; i < 4; i++)
{
for (int j = 1; j <= 13; j++)
{
CardBase card = null;
switch (i)
{
case 0:
card = new CardClub();
card.Card.Name = "CardClub" + j.ToString();
break;
case 1:
card = new CardDiamond();
card.Card.Name = "CardDiamond" + j.ToString();
break;
case 2:
card = new CardHeart();
card.Card.Name = "CardHeart" + j.ToString();
break;
case 3:
card = new CardSpader();
card.Card.Name = "CardSpader" + j.ToString();
break;
}
card.CardNumber = j;
cardCollection.Add(card);
}
}
//最后来添加大小王
cardCollection.Add(new CardBigJoker());
cardCollection.Add(new CardSmallJoker());
return SetCardRnd(cardCollection);
}
/// <summary>
/// 将生成的扑克随机打乱(洗牌操作)
/// </summary>
/// <param name="oldCardCollection">已经生成的扑克牌集合</param>
/// <returns></returns>
private static List<CardBase> SetCardRnd(List<CardBase> oldCardCollection)
{
Random ran = new Random();
List<CardBase> cardCollection = new List<CardBase>();
for (int i = 53; i >= 0; i--)
{
int cardIndex = ran.Next(0, i + 1);//随机数可以取到下限值,但是不能取到上限值。
cardCollection.Add(oldCardCollection[cardIndex]);
oldCardCollection.RemoveAt(cardIndex);
}
return cardCollection;
}
}