源码下载在最后
前年我们的课程设计需要斗地主程序。 当时我就在烦恼界面怎么做。 我当时正好在学C#,所以就用C#完成了程序。
一方面,当时我的C#功底还很差(其实现在也不是很好),很多地方都使用了“笨方法”,实现起来也比较幼稚,程序效率也很差。非常低。 这个程序的初衷是研究斗地主程序的AI扑克牌等算法相关的东西,但我几乎忽略了那些内容。 (我会好好学算法的...^-^)
最可怕的是,因为当时时间比较紧,只有几天的时间,所以我本着“跑就跑”的想法完成了程序。 从程序本身来看,我觉得我的代码几乎没有参考价值,充满了switch...case...,结构混乱,而且最可怕的是几乎所有的代码都集中在一个mainform.xaml中.cs 文件。 。 。 太可怕了。 我仍然为自己会写出这样的代码感到羞耻...所以我不敢发布源代码。
最近又在学习Java,在做另一个项目。 看了原代码,感觉代码好像写的不好斗地主手游源码,但是有些地方的处理还是有一定意义的。 毕竟这也是一个中小型游戏应用,所以我用JAVA重画了一遍斗地主手游源码,贴出来给大家分享。 如果它能在你的学习或工作中发挥任何作用,我将非常高兴。
这个源代码是完全免费使用的,你可以用它来做任何事情,包括商业应用,无需事先通知我。
这次我用的是JAVA8,JAVA最新版本,
IDE是netbeans,总大小约80MB,体积小,安装方便
程序文件夹结构是从C# 转移过来的。 期间使用了一个叫C#转JAVA的工具来转换句型。 效果不是很理想,很多地方都是手动改的。
可以看到,程序是从Program.java启动的(和VS项目一样)
游戏以网页版在线,所以分为服务器端和客户端两部分。
服务器端JAVA包括斗地主逻辑服务和记录服务(生成SQL语句并发送给数据库)
游戏客户端-》斗地主逻辑服务-》记录服务-》数据库
”-“-”-
客户端发送消息给斗地主逻辑,斗地主逻辑转发给记录服务,然后返回,这样一个通信过程
将逻辑和记录分成两部分的目的是可以并行运行,提高效率。 比如执行SQL语句时,楼主逻辑可以继续处理请求
现在开始构建游戏。 为了不让代码变得如此难看,我们有必要加入设计模式和面向对象的思想。
首先,我们列出 54 张牌。
正如你所看到的,当扑克牌数字相同时,有 4 种花色。
利用这个特点,我们采用了数字区间,0-3为一组,4-7为一组。 如果你想得到西装,你可以只取模。 是不是很方便呢?
1 /** 2 * 背面牌都是负数 3 */ 4 public static final int BG_NORMAL = -3; 5 public static final int BG_NONGMING = -2; 6 public static final int BG_DIZHU = -1; 7 8 public static final int F_3 = 0; 9 public static final int M_3 = 1; 10 public static final int X_3 = 2; 11 public static final int T_3 = 3; 12 13 public static final int F_4 = 4; 14 public static final int M_4 = 5; 15 public static final int X_4 = 6; 16 public static final int T_4 = 7; 17 18 public static final int F_5 = 8; 19 public static final int M_5 = 9; 20 public static final int X_5 = 10; 21 public static final int T_5 = 11; 22 23 public static final int F_6 = 12; 24 public static final int M_6 = 13; 25 public static final int X_6 = 14; 26 public static final int T_6 = 15; 27 28 public static final int F_7 = 16; 29 public static final int M_7 = 17; 30 public static final int X_7 = 18; 31 public static final int T_7 = 19; 32 33 public static final int F_8 = 20; 34 public static final int M_8 = 21; 35 public static final int X_8 = 22; 36 public static final int T_8 = 23; 37 38 public static final int F_9 = 24; 39 public static final int M_9 = 25; 40 public static final int X_9 = 26; 41 public static final int T_9 = 27; 42 43 public static final int F_10 = 28; 44 public static final int M_10 = 29; 45 public static final int X_10 = 30; 46 public static final int T_10 = 31; 47 48 public static final int F_J = 32; 49 public static final int M_J = 33; 50 public static final int X_J = 34; 51 public static final int T_J = 35; 52 53 public static final int F_Q = 36; 54 public static final int M_Q = 37; 55 public static final int X_Q = 38; 56 public static final int T_Q = 39; 57 58 public static final int F_K = 40; 59 public static final int M_K = 41; 60 public static final int X_K = 42; 61 public static final int T_K = 43; 62 63 public static final int F_A = 44; 64 public static final int M_A = 45; 65 public static final int X_A = 46; 66 public static final int T_A = 47; 67 68 public static final int F_2 = 56; 69 public static final int M_2 = 57; 70 public static final int X_2 = 58; 71 public static final int T_2 = 59; 72 73 public static final int JOKER_XIAO = 60; 74 public static final int JOKER_DA = 64;
在PaiBoardByDdz类中,它负责生成新牌和洗牌操作。 我的想法是这样的,首先通过算法按顺序生成54张牌,然后随机抽出这样的牌,并将抽出的牌从原来的集合中删除,直到抽完所有牌,从而达到洗牌的目的。 参考如下代码: 可以看出,生成新卡牌时使用了增加的随机数。
/** 洗牌 */ public final void xipai() { // reset(); // int i = 0; int len = 0; int n = 0; //clone pai name java.util.ArrayList p = PAI_NAME.GetList(); //第一次发17张牌 len = 17; //提高随机数不重复概率的种子生成方法: //Millisecond 取值范围是 0 - 999 //DateTime.Now.Ticks是指从1970年1月1日(具体哪年忘了哈,好像是1970)开始到目前所经过的毫秒数——刻度数。 //54张牌的组合是 54! //是一个非常大的数,结果是: 2.3e + 71 //因此我们的seed的取值范围也应该非常大,也就是0到上面的结果, //Millisecond小了,导致只会出现999种牌的组合 //guid方法不可取,每回都是一样的 //直接以Random做为随机数生成器因为时钟精度问题, //在一个小的时间段内会得到同样的伪随机数序列, //你shuffle后会得到同一个结果。 //.net提供了RNGCryptoServiceProvider可以避免这种情况 //GetRandSeed后的取值范围是 0 - int32.MaxValue,虽然还差很远,但是999要好很多 java.util.Random r = new java.util.Random(RandomUtil.GetRandSeed()); for (i = 0; i < len; i++) { n = r.nextInt(p.size()); grid[0][i] = p.get(n); p.remove(n); } for (i = 0; i < len; i++) { n = r.nextInt(p.size()); grid[1][i] = p.get(n); p.remove(n); } for (i = 0; i < len; i++) { n = r.nextInt(p.size()); grid[2][i] = p.get(n); p.remove(n); } //end for //底牌 grid2[0] = p.get(0); grid2[1] = p.get(1); grid2[2] = p.get(2); //distory p.clear(); }
玩过Win7纸牌游戏的同学一定对游戏中的发牌动画记忆深刻。 现在我们来自己实现动画流程。 说到授权动画,90%的程序员肯定会想到通过改变位置(Location)来刷新界面,并且可能需要启用一些线程或者定时器。 但Flash天生就是用来做动画的,用Tween缓动就可以轻松实现。
客户端采用FLASH编写,IDE为Flash Builder,语言改为AS3。 由于本文主要讨论JAVA,所以这里略过。
唯一需要注意的是,为了保证程序代码的一致性,基本上JAVA写完之后就直接复制到客户端,这样就省去了建模数组不同或者名称不一致的问题
本游戏采用插件设计,目前可以集成DISCUZ、
我不需要独立的数据库,共享DISCUZ,
需要使用的童鞋,先搭建好DISCUZ和MYSQL数据库(可以使用WAMP来集成环境)
成品下载地址
独立数据库需要VPS或者有独立外网IP的独立主机
可以和峰会放在同一主机上,也可以单独打开(共享峰会的数据库)
安装注意事项
1、将斗地主客户端所有文件复制到峰会根目录下
2.在服务器上安装Java 8
修改DdzServer和RecordServer目录下的run.bat,将上述路径改为当前路径
RecordServer参数还包括连接峰会MYSQL数据库的用户名和密码
依次启动DdzServer、RecordServer、SecurityServer安全策略服务
支持win、Linux操作系统,
Linux在终端输入sudo java -jar完整路径
*服务器需要开放9300、843 TCP端口
3.在浏览器中输入你的URL/ddz.php开始游戏
可以多人同时玩,有排行榜,还有聊天
源代码