源碼下載在最后
我們的前年的課設要求做一個斗地主程序,當時正在愁如何做界面,當時剛好在學習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<String> 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集成環境)
成品下載地址
http://pan.baidu.com/s/1gdjOIYZ
獨立數據庫,需要VPS或獨立主機一台,有獨立外網IP
可與論壇放同一主機,或分開放也可(共用論壇的數據庫)
安裝說明
1.將斗地主客戶端所有文件 拷貝到論壇根目錄
2.在服務器上安裝好Java 8
修改DdzServer、RecordServer 目錄里的run.bat,將里面路徑修改為當前路
RecordServer 參數還包括連接論壇MYSQL數據庫的用戶名,密碼等
依次啟動DdzServer,RecordServer 和SecurityServer安全策略服務
支持win,Linux操作系統,
Linux在terminal上輸入 sudo java -jar 完整路徑
*需要服務器開放9300 ,843 TCP端口
3.在瀏覽器輸入 http://你的網址/ddz.php 開始游戲
可多人同時玩,有排行榜,可聊天
源碼
https://github.com/wdmir/521266750_qq_com.git