/*牌面数字使用:2 3 4 5 6 7 8 9 T J Q K A
花色:黑桃:B, 红桃:R, 棉花:M, 方块:F一手牌就是:
B2M2R3RJRK
(一张黑桃2,一张棉花2,一张红桃3,一张红桃J,一张红桃K)比较规则:首先约定,这些牌面首先使用这些数字符号表示
// 单张 一对 两对 三张 顺子 同花 满堂红四张同花顺
// 0 1 2 3 4 5 6 7 8实现两个功能:
①假如一手牌,就是这样的包含10个字符的一个字符串,那么请实现一个方法,能判定当前这手牌是什么牌
public int getCardSign(String cards);
传入参数:一手牌,也就是5张牌
返回值:该牌的数字符号
②现在给定两手牌,请帮我比较大小
public boolean compareCards(String cardsFirst, String cardsSecond);
传入参数:两手牌
返回值:布尔值,返回true表示cardsFirst大于cardsSecond,返回false,表示cardsSecond大于cardsFirst
比较规则:
0 < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8
然后,出现:两手牌的数字符号一样,请按照花色等自定义规则在继续比较。一定要比出个大小。备注:详细德州扑克的规则,请自行查询。
*/
没进行优化,主要思想就是如下
package pokeruser;
import java.util.Scanner;
/**
*
* <p>Title: UserTest</p>
* @author Carl_蔡先生
* @date 2019年9月15日下午4:55:27
* 描述:功能实现:
* 1.用户输入两副牌
* 2.德州扑克规则level:
* 1)手中存在且仅存在一个对子--一对 如M4F4R7B3R5
* 2)手中存在两个对子--两对 如M4F4R9B5R5
* 3)手中存在且仅存在三张相同牌面值的牌--三张 如M4F4R4B3R5
* 4)手中存在五张连续的牌--顺子 如MAF2R3B4R5
* 5)手中存在五张花色相同的牌且不需要连续--同花 如F2F6F5F9F8
* 6)手中存在三张相同牌面值的牌且存在一对--满堂红 如B2M2F2R3M3
* 7)手中存在四张相同牌面值的牌--四条 如:BQMQFQRQMA
* 8)在同花的基础上牌面值连续--同花顺
* 0)以上都不存在则为烂牌
* 3.异常: 牌面值越界异常,牌面值不在给定区域
* 花色值越界异常,花色不在给定区域
* 牌数不合法,同花色牌的牌面值相同不符合要求
*
*/
public class UserTest {
public static void menu() {
System.out.println("***********************欢迎来到德州扑克界面*********************************");
//做一个菱形*主要是用于排版。。可以忽略
for(int i=1;i<=5;i++) {
for(int k=5;k>i;k--)
System.out.print(" \t");
for(int j=1;j<=2*i-1;j++) {
System.out.print("*\t");
}
System.out.println();
}
for(int i=4;i>0;i--) {
for(int k=4;k>=i;k--)
System.out.print(" \t");
for(int j=1;j<=2*i-1;j++) {
System.out.print("*\t");
}
System.out.println();
}
System.out.println("**************************************************************************");
System.out.println();
System.out.println("\t*********************游戏说明:************************* *");
System.out.println("\t*请按要求输入您的牌:花色+牌值为一张牌 *\n"
+ "\t*示例:BAM2R3R4R5 *\n"
+ "\t*要求花色使用:黑桃:B, 红桃:R, 棉花:M, 方块:F *\n"
+ "\t*牌面数字使用:2 3 4 5 6 7 8 9 T J Q K A *");
System.out.println("\t*********************比较规则:************************* *\n"
+ "\t*0.烂牌 *\n"
+ "\t*1.一对 *\n"
+ "\t*2.两对 *\n"
+ "\t*3.三张 *\n"
+ "\t*4.顺子 *\n"
+ "\t*5.同花 *\n"
+ "\t*6.满堂红 *\n"
+ "\t*7.四条 *\n"
+ "\t*8.同花顺 *\n"
+ "\t*********************原则:************************* *\n"
+ "\t*优先比较等级大小, *\n"
+ "\t*若等级相同,则比较花色,"
+ "花色重复数多者为胜 *\n"
+ "\t*若花色数相同,则按花色等级比较 *\n"
+ "\t*花色等级B>R>M>F *\n"
+ "\t*如果花色等级也相同, *\n"
+ "\t*则比较牌面值的总点数,总点数大者胜 *\n");
System.out.println("*************************************************************************");
System.out.println();
}
public static void main(String[] args) throws Exception {
Scanner sc=new Scanner(System.in);
menu();
System.out.println("下面请输入你的手牌:");
String str_First=sc.next();
System.out.println("下面请输入对手的手牌:");
String str_Second=sc.next();
Board b=new Board();
boolean flag=b.compareCards(str_First,str_Second);
if(flag) {
System.out.println("您的手牌大于对家手牌!恭喜获胜!");
}else {
System.out.println("您的手牌小于对家手牌!请继续努力!");
}
// System.out.println("返回true表示cardsFirst大于cardsSecond,\n"
// + "返回false,表示cardsSecond大于cardsFirst");
}
}
package pokeruser;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
class Board{
// private char[] arr= {'1','2','3','4','5','6','7','8','9','T','J','Q','K'};//牌面数字
// private char[] color= {'B','R','M','F'};//花色
// private char[] rule= {0,1,2,3,4,5,6,7,8};
//牌面值
public String getCardArr(char s) throws Exception {//2
String str="";
//判断牌面值
switch(s) {
case 'A':
str="A";
break;
case '2':
str="2";
break;
case '3':
str="3";
break;
case '4':
str="4";
break;
case '5':
str="5";
break;
case '6':
str="6";
break;
case '7':
str="7";
break;
case '8':
str="8";
break;
case '9':
str="9";
break;
case 'T':
str="T";
break;
case 'J':
str="J";
break;
case 'Q':
str="Q";
break;
case 'K':
str="K";
break;
default:
throw new Exception("牌面值越界输入异常");
}
return str;
}
/**
* //匹配花色与牌面
* @param cards
* @return
* @throws Exception
*/
public int getCardSign(String cards) throws Exception {
String s="";
String s1="";
//接收花色
for(int i=0;i<cards.length();i+=2) {
s1+=cards.charAt(i)+"";
}
//接收牌面值
for(int i=1;i<cards.length();i+=2) {
s+=cards.charAt(i)+"";
}
//判断花色
for(int i=0;i<s1.length();i++) {
switch(s1.charAt(i)) {
case 'B':
System.out.println("黑桃"+getCardArr(s.charAt(i)));
break;
case 'R':
System.out.println("红桃"+getCardArr(s.charAt(i)));
break;
case 'M':
System.out.println("梅花"+getCardArr(s.charAt(i)));
break;
case 'F':
System.out.println("方块"+getCardArr(s.charAt(i)));
break;
default:
throw new Exception("花色值越界输入异常");
}
}
System.out.print("该牌为:");
return getCardslevel(s,s1);
}
/**
* //牌值的等级
* @param s:牌面
* @param s1:花色
*/
public int getCardslevel(String s,String s1) {
//count_s用于统计牌面相同值
int count_s=0;
//level用于设置等级,默认为0
int level = 0;
//遍历字符串
for(int i=0;i<s.length();i++) {
for(int j=i+1;j<s.length();j++) {
//比较值是否相同
if((s.charAt(i)+"").equals((s.charAt(j)+""))){
count_s++;
}
}
}
switch(count_s) {
case 1://两张相同
level=1;
System.out.println("一对");
break;
case 2://两对牌相同
level=2;
System.out.println("两对");
break;
case 3://三张相同
level=3;
System.out.println("三张");
break;
case 4://3+2
level=6;
System.out.println("满堂红");
break;
case 6://四张相同
level=7;
System.out.println("四条");
break;
default:
level=getCardsColor(s,s1);
}
System.out.println("level="+level+"\n");
return level;
}
/**
* //判断花色
* @param s
* @param s1
* @return
*/
public int getCardsColor(String s,String s1) {
//count_s1用于统计花色相同值
int count_s1=0;
int level=0;
//遍历字符串
for(int i=0;i<s1.length();i++) {
for(int j=i+1;j<s1.length();j++) {
//比较值是否相同
if((s1.charAt(i)+"").equals((s1.charAt(j)+""))){
count_s1++;
}
}
}
switch(count_s1) {
case 10:
level=5;
System.out.print("同花");
if(transition(s)==true) {
level=8;
System.out.println("顺");
}else {
System.out.println();
}
break;
default:
if(transition(s)==true) {
level=4;
System.out.println("顺子");
}else {
System.out.println("杂牌");
}
}
return level;
}
/**
* //牌面值 其他字符转换成数字
* @param s
* @return
*/
public boolean transition(String s) {//173JK
char[] a=s.toCharArray();
int[] b=new int[a.length];
for(int j=0;j<a.length;j++) {
if (Character.isDigit(a[j])){ // 判断是否是数字
b[j]= Integer.parseInt(String.valueOf(a[j]));
} else if(a[j]=='T') {
b[j]=10;
}else if(a[j]=='J') {
b[j]=11;
}else if(a[j]=='Q') {
b[j]=12;
}else if(a[j]=='K') {
b[j]=13;
}else if(a[j]=='A') {
b[j]=1;
}
//System.out.println(b[j]);
}
return isNStraightHand(b, b.length);
}
/**
* //将预处理好的数组作为形参传入,判断是不是顺子
* @param b
* @param length
* @return
*/
public boolean isNStraightHand(int[] b, int length) {
if (b == null || b.length == 0 || b.length % length != 0) {
return false;
}
// 数组排序
Arrays.sort(b);
//并将元素及其出现次数存储在 map 中
Map<Integer, Integer> map = new HashMap<>();
for (int i : b) {
//将元素存储到map并存储其默认值为1
map.put(i, map.getOrDefault(i, 0) + 1);
}
for (int h : b) {
//首先判断该键的默认值是否大于0
if (map.get(h) > 0) {
for (int j = 0; j < length; j++) {
// 判断 map 中以h为首的连续数字是不是所有元素构成顺子
if (map.getOrDefault(h + j, 0) > 0) {
map.put(h + j, map.get(h + j) - 1);//把默认值还原为0,为下一次遍历做准备
} else {
return false;
}
}
}
}
return true;
}
/**
* //以花色作为比较大小的标准,哪边花色多则大,若一样多则花色等级大则大,若花色等级相同则比较总点数
* @param cardsFirst
* @param cardsSecond
* @return
*/
public boolean ColorBord(String cardsFirst, String cardsSecond) {
String s_first="";
String s1_Second="";
for(int i=0;i<cardsFirst.length();i+=2) {
s_first+=cardsFirst.charAt(i)+"";
}
for(int i=0;i<cardsSecond.length();i+=2) {
s1_Second+=cardsSecond.charAt(i)+"";
}
//System.out.println(s_first+"=="+s1_Second);
char[] a=s_first.toCharArray();
int[] b=new int[a.length];
System.out.println("您的手牌花色等级:");
for(int j=0;j<a.length;j++) {
if(a[j]=='B') {
b[j]=4;
}else if(a[j]=='R') {
b[j]=3;
}else if(a[j]=='M') {
b[j]=2;
}else if(a[j]=='F') {
b[j]=1;
}
System.out.print(b[j]);
}
System.out.println();
char[] a1=s1_Second.toCharArray();
int[] b1=new int[a1.length];
System.out.println("对家手牌花色等级:");
for(int j=0;j<a1.length;j++) {
if(a1[j]=='B') {
b1[j]=4;
}else if(a1[j]=='R') {
b1[j]=3;
}else if(a1[j]=='M') {
b1[j]=2;
}else if(a1[j]=='F') {
b1[j]=1;
}
System.out.print(b1[j]);
}
System.out.println();
int count=1;
int count1=1;
int n=0;
Arrays.sort(b);
Arrays.sort(b1);
for(int i=0;i<b.length-1;i++) {
if(b[i]==b[i+1]) {
count++;
n=i;
}
}
for(int i=0;i<b1.length-1;i++) {
if(b1[i]==b1[i+1]) {
count1++;
}
}
// System.out.println("重复花色数为:"+count+"===="+count1);
if(count<count1) {
return false;
}else if(count==count1) {
if(b[n]<b1[n]) {
return false;
}else if(b[n]==b1[n]) {
System.out.println("两副牌等级相同,花色等级也相同,进行总点数比较:");
return ValueBord(cardsFirst,cardsSecond);
}
}
return true;
}
/**
* //比较总点数,所有牌面值的和最大者胜
* @param cardsFirst
* @param cardsSecond
* @return
*/
public boolean ValueBord(String cardsFirst,String cardsSecond) {
String s_first="";
String s1_Second="";
for(int i=1;i<cardsFirst.length();i+=2) {
s_first+=cardsFirst.charAt(i)+"";
}
for(int i=1;i<cardsSecond.length();i+=2) {
s1_Second+=cardsSecond.charAt(i)+"";
}
char[] a=s_first.toCharArray();
int[] b=new int[a.length];
for(int j=0;j<a.length;j++) {
if (Character.isDigit(a[j])){ // 判断是否是数字
b[j]= Integer.parseInt(String.valueOf(a[j]));
} else if(a[j]=='T') {
b[j]=10;
}else if(a[j]=='J') {
b[j]=11;
}else if(a[j]=='Q') {
b[j]=12;
}else if(a[j]=='K') {
b[j]=13;
}else if(a[j]=='A') {
b[j]=1;
}
}
char[] a1=s1_Second.toCharArray();
int[] b1=new int[a1.length];
for(int j=0;j<a1.length;j++) {
if (Character.isDigit(a1[j])){ // 判断是否是数字
b1[j]= Integer.parseInt(String.valueOf(a1[j]));
} else if(a1[j]=='T') {
b1[j]=10;
}else if(a1[j]=='J') {
b1[j]=11;
}else if(a1[j]=='Q') {
b1[j]=12;
}else if(a1[j]=='K') {
b1[j]=13;
}else if(a1[j]=='A') {
b1[j]=1;
}
}
int s=0;
int s1=0;
for(int i=0;i<b.length;i++) {
s+=b[i];
}
System.out.println("您的手牌总点数:"+s);
for(int i=0;i<b1.length;i++) {
s1+=b1[i];
}
System.out.println("对家手牌总点数:"+s1);
if(s<s1) {
return false;
}
return true;
}
/**
* //如果两副牌出现相同花色的牌面值也相同则抛出异常
* @param cardsFirst
* @param cardsSecond
* @return
* @throws Exception
*/
public void overCards(String cardsFirst, String cardsSecond) throws Exception {
String s_first="";
String s1_first="";
String s_Second="";
String s1_Second="";
//接收花色
for(int i=0;i<cardsFirst.length();i+=2) {
s_first+=cardsFirst.charAt(i)+"";
}
//接收牌面值
for(int i=1;i<cardsFirst.length();i+=2) {
s1_first+=cardsFirst.charAt(i)+"";
}
//System.out.println(s_first+""+s1_first);//MRMMR22211
//接收花色
for(int i=0;i<cardsSecond.length();i+=2) {
s_Second+=cardsSecond.charAt(i)+"";
}
//接收牌面值
for(int i=1;i<cardsSecond.length();i+=2) {
s1_Second+=cardsSecond.charAt(i)+"";
}
//System.out.println(s_Second+""+s1_Second);//BMRRR12345
for(int i=0;i<s1_first.length();i++) {//遍历牌1的牌值
for(int k=0;k<s1_Second.length();k++) {//遍历牌2的牌值
//System.out.println((s1_first.charAt(i)+"").equals(s1_Second.charAt(k)+""));
if((s1_first.charAt(i)+"").equals(s1_Second.charAt(k)+"")) {//如果牌值相同
if((s_first.charAt(i)+"").equals(s_Second.charAt(k)+"")) {//比较花色
throw new Exception("牌数不合法");
}
}
}
}
}
/**
* //比较两副牌
* @param cardsFirst
* @param cardsSecond
* @return
* @throws Exception
*/
public boolean compareCards(String cardsFirst, String cardsSecond) throws Exception {
//判断牌是否合法
overCards(cardsFirst,cardsSecond);
boolean flag=false;
System.out.println("**********您的手牌为:***************");
int f=getCardSign(cardsFirst);
System.out.println("**********对家的手牌为:*************");
int s=getCardSign(cardsSecond);
if(f>s) {
flag=true;
}else if(f==s) {
System.out.println("两副牌等级相同,进行花色比较:");
if(cardsFirst.equals(cardsSecond)) {
System.out.println("同一副牌");
}else {
//比较花色,花色多者胜,若花色数量相同,则比较B>R>M>F
return ColorBord(cardsFirst,cardsSecond);
}
}
return flag;
}
}
实现结果:
***********************欢迎来到德州扑克界面*********************************
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
* * * * * * *
* * * * *
* * *
*
**************************************************************************
*********************游戏说明:************************* *
*请按要求输入您的牌:花色+牌值为一张牌 *
*示例:BAM2R3R4R5 *
*要求花色使用:黑桃:B, 红桃:R, 棉花:M, 方块:F *
*牌面数字使用:2 3 4 5 6 7 8 9 T J Q K A *
*********************比较规则:************************* *
*0.烂牌 *
*1.一对 *
*2.两对 *
*3.三张 *
*4.顺子 *
*5.同花 *
*6.满堂红 *
*7.四条 *
*8.同花顺 *
*********************原则:************************* *
*优先比较等级大小, *
*若等级相同,则比较花色,花色重复数多者为胜 *
*若花色数相同,则按花色等级比较 *
*花色等级B>R>M>F *
*如果花色等级也相同, *
*则比较牌面值的总点数,总点数大者胜 *
*************************************************************************
下面请输入你的手牌:
B3F5M4M6R7
下面请输入对手的手牌:
F9FTMJRQBK
**********您的手牌为:***************
黑桃3
方块5
梅花4
梅花6
红桃7
该牌为:顺子
level=4
**********对家的手牌为:*************
方块9
方块T
梅花J
红桃Q
黑桃K
该牌为:顺子
level=4
两副牌等级相同,进行花色比较:
您的手牌花色等级:
41223
对家手牌花色等级:
11234
您的手牌大于对家手牌!恭喜获胜!