聯系我們 - 廣告服務 - 聯系電話:
您的當前位置: > 關注 > > 正文

【模擬兩人詐金花牌】手牌大小判斷決定輸贏

來源:CSDN 時間:2023-03-02 09:43:20

初始目標:

模擬兩人詐金花牌,并進行手牌大小判斷  來決定輸贏(并不包含詐人的游戲過程)


(資料圖片)

目標分析:

確定游戲需求:游戲娛樂確定項目應用前景:簡單游戲需求,初級學習需求,商業化能力≈0分析項目內容

項目分析:

發牌手牌等級判斷等級比較確認輸贏

1.每個人 手牌的 標準javaBean包

包括了:

大等級(豹子,同花順……),小等級(相同大等級內細分的 小等級)

每張手牌的  花色 , 牌面數字

每個人的ID

package Save_Pai;import java.util.Arrays;public class PersonPoker {public int BigLevel;public String SmallLevel;private int PokerColour[];private int PokerNumber[];public int person;public PersonPoker(){}public PersonPoker(int[] pokerColour, int[] pokerNumber) {super();PokerColour = pokerColour;PokerNumber = pokerNumber;}public int[] getPokerColour() {return PokerColour;}public void setPokerColour(int[] pokerColour) {PokerColour = pokerColour;}public int[] getPokerNumber() {return PokerNumber;}public void setPokerNumber(int[] pokerNumber) {PokerNumber = pokerNumber;}@Overridepublic String toString() {return "PersonPoker [PokerColour=" + Arrays.toString(PokerColour) + ", PokerNumber="+ Arrays.toString(PokerNumber) + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + Arrays.hashCode(PokerColour);result = prime * result + Arrays.hashCode(PokerNumber);return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;PersonPoker other = (PersonPoker) obj;if (!Arrays.equals(PokerColour, other.PokerColour))return false;if (!Arrays.equals(PokerNumber, other.PokerNumber))return false;return true;}}

2.主程序分析

游戲不止兩個人進行,可以為多人發牌多人發牌前需要得到本局游戲人數確認發牌是否成功

主程序(domain)

package domain;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.List;import java.util.Scanner;import Fapai.Fapai;import PokerLevel.PokerLevel;import PrintPoker.PrintPoker;import Save_Pai.PersonPoker;public class domain {private static final int BAOZI = 1;public static void main(String[] args) {Fapai t1;Scanner sc = new Scanner(System.in);String ss;System.out.println("開始游戲請輸入 Y , 否則輸入 N");int Person = 0;while ((ss = sc.next()).equals("Y")) {t1 = new Fapai();System.out.println("請輸入參與游戲人數(因牌數限制,人數小于等于17 , 大于1)");sc = new Scanner(System.in);int invol = sc.nextInt();if (!t1.Fp(invol)) {System.out.println("發牌失敗,是否重新發牌");System.out.println("重新發牌輸入 Y , 否則輸入 N");sc = new Scanner(System.in);continue;}for (int i = 0; i < invol; i++) {System.out.println("第" + (i + 1) + "人 牌型:");PrintPoker P = new PrintPoker(t1.p[i]);}for (int i = 0; i < invol; i++) {t1.p[i].BigLevel = new PokerLevel(t1.p[i]).GetBigLevel();if (t1.p[i].BigLevel != 5) {t1.p[i].SmallLevel = new PokerLevel(t1.p[i]).MakeString(0);} else {t1.p[i].SmallLevel = new PokerLevel(t1.p[i]).MakeString(1);}}ArrayListAL1 = new ArrayList<>();for (int i = 0; i < invol; i++) {AL1.add(t1.p[i]);}Collections.sort(AL1, new Comparator() {@Overridepublic int compare(PersonPoker o1, PersonPoker o2) {if (o1.BigLevel != o2.BigLevel) {if (o1.BigLevel > o2.BigLevel)return 1;elsereturn -1;}return o1.SmallLevel.compareTo(o2.SmallLevel);}});int ans = 0;if (AL1.get(0).BigLevel == BAOZI) {for (int i = 1; i < AL1.size(); i++) {int a[] = AL1.get(i).getPokerColour();if (AL1.get(i).SmallLevel.equals("JLM") && a[0] != a[1] && a[1] != a[2] && a[0] != a[2]) {ans = i;break;}}}System.out.println("第 " + AL1.get(ans).person + " 贏了!");System.out.println("\n重新發牌輸入 Y , 否則輸入 N");sc = new Scanner(System.in);}}}

3.發牌分析:

確認是否發牌輸入游戲人數

發牌方式

方式一:直接隨機  牌色   和   牌面值,出現重復牌,重新隨機方式二:為所有牌確定等級(包括花色 4 * 13 張),隨機等級,出現重復等級重新隨機方式三:將所有牌的牌色  和  牌面值  放進兩個List ,對List進行隨機排序,依次取每個人的牌方式四:在方式二的基礎上 也是放進List , 對List 進行隨機排序, 依次取每個人的牌

發牌方式復雜度和操作難度分析

方式一:人數少時速度較快,人數多時,出現重復牌的概率增加(最壞情況  一直取到重復出現的牌)方式二:速度較第一種略快(但是也會出現方式一的最壞情況),分配等級困難很高,預處理static過程出錯不容易查找方式三:static預處理簡單,優化取消了重復牌出現的可能,確定等級過程稍顯復雜(需要一些小思考)方式四:預處理困難,隨機過程內部時間復雜度不確定(感覺挺高),優點是 確定等級的 直接排序過程 得到了優化

發牌:(選擇方式三)

package Fapai;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.HashSet;import java.util.List;import java.util.Random;import java.util.Set;import Save_Pai.PersonPoker;public class Fapai {private static final int PersonNumber = 17;public static PersonPoker p[] = new PersonPoker[PersonNumber];public static ArrayListPkColour = new ArrayList<>();public static ArrayListPkNumber = new ArrayList<>();static {int cnt = 0;for (int i = 0; i < 4; i++) {for (int j = 1; j <= 13; j++) {PkColour.add(i);}cnt++;}for (int i = 1; i <= 13; i++) {for (int j = 1; j <= public="" static="" boolean="" int="" new="" if="" num=""> 17 || num <= 1){return false;}else{int cnt = 0;for (int i = 0; i < num; i++) {int PC[] = new int[3];int PN[] = new int[3];for (int j = 0; j < 3; j++) {PC[j] = PkColour.get(cnt);PN[j] = PkNumber.get(cnt++);}//System.out.println(PC[0] + " " + PC[1] + " " + PC[2]);//System.out.println(PN[0] + " " + PN[1] + " " + PN[2]);p[i] = new PersonPoker(PC , PN);p[i].person = i+1;}return true;}}}

4.輸出每個人的手牌:

比較簡單的對應轉換輸出,不做詳解

package PrintPoker;import Save_Pai.PersonPoker;public class PrintPoker {public PrintPoker(PersonPoker p) {super();OPT(p);}private void OPT(PersonPoker e) {int[] a;int[] b;a = e.getPokerColour();b = e.getPokerNumber();for (int i = 0; i < 3; i++) {OptColour(a[i]);System.out.print(" ");OptNumber(b[i]);if(i != 2)System.out.print(", ");}System.out.println();}private void OptColour(int x) {if(x == 0){System.out.print("方塊");} else if(x == 1){System.out.print("梅花");} else if(x == 2){System.out.print("紅桃");} else {System.out.print("黑桃");}}private void OptNumber(int x) {if(x == 1){System.out.print("A");} else if(x <= 10){System.out.print(x);} else if(x == 11){System.out.print("J");} else if(x == 12){System.out.print("Q");} else if(x == 13){System.out.print("K");}}}

5.確定發牌等級(最重要的處理步驟):

首先確定手牌的大等級:

豹子 > 同花順 > 同花 > 順子 > 對子 > 單牌

特殊牌:三張不同花色的235不做單獨考慮,后面出現豹子獲勝的人,再特判即可

確定小等級:

最容易的思路就是把同一等級的所有小等級全部按順序編號,但這違背方法三的初衷(取消復雜的小等級確定過程)

通過思考   除了對子    的小牌等級   比較大小  方式比較特殊,其他的牌均相同

對子:先比較對牌的大小,對子牌相同,比較單牌大小

其他等級:A (1)> K(13) > Q(12) > J(11) > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2

因為直接用這種數字比較,大小的概念是很難 確定的,實現起來繁瑣冗雜

可以將13個數字(其中1=A,13=K,12=Q,11=J)

變換為:

11312111098765432

ABCDEFGHIJKLM

這種改寫方式可以直接將牌的大小 用字符串的  compareTo方法進行比較

對子:只需要先以上面表格的方式作為小等級的前兩個字符,其他的不變即可

package PokerLevel;import Save_Pai.PersonPoker;public class PokerLevel {PersonPoker p;private static final int BaoZi = 1;private static final int TongHuaShun = 2;private static final int TongHua = 3;private static final int ShunZi = 4;private static final int DuiZi = 5;private static final int DanZhang = 6;public PokerLevel(PersonPoker p) {super();this.p = p;}public String MakeString(int cek) {char[] a = new char[3];int cnt = 0;char ch = "A";int Number[] = p.getPokerNumber();int CalNum[] = new int[15];for (int i = 0; i < 3; i++) {CalNum[Number[i]]++;}if (cek == 0) {while (CalNum[1] > 0) {a[cnt++] = ch;CalNum[1]--;}for (int i = 13; i > 1; i--) {++ch;while (CalNum[i] > 0) {a[cnt++] = ch;CalNum[i]--;}if (cnt == 3)break;}return new String(a);} else {if (CalNum[1] == 2) {a[0] = a[1] = ch;CalNum[1] = 0;} else {for (int i = 13; i > 1; i--) {++ch;if (CalNum[i] == 2) {a[0] = a[1] = ch;CalNum[i] = 0;break;}}}ch = "A";if(CalNum[1] == 1)a[2] = ch;for(int i = 13 ; i > 1 ; i--){++ch;if(CalNum[i] == 1){a[2] = ch;break;}}return new String(a);}}public int GetBigLevel() {int Colour[] = p.getPokerColour();int Number[] = p.getPokerNumber();int CalCol[] = new int[5];int CalNum[] = new int[15];for (int i = 0; i < 3; i++) {CalCol[Colour[i]]++;}for (int i = 0; i < 3; i++) {CalNum[Number[i]]++;}// 豹子if (isBaoZi(CalNum)) {return BaoZi;}if (isTongHua(CalCol)) {// 同花順if (isShunZi(CalNum)) {return TongHuaShun;}// 同花return TongHua;}// 順子if (isShunZi(CalNum)) {return ShunZi;}// 對子if (isDuiZi(CalNum)) {return DuiZi;}// 單牌return DanZhang;}private boolean isDuiZi(int[] a) {for (int i = 1; i <= 1="" if="" return="" private="" boolean="" for="" int="" i="">= 3; i--) {if (a[i] == 1 && a[i - 1] == 1 && a[i - 2] == 1) {return true;}}return false;}private boolean isTongHua(int a[]) {for (int i = 0; i < 4; i++) {if (a[i] == 3)return true;}return false;}private boolean isBaoZi(int a[]) {for (int i = 13; i >= 1; i--) {if (a[i] == 3) {return true;}}return false;}}

回到主程序:

我們將每個人的手牌JavaBean塞到List里,運用Collections工具類,重寫實現內部類,進行排序

直接獲取第一個人的ID

特判:如果此時獲勝者是 豹子 手牌,則在List內遍歷是否有牌面為235,且三張牌不同花色  的人,如果找到,更改ans存的ID

輸出獲勝者ID

責任編輯:

標簽:

相關推薦:

精彩放送:

新聞聚焦
Top 岛国精品在线