四、生成扑克与发牌
首先,发牌操作是在GenerateAndDealCards方法中实现的。
(1)生成52张随机顺序的扑克
首先,应当以随机的顺序生成52张扑克:
Card[] arrPoker = new Card[52];
Card[] OrderPoker = new Card[52];
int[] RandomI = new int[52];
int curNum;
RandomKDiffer(0, 51, 52, RandomI);
for (int i = 0; i < 52; i++){
curNum = i < 13 ? i + 1 : ((i + 1) % 13 == 0 ? 13 : (i + 1) % 13);//range 1~13
if (i < 13) //0-12
OrderPoker[i] = new Card(curNum, Suits.Clubs);
else if (i < 26) //13-25
OrderPoker[i] = new Card(curNum, Suits.Diamonds);
else if (i < 39) //26-38
OrderPoker[i] = new Card(curNum, Suits.Hearts);
else
OrderPoker[i] = new Card(curNum, Suits.Spades);
arrPoker[RandomI[i]] = OrderPoker[i];//乱序
InverseBehaviorArray[i].Attach(arrPoker[RandomI[i]]);
//……省略其他
}
首先,我们定义一个Card数组arrPoker来存储52张随机顺序的扑克。另一个Card数组OrderPoker用于存储52张按自小到大顺序的扑克。
其次,借助于方法RandomKDiffer的帮助,我们生成序号从0到51的52张不同的扑克。
接下来,存储在数组arrPoker中的52张扑克都被初始化为正面向上(其实在空当接龙游戏中根本没有正面朝下的情况)。
最后,一旦生成一张扑克即把一个相关的InverseColorClickBehavior行为附加到其上。
(2)创建游戏主界面中的初始元素
当玩家按下菜单“Game”—“Start”后,界面底部的52张扑克准备就绪。下图给出了游戏开始时的运行时快照。
注意到,我们在上部添加了一些矩形控件用于修饰可用单元和回收单元。当然,你也可以采用其他的策略,但是我们必须注意由此产生的一些“影响”。
具体来说,本游戏中有两处涉及到这个“影响”。一处是前面讨论过的获取当前扑克牌的方法GetCurrentCard。另一处是我们应当何时及怎样添加上述矩形控件。
首先,我们选择在方法GenerateAndDealCards中添加这些矩形。不过,在单击“Start”菜单前,屏幕上是看不到这些矩形的。
其次,我们决定在正式加载扑克控件前以动态方法加载这些矩形相关的XAML代码。
那么,如何动态加载呢?下面讨论完成这项任务的LoadRectangleElementsFirst方法。此方法的关键代码如下:
XElement rectanglestr = XElement.Parse(
@"
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
Fill='Red' Stroke='Black' Height='32' Width='29' Canvas.Left='308' Canvas.Top='29' />");
cardContainer.Children.Add(XamlReader.Load(rectanglestr.ToString()) as UIElement);
XElement p3Str = XElement.Parse(
@"
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
Fill='White' Stretch='Fill' Height='100' Width='1' UseLayoutRounding='False' Canvas.Left='75' Data='M319,100 L319,8' Stroke='#FFBEFF00'/>");
cardContainer.Children.Add(XamlReader.Load(p3Str.ToString()) as UIElement);
XElement p2Str = XElement.Parse(
@"
xmlns='http://schemas.microsoft.com/client/2007'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
Fill='White' Stretch='Fill' Stroke='Black' Height='100' Width='1' UseLayoutRounding='False' Canvas.Left='0' Data='M319,100 L319,8'/>");
cardContainer.Children.Add(XamlReader.Load(p2Str.ToString()) as UIElement);
//……省略其他
cardContainer.Children.Add(XamlReader.Load(p0_Copy6Str.ToString()) as UIElement);
}
在上面代码中,有如下几点值得注意:
使用LINQ to XML技术动态创建XAML元素。
程序开始必须先添加对于程序集System.Xml.Linq.dll的引用。
创建了大量的XElement对象并填充以繁琐的XAML标记。
? ?在每一个XElement对象中,必须要声明两个默认的XML命名空间;否则,我们会遇到如下运行时错误:AG_E_PARSER_MISSING_DEFAULT_NAMESPACE。