C#写的网络版斗地主.docx
《C#写的网络版斗地主.docx》由会员分享,可在线阅读,更多相关《C#写的网络版斗地主.docx(9页珍藏版)》请在冰点文库上搜索。
C#写的网络版斗地主
C#写的网络版斗地主
豆豆网 技术应用频道 2009年06月08日 【字号:
小中大】收藏本文
断断续续写了一个月,总算是把这个东西搞出来了。
第一次写网络程序,所以网络部分很烂,如果网络延迟厉害的话就会出错。
出牌规则和牌组之间的比较已经比较完善,能想到的组合方式都写上去了。
大家知道,斗地主这个游戏是将一些特有的牌组合成牌组然后来比较牌组的大小,那么,就应该给PokerGroup类定义一个属性type,即牌组的类型,type的值是一个枚举类型
1. 1 publicenumPokerGroupType
2. 2 {
3. 3 单张=1,
4. 4 对子=2,
5. 5 双王=3,
6. 6 三张相同=4,
7. 7 三带一=5,
8. 8 炸弹=6,
9. 9 五张顺子=7,
10.10 六张顺子=8,
11.11 三连对=9,
12.12 四带二=10,
13.13 二连飞机=11,
14.14 七张顺子=12,
15.15 四连对=13,
16.16 八张顺子=14,
17.17 飞机带翅膀=15,
18.18 九张顺子=16,
19.19 三连飞机=17,
20.20 五连对=18,
21.21 十张顺子=19,
22.22 十一张顺子=20,
23.23 十二张顺子=21,
24.24 四连飞机=22,
25.25 三连飞机带翅膀=23,
26.26 六连对=24,
27.27 //没有13
28.28 七连对=25,
29.29 五连飞机=26,
30.30 八连对=27,
31.31 四连飞机带翅膀=28,
32.32 //没有17
33.33 九连对=29,
34.34 六连飞机=30,
35.35 //没有19
36.36 十连对=31,
37.37 五连飞机带翅膀=32
38.38
39.39
40.40 //下面是各种牌组对应的牌的张数
41.41 //单张=1,
42.42 //对子=2,
43.43 //双王=2,
44.44 //三张相同=3,
45.45 //三带一=4,
46.46 //炸弹=4,
47.47 //五张顺子=5,
48.48 //六张顺子=6,
49.49 //三连对=6,
50.50 //四带二=6,
51.51 //二连飞机=6,
52.52 //七张顺子=7,
53.53 //四连对=8,
54.54 //八张顺子=8,
55.55 //飞机带翅膀=8,
56.56 //九张顺子=9,
57.57 //三连飞机=9,
58.58 //五连对=10,
59.59 //十张顺子=10,
60.60 //十一张顺子=11,
61.61 //十二张顺子=12,
62.62 //四连飞机=12,
63.63 //三连飞机带翅膀=12,
64.64 //六连对=12,
65.65 ////没有13
66.66 //七连对=14,
67.67 //五连飞机=15,
68.68 //八连对=16,
69.69 //四连飞机带翅膀=16,
70.70 ////没有17
71.71 //九连对=18,
72.72 //六连飞机=18,
73.73 ////没有19
74.74 //十连对=20,
75.75 //五连飞机带翅膀=20
76.76 }
当玩家出牌时,首先应判断玩家的牌组类型。
我判断牌组类型的方法是根据玩家所出牌组张数的不同来做出不同的处理。
比如,玩家出的牌只有一张,那么肯定是个子。
如果有两张肯定是对子。
如果有三张,肯定是三个。
如果有6张呢?
就有三种情况了:
1、顺子。
2、连对。
、3、飞机。
由于顺子,连对,飞机这三种牌可以有很多组合,顺子可以有6张顺子或者7张顺子,连对可以有4连对或者5连对。
飞机可以有2连飞机,三连飞机。
所以就需要写几个方法分别判断牌组是否为顺子,连对,飞机了。
顺子和对子很好判断,飞机就麻烦点了,由于飞机可以随便带一张或几张牌,如果带的牌的点数比飞机本身的点数大,那么大的那张牌就被排序到飞机前面了,这样对比较牌组的大小很不方便。
所以还要有一个对飞机带翅膀这样的牌组进行排序的方法。
判断牌组类型的代码下载地址:
无序的牌组通过以上代码的洗礼,已经变成了非常容易比较的牌组了。
比较牌组的大小就非常简单了。
首先排除特殊牌组炸弹,双王。
然后再比较普通牌组的第一张牌就可以了。
下面是牌组比较的代码,重写了PokerGroup的大于号运算符
1. publicstaticbooloperator>(PokerGroupLP,PokerGroupRP)
2. {
3. boolIsGreater=false;
4. if(LP.type!
=RP.type&&LP.type!
=PokerGroupType.炸弹&&LP.type!
=PokerGroupType.双王)
5. {
6. IsGreater=false;
7. }
8. else
9. {
10. if(LP.type==PokerGroupType.炸弹&&RP.type==PokerGroupType.炸弹)//LPRP都为炸弹
11. {
12. if(LP[0]>RP[0])//比较大小
13. {
14. IsGreater=true;
15. }
16. else
17. {
18. IsGreater=false;
19. }
20. }
21. else
22. {
23. if(LP.type==PokerGroupType.炸弹)//只有LP为炸弹
24. {
25. IsGreater=true;
26. }
27. else
28. {
29. if(LP.type==PokerGroupType.双王)//LP为双王
30. {
31. IsGreater=true;
32. }
33. else
34. {
35. if(LP[0]>RP[0])//LP为普通牌组
36. {
37. IsGreater=true;
38. }
39. else
40. {
41. IsGreater=false;
42. }
43. }
44. }
45. }
46. }
47. returnIsGreater;
48. }
复制代码
然后在接收其他玩家牌组的时候调用IsRule方法给牌组定义一个类型,自己出牌的时候也定义一个类型,再在出牌的时候比较俩牌组的大小。
由于本人学习C#的时间不长,而且是利用业余时间学习。
所以技术不怎么样,写出来的代码总共2147行。
质量个人觉得比较差劲,刚开始架构整个程序时还是按照面向对象的思考方式架构整个程序,但是架构了一部分之后后面的东西,比如网络,规则等实在是想不出来了,只能走一步算一步。
所以后面写的代码基本没有面向对象,完全是为了实现功能写代码。
嗯,本程序是我断断续续学习C#大半年来,写的最难最复杂的一个程序。
除了牌的从大到小排序算法使用著名的冒泡排序以外,其他所有代码全部原创。
回过头来看看自己写的这些东西,还是蛮有成就感的~
截图:
图片看不清楚?
请点击这里查看原图(大图)。
下面放出程序的源代码,希望能和大家一起学习交流。
C#网络版斗地主——网络部分实现
C#网络版斗地主——网络部分实现。
本文是对C#网络版斗地主的总结,之后还有两篇,分别介绍地主权限的传递和出牌权限的传递,还有出牌算法和规则。
服务器使用server类与客户端通讯,客户端使用client类与服务器通讯。
当创建游戏时,new出一个server对象,并且开始监听默认端口“1991”。
然后创建一个线程,用死循环while(true)检测是否有客户端连接,如果有的话获取Client对象,当获取了两个Clinet对象后,停止监听,中断循环。
服务器获取了两个客户端后,启动两个线程“AccpetClient1Data”、“AccpetClient2Data”,使用server中同名方法,分别监听客户端1和客户端2发送的数据。
当加入游戏时,new出一个client对象,并且连接玩家指定的IP,端口默认为1991。
连接上后,启动线程“AcceptServerData”,使用client中同名方法。
这样,server端使用方法SendDataForClient向客户端发送信息,client能够收到,client端使用SendDataForServer向server端发送信息,Server端也能收到。
值得一提的是,两个客户端之间是没有连接的,他们之间通讯需要通过server端来“代理”。
连接建立好后,客户端的准备按钮显示出来,点击准备按钮向服务端发送“OK”字符串,服务器收到后会通过“AccpetClient1Data”、“AccpetClient2Data”这两个方法识别出来,然后显示服务器端的开始按钮。
点击开始按钮后,服务器端像客户端“发送StartPokers+牌组”,发给自己的牌组不需要在网络中传输,所以直接添加到相关的牌组对象中即可。
这里的牌组类要自己写序列化和反序列化的方法,需要把牌组序列化为byte[]才能在网络中传送。
客户端通过“AcceptServerData”方法读取并处理“StartPokers+牌组”。
处理后的结果是一个PokerGroup对象,把引用传递给相应对象就完成发牌了。
后面就是确定地主,出牌权限的传递,出出去的牌组的传递等等了,也都是使用server和client中的SendDataForServer和SendDataForClient方法发送byte流,然后使用“AccpetClient1Data”、“AccpetClient2Data”,“AcceptServerData”,完成接受并处理数据。
C#网络版斗地主——地主权限的传递
C#网络版斗地主——地主权限的传递。
本文是对C#网络版斗地主的总结。
首先服务器使用一个随机数来随即选出默认地主。
然后发送信息给选出来的玩家。
玩家接收到信息后显示两个按钮“叫地主”,“不叫”。
如果选择不叫,则把可以叫地主的权限发送给另外一个玩家,如果另外两个玩家都不要的话,就执行Restart()方法重新发牌。
叫地主权限的传递顺序如下图所示:
具体实现方法:
服务器得到一个1-3的随机数,1代表服务器是默认地主(默认地主就是随机选择的第一个有权限叫地主的玩家),2代表client1是默认地主,3代表client2是默认地主。
只有服务器端能够选择地主,所以该方法在server类中
public void SendOrder(int Num)
{
switch (Num)
{
case 1:
DConsole.player1.areYouLandLord = true; //把叫地主权限给自己
break;
case 2:
this.SendDataForClient("AreYouLandLord", 1); //传递叫地主权限给client1
break;
case 3:
this.SendDataForClient("AreYouLandLord", 2); //传递叫地主权限给client2
break;
}
}