一)在无癞子牌的时候手牌能否胡
设计过程:首先判断玩家是否缺一门,能否胡手牌和对对胡(能否胡牌判读是否为顺子和一个对子)
/**
* 手牌能否胡
* @param paiList 所有手牌
* @param show 碰杠牌堆
* @param laiZi 癞子牌
* @return
*/
public static boolean fitHu(List<Integer> paiList, List<Integer> show, Integer laiZi){
boolean huPai=false;
List<Integer> allPai = new ArrayList<>(paiList);
allPai.addAll(show);
if (!isQueYiMen(allPai,laiZi)) {//判断是否缺一门
return huPai;
}
int[][] memberPai = changeToArr(paiList);
if (huPai(memberPai)) {//能否胡牌
huPai = true;
} else {
if (show == null || show.size() == 0) {
if (duiduiHu(memberPai)){//特殊-对对胡
huPai = true;
}
}
}
return huPai;
}
/**
* 胡手牌
*
* @param allPai
* @return
*/
public static boolean huPai(int[][] allPai) {
int duiZi = 0;// 哪一组牌中存在对子
int yuShu = 0;
boolean duiZiExisted = false;
for (int i = 0; i < 3; i++) {//allPai[i][0] ——某种类型(筒、万、条)牌的数量
yuShu = allPai[i][0] % 3;
if (yuShu == 1) {
return false;
}
if (yuShu == 2) {
if (duiZiExisted) {
return false;
}
duiZi = i;
duiZiExisted = true;
}
}
for (int i = 0; i < 3; i++) {
if (i != duiZi) {
int[] temp = new int[10];
for (int j = 0; j <= 9; j++) {
temp[j] = allPai[i][j];
}
if (!analyze(temp, i == 3)) {
return false;
}
}
}
boolean success = false;
for (int j = 1; j <= 9; j++) {
if (allPai[duiZi][j] >= 2) {
allPai[duiZi][j] = allPai[duiZi][j] - 2;
allPai[duiZi][0] = allPai[duiZi][0] - 2;
int[] temp = new int[10];
for (int k = 0; k <= 9; k++) {
temp[k] = allPai[duiZi][k];
}
if (analyze(temp, duiZi == 3)) {
success = true;
}
allPai[duiZi][j] = allPai[duiZi][j] + 2;
allPai[duiZi][0] = allPai[duiZi][0] + 2;
if (success) {
break;
}
}
}
return success;
}
/**
* 分析每一种牌是否符合
* @param aKindPai
* @param ziPai
* @return
*/
public static boolean analyze(int[] aKindPai, boolean ziPai) {
if (aKindPai[0] == 0) {
return true;
}
int index = 0;
for (int i = 1; i <= 9; i++) {
if (aKindPai[i] != 0) {
index = i;
break;
}
}
boolean result = false;
if (aKindPai[index] >= 3) {
aKindPai[index] = aKindPai[index] - 3;
aKindPai[0] = aKindPai[0] - 3;
result = analyze(aKindPai, ziPai);//回调处理
aKindPai[index] = aKindPai[index] + 3;
aKindPai[0] = aKindPai[0] + 3;
return result;
}
if (!ziPai && index < 8 && aKindPai[index + 1] > 0
&& aKindPai[index + 2] > 0) {
aKindPai[index] = aKindPai[index] - 1;
aKindPai[index + 1] = aKindPai[index + 1] - 1;
aKindPai[index + 2] = aKindPai[index + 2] - 1;
aKindPai[0] = aKindPai[0] - 3;
result = analyze(aKindPai, ziPai);
aKindPai[index] = aKindPai[index] + 1;
aKindPai[index + 1] = aKindPai[index + 1] + 1;
aKindPai[index + 2] = aKindPai[index + 2] + 1;
aKindPai[0] = aKindPai[0] + 3;
return result;
}
return false;
}
二)简单测试
public static void main(String[] args) {
List<Integer> initPais = new ArrayList<>();
initPais.add(11);
initPais.add(11);
initPais.add(13);
initPais.add(14);
initPais.add(15);
initPais.add(16);
initPais.add(17);
initPais.add(18);
List<Integer> show = new ArrayList<>();
show.add(19);//碰牌 9万
show.add(19);
show.add(19);
show.add(21);//杠牌 1条
show.add(21);
show.add(21);
show.add(21);
Integer laiZi = 32;
boolean canHu = fitHu(initPais, show, laiZi);
System.out.println("canHu? " + canHu);
}
结果 canHu ? true
三)手牌中有癞子牌时
/**
* 加入一张赖子牌,判断该手牌能不能胡,返回胡牌集合
*
* @param allPai
* @return huData.size()>0则表示可以胡牌
*/
public static List<List<Integer>> huLaizi(List<Integer> list, Integer laizi, List<Integer> show) {
int[][] allPai = changeToArr(list);
int laiziNum = allPai[laizi / 10 - 1][laizi % 10];//癞子牌数量
allPai[laizi / 10 - 1][laizi % 10] = 0;
allPai[laizi / 10 - 1][0] = allPai[laizi / 10 - 1][0] - laiziNum;//这种牌去掉癞子牌以后剩余牌数量
List<Integer> tingTable = quePai(allPai);//听的牌的集合
tingTable.add(laizi);
if (laiziNum > 0) {
for(int pai : list){
if (pai != laizi && !tingTable.contains(pai)) {
tingTable.add(pai);
}
}
}
List<List<Integer>> huData = new ArrayList<List<Integer>>();//存放癞子牌的转换牌型
tingTable.addAll(quePai2(allPai, laizi, laiziNum));//带癞子的七小对的缺牌
if (laiziNum == 1) {
for (Integer pai : tingTable) {//遍历听牌集合,用一张癞子牌替换判断此时可否胡
int yu = pai / 10 - 1;
int mod = pai % 10;
allPai[yu][mod] = allPai[yu][mod] + 1;
allPai[yu][0] = allPai[yu][0] + 1;
if (fitHu(arrToList(allPai), show, laizi)) {//所有的牌和展示的牌符合胡
List<Integer> data = new ArrayList<Integer>();//癞子牌替换到可以胡牌的牌,如11-13,听牌12,癞子牌替换为12
d