概述
一)在无癞子牌的时候手牌能否胡
设计过程:首先判断玩家是否缺一门,能否胡手牌和对对胡(能否胡牌判读是否为顺子和一个对子)
/**
* 手牌能否胡
* @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
data.add(pai);
huData.add(data);
}
allPai[yu][mod] = allPai[yu][mod] - 1;
allPai[yu][0] = allPai[yu][0] - 1;
}
} else if (laiziNum == 2) {
for (Integer pai1 : tingTable) {
for (Integer pai2 : tingTable) {
int yu1 = pai1 / 10 - 1;
int mod1 = pai1 % 10;
int yu2 = pai2 / 10 - 1;
int mod2 = pai2 % 10;
allPai[yu1][mod1] = allPai[yu1][mod1] + 1;
allPai[yu2][mod2] = allPai[yu2][mod2] + 1;
allPai[yu1][0] = allPai[yu1][0] + 1;
allPai[yu2][0] = allPai[yu2][0] + 1;
// ystem.out.println("pai1"+pai1+"pai2:"+pai2);
if (pai1 == 16 && pai2 == 37) {
//
int i = 0;
}
if (fitHu(arrToList(allPai), show, laizi)) {
List<Integer> data = new ArrayList<Integer>();
data.add(pai1);
data.add(pai2);
huData.add(data);
}
allPai[yu1][mod1] = allPai[yu1][mod1] - 1;
allPai[yu2][mod2] = allPai[yu2][mod2] - 1;
allPai[yu1][0] = allPai[yu1][0] - 1;
allPai[yu2][0] = allPai[yu2][0] - 1;
}
}
} else if (laiziNum == 3) {
for (Integer pai1 : tingTable) {
for (Integer pai2 : tingTable) {
for (Integer pai3 : tingTable) {
int yu1 = pai1 / 10 - 1;
int mod1 = pai1 % 10;
int yu2 = pai2 / 10 - 1;
int mod2 = pai2 % 10;
int yu3 = pai3 / 10 - 1;
int mod3 = pai3 % 10;
allPai[yu1][mod1] = allPai[yu1][mod1] + 1;
allPai[yu2][mod2] = allPai[yu2][mod2] + 1;
allPai[yu3][mod3] = allPai[yu3][mod3] + 1;
allPai[yu1][0] = allPai[yu1][0] + 1;
allPai[yu2][0] = allPai[yu2][0] + 1;
allPai[yu3][0] = allPai[yu3][0] + 1;
if (fitHu(arrToList(allPai), show, laizi)) {
List<Integer> data = new ArrayList<Integer>();
data.add(pai1);
data.add(pai2);
data.add(pai3);
huData.add(data);
}
allPai[yu1][mod1] = allPai[yu1][mod1] - 1;
allPai[yu2][mod2] = allPai[yu2][mod2] - 1;
allPai[yu3][mod3] = allPai[yu3][mod3] - 1;
allPai[yu1][0] = allPai[yu1][0] - 1;
allPai[yu2][0] = allPai[yu2][0] - 1;
allPai[yu3][0] = allPai[yu3][0] - 1;
}
}
}
} else if (laiziNum == 4) {//四张癞子牌替换四张在听到的牌,看能否胡牌
for (Integer pai1 : tingTable) {//替换的第一张听牌
for (Integer pai2 : tingTable) {//替换的第二张
for (Integer pai3 : tingTable) {//替换第三张
for (Integer pai4 : tingTable) {//替换第四张
int yu1 = pai1 / 10 - 1;
int mod1 = pai1 % 10;
int yu2 = pai2 / 10 - 1;
int mod2 = pai2 % 10;
int yu3 = pai3 / 10 - 1;
int mod3 = pai3 % 10;
int yu4 = pai4 / 10 - 1;
int mod4 = pai4 % 10;
allPai[yu1][mod1] = allPai[yu1][mod1] + 1;
allPai[yu2][mod2] = allPai[yu2][mod2] + 1;
allPai[yu3][mod3] = allPai[yu3][mod3] + 1;
allPai[yu4][mod4] = allPai[yu4][mod4] + 1;
allPai[yu1][0] = allPai[yu1][0] + 1;
allPai[yu2][0] = allPai[yu2][0] + 1;
allPai[yu3][0] = allPai[yu3][0] + 1;
allPai[yu4][0] = allPai[yu4][0] + 1;
if (fitHu(arrToList(allPai), show, laizi)) {
List<Integer> data = new ArrayList<Integer>();
data.add(pai1);
data.add(pai2);
data.add(pai3);
data.add(pai4);
huData.add(data);
}
allPai[yu1][mod1] = allPai[yu1][mod1] - 1;
allPai[yu2][mod2] = allPai[yu2][mod2] - 1;
allPai[yu3][mod3] = allPai[yu3][mod3] - 1;
allPai[yu4][mod4] = allPai[yu4][mod4] - 1;
allPai[yu1][0] = allPai[yu1][0] - 1;
allPai[yu2][0] = allPai[yu2][0] - 1;
allPai[yu3][0] = allPai[yu3][0] - 1;
allPai[yu4][0] = allPai[yu4][0] - 1;
}
}
}
}
}
return huData;
}
/**把数组牌转为list牌集
* @param paiArr
*/
public static List<Integer> arrToList(int[][] paiArr) {
List<Integer> paiList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
int paiNum = paiArr[i][j];//根据每一张牌的数量逆转
if (paiNum <= 0) {
continue;
}
for (int k = 0; k < paiArr[i][j]; k++) {
paiList.add((i+1) * 10 + j);
}
}
}
return paiList;
}
/**
* 麻将缺什么牌 型完整
*
* @param allPai
* @return
*/
public static List<Integer> quePai(int[][] allPai) {
int pai = 0;
List<Integer> tingTable = new ArrayList<>();
for (int i = 1; i <= 3; i++) {
List<Integer> duizi = new ArrayList<Integer>();
for (int j = 1; j <= 9; j++) {//遍历每一张牌,统计每张牌组合牌型
pai = 10 * i + j;
int yu = pai / 10 - 1;
int mod = pai % 10;
// 是否有对子
int size = allPai[yu][mod];//这种牌pai张数
if (size == 0) {
continue;
}
boolean hasShun = shunFilter(allPai, pai, tingTable);
if (size == 2 && !hasShun) {//没有带顺序的牌 并且是一对的
duizi.add(pai);
}
if (size == 2 && hasShun) {//有带顺序的牌 并且是一对的
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
if (size == 2) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
if (size == 3 && hasShun) {
duizi.add(pai);
}
}
if (duizi.size() > 1) {
for (Integer data : duizi) {
if (!tingTable.contains(data)) {
tingTable.add(data);
}
}
}
}
// 连续牌缺牌的整体判断
for (int i = 1; i <= 3; i++) {
Map<Integer, Integer> shun = new HashMap<Integer, Integer>();
int max = 0;
int start = 0;
int yu = i - 1;
for (int j = 1; j <= 9; j++) {
int next = 1;
start = j;
for (int k = j; k <= 8; k++) {
if (allPai[yu][k] > 0 && allPai[yu][k + 1] > 0) {
next++;
} else {
break;
}
}
if (next > 3) {
shun.put(start, next);
}
if (next > max) {
max = next;
}
}
for (Map.Entry<Integer, Integer> entry : shun.entrySet()) {
for (int k = 0; k < entry.getValue(); k++) {
pai = 10 * i + entry.getKey() + k;
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
if (entry.getKey() > 1) {
pai = 10 * i + entry.getKey() - 1;
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
int end = entry.getKey() + entry.getValue();
if (end < 10) {
pai = 10 * i + end;
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
}
shun.clear();
}
return tingTable;
}
/**带癞子的七小对的缺牌
* @param allPai 所有手牌(除碰杠牌)
* @param laizi
癞子牌
* @param laiziNum
癞子牌数量
* @return
*/
public static List<Integer> quePai2(int[][] allPai , int laizi ,int laiziNum) {
int pai = 0;
int duiziNum = 0;
List<Integer> tingTable = new ArrayList<Integer>();
List<Integer> singlePai = new ArrayList<Integer>();//单张牌
List<Integer> threePai = new ArrayList<Integer>();//3张牌
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 9; j++) {
pai = 10 * i + j;
int yu = pai / 10 - 1;
int mod = pai % 10;
// 是否有对子
int size = allPai[yu][mod];
if (size == 0) {
continue;
}
if (size == 1) {
singlePai.add(pai);
}
if (size == 2 ) {
duiziNum ++;
}
if (size == 3) {//龙七对
threePai.add(pai);
}
}
}
if (laiziNum == 1 && duiziNum == 6) {
tingTable.addAll(singlePai);
}else if (laiziNum == 2 && duiziNum == 5) {
tingTable.addAll(singlePai);
}else if (laiziNum == 3 && duiziNum == 4) {
tingTable.addAll(singlePai);
}else if (laiziNum == 4 && duiziNum == 3 ) {
tingTable.addAll(singlePai);
}
if (threePai.size() == 1 && duiziNum == 5) {
tingTable.addAll(threePai);
}
return tingTable;
}
/**
* 是否带顺序的牌及其听牌
*
* @param allPai
手牌(不包含癞子牌)
* @param pai
模拟加入某张牌
* @param tingTable
听牌列表
* @return
*/
private static boolean shunFilter(int[][] allPai, int pai, List<Integer> tingTable) {
int yu = pai / 10 - 1;//
int paiNum = pai % 10;//牌号:1——9筒万条
// 是否有对子
int size = allPai[yu][paiNum];//某种牌数量
boolean hasShun = false;
// 先进性边张判断1-9,2-8,最后3——7,顺子的判断
if (paiNum == 9) {
if (allPai[yu][paiNum - 1] >= 1 && allPai[yu][paiNum - 2] >= 1) {
hasShun = true;
if (size >= 2 && allPai[yu][paiNum - 1] >= 2) {
if (!tingTable.contains(pai - 2)) {
tingTable.add(pai - 2);
}
}
if (size >= 2 && allPai[yu][paiNum - 2] >= 2) {
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
}
} else if (allPai[yu][paiNum - 1] >= 1) {
if (!tingTable.contains(pai - 2)) {
tingTable.add(pai - 2);
}
hasShun = true;
} else if (allPai[yu][paiNum - 2] >= 1) {
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
hasShun = true;
} else {
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
}
} else if (paiNum == 1) {
if (allPai[yu][paiNum + 1] >= 1 && allPai[yu][paiNum + 2] >= 1) {
hasShun = true;
if (size >= 2 && allPai[yu][paiNum + 1] >= 2) {
if (!tingTable.contains(pai + 2)) {
tingTable.add(pai + 2);
}
}
if (size >= 2 && allPai[yu][paiNum + 2] >= 2) {
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
}
} else if (allPai[yu][paiNum + 1] >= 1) {
if (!tingTable.contains(pai + 2)) {
tingTable.add(pai + 2);
}
hasShun = true;
} else if (allPai[yu][paiNum + 2] >= 1) {
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
hasShun = true;
} else {
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
}
} else if (paiNum == 8) {
if (allPai[yu][paiNum - 1] >= 1 && allPai[yu][paiNum - 2] >= 1) {
hasShun = true;
if (size >= 2 && allPai[yu][paiNum - 1] >= 2) {
if (!tingTable.contains(pai - 2)) {
tingTable.add(pai - 2);
}
}
if (size >= 2 && allPai[yu][paiNum - 2] >= 2) {
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
}
} else if (allPai[yu][paiNum - 1] >= 1 && allPai[yu][paiNum + 1] >= 1) {
hasShun = true;
if (size >= 2 && allPai[yu][paiNum - 1] >= 2) {
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
}
if (size >= 2 && allPai[yu][paiNum + 1] >= 2) {
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
}
} else if (allPai[yu][paiNum - 1] >= 1) {
hasShun = true;
if (!tingTable.contains(pai - 2)) {
tingTable.add(pai - 2);
}
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
} else if (allPai[yu][paiNum - 2] >= 1 || allPai[yu][paiNum + 1] >= 1) {
hasShun = true;
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
} else {
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
}
} else if (paiNum == 2) {
if (allPai[yu][paiNum + 1] >= 1 && allPai[yu][paiNum + 2] >= 1) {
hasShun = true;
if (size >= 2 && allPai[yu][paiNum + 1] >= 2) {
if (!tingTable.contains(pai + 2)) {
tingTable.add(pai + 2);
}
}
if (size >= 2 && allPai[yu][paiNum + 2] >= 2) {
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
}
} else if (allPai[yu][paiNum - 1] >= 1 && allPai[yu][paiNum + 1] >= 1) {
hasShun = true;
if (size >= 2 && allPai[yu][paiNum + 1] >= 2) {
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
}
if (size >= 2 && allPai[yu][paiNum - 1] >= 2) {
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
}
} else if (allPai[yu][paiNum + 1] >= 1) {
hasShun = true;
if (!tingTable.contains(pai + 2)) {
tingTable.add(pai + 2);
}
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
} else if (allPai[yu][paiNum + 2] >= 1 || allPai[yu][paiNum - 1] >= 1) {
hasShun = true;
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
} else {
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
}
} else {
if (allPai[yu][paiNum - 1] >= 1 && allPai[yu][paiNum + 1] >= 1) {
hasShun = true;
if (size >= 2 && allPai[yu][paiNum - 1] >= 2) {
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
}
if (size >= 2 && allPai[yu][paiNum + 1] >= 2) {
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
}
} else if (allPai[yu][paiNum - 1] >= 1 && allPai[yu][paiNum - 2] >= 1) {
hasShun = true;
if (size >= 2 && allPai[yu][paiNum - 1] >= 2) {
if (!tingTable.contains(pai - 2)) {
tingTable.add(pai - 2);
}
}
if (size >= 2 && allPai[yu][paiNum - 2] >= 2) {
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
}
} else if (allPai[yu][paiNum + 1] >= 1 && allPai[yu][paiNum + 2] >= 1) {
hasShun = true;
if (size >= 2 && allPai[yu][paiNum + 1] >= 2) {
if (!tingTable.contains(pai + 2)) {
tingTable.add(pai + 2);
}
}
if (size >= 2 && allPai[yu][paiNum + 2] >= 2) {
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
}
} else if (allPai[yu][paiNum - 1] >= 1) {
hasShun = true;
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
if (!tingTable.contains(pai - 2)) {
tingTable.add(pai - 2);
}
} else if (allPai[yu][paiNum + 1] >= 1) {
hasShun = true;
if (!tingTable.contains(pai + 2)) {
tingTable.add(pai + 2);
}
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
} else if (allPai[yu][paiNum - 2] >= 1) {
if (!tingTable.contains(pai - 1)) {
tingTable.add(pai - 1);
}
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
} else if (allPai[yu][paiNum + 2] >= 1) {
if (!tingTable.contains(pai + 1)) {
tingTable.add(pai + 1);
}
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
} else {
if (size == 1) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
}
}
return hasShun;
}
四)有癞子时候的飞碰飞杠飞补杠
1)飞杠
/**
* 能否飞杠
* @param laizinum
癞子牌
* @param lastPai 最后牌桌出的牌
* @param memberShouPai
玩家手牌
* @return
*/
public static boolean canFreeGang(int laizinum, int lastPai, List<Integer> memberShouPai) {
int free = laizinum;
if (free == lastPai) {
return false;
}
int[][] memberPai = changeToArr(memberShouPai);
// 已有该张牌的数量
int yetNum = memberPai[lastPai / 10 - 1][lastPai % 10];
int freeNum = memberPai[free / 10 - 1][free % 10];
if (freeNum > 0 && yetNum >= 2) {
return true;
}
return false;
}
2)飞碰、飞暗杠、飞补杠
/**
* 判断玩家能否飞碰
* @param targetPai
* @param handPais
* @param laiZi
* @return
*/
public boolean canFreePeng(Integer targetPai, List<Integer> handPais, Integer laiZi) {
boolean isCanPeng = false;
int[][] memberPai = changeToArr(handPais);
// 已有癞子牌的数量
int freeNum = memberPai[laiZi / 10 - 1][laiZi % 10];
//筒-万-条
for (int i = 0; i < 3; i++) {
for (int j = 1; j < 10; j++) {
int pai = 10 * (i + 1) + j;
if (pai >= laiZi ) {
continue;
}
int count = memberPai[i][j];
if (count >= 1 && freeNum >= 1) { //1癞子+ >=1同类型牌
isCanPeng = true;
break;
}
}
}
return isCanPeng;
}
/**
* 判断玩家能否飞暗杠
* @param targetPai
* @param handPais
* @return
*/
public boolean canFreeAnGang(Integer targetPai, List<Integer> handPais, Integer laiZi) {
boolean isCanAnGang = false;
handPais.add(targetPai);
int[][] memberPai = changeToArr(handPais);
// 已有癞子牌的数量
int freeNum = memberPai[laiZi / 10 - 1][laiZi % 10];
//筒-万-条-风
for (int i = 0; i < 4; i++) {
for (int j = 1; j < 10; j++) {
int pai = 10 * (i + 1) + j;
if (pai >= laiZi ) {
continue;
}
int count = memberPai[i][j];
if (count >= 3 && freeNum >= 1) { //1癞子+ >=3同类型牌
isCanAnGang = true;
break;
}
}
}
return isCanAnGang;
}
/**
* 判断玩家能否飞补杠
*
* @param targetPai
*
目标牌
* @param paiMap
*
碰杠牌集合
* @return
*/
public boolean canFreeExtraGang(Integer targetPai, List<Integer> handPais,Integer laiZi, List<List<Integer>> showPais) {
boolean isCanGang = false;
//玩家手牌中加入目标牌后判断能否补杠
handPais.add(targetPai);
int[][] memberPai = changeToArr(handPais);
// 已有癞子牌的数量
int laiZiNum = memberPai[laiZi / 10 - 1][laiZi % 10];
for (List<Integer> data : showPais) {
if (data.size() != 3) {
continue;
}
if (data.size() == 3) {
if (data.contains(laiZi)) {//碰牌中已包含癞子牌,加一个同类型牌
int yetNum = memberPai[data.get(1) / 10 - 1][data.get(1) % 10];
if (yetNum >= 1) {
isCanGang = true;
break;
}
}else {//碰牌中未包含癞子牌,则添加一个癞子牌
if (laiZiNum >= 1) {
isCanGang = true;
break;
}
}
}
}
return isCanGang;
}
五)听牌
1)玩家听什么牌可以胡
/**
* 无赖子牌时听牌
* @param allPai
* @param show
* @param laiZi
* @return
*/
public static List<Integer> tingPai(int[][] allPai, List<Integer> show, Integer laiZi) {
int pai = 0;
List<Integer> tingTable = new ArrayList<>();
int[][] readyAllPai = allPai;
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 9; j++) {
pai = 10 * i + j;
boolean bool = false;
if (readyAllPai[i - 1][j] < 4) {// 已经是一杠牌了不处理
readyAllPai[i - 1][0] = readyAllPai[i - 1][0] + 1;
readyAllPai[i - 1][j] = readyAllPai[i - 1][j] + 1;
bool = true;
}// 遍历添加一张 看是否符合胡牌条件
if (fitHu(arrToList(readyAllPai),show,laiZi)) {
tingTable.add(pai);
}
if (bool) {
readyAllPai[i - 1][0] = readyAllPai[i - 1][0] - 1;
readyAllPai[i - 1][j] = readyAllPai[i - 1][j] - 1;
}
}
}
return tingTable;
}
/**
* 有癞子牌时检查听牌
*
* @param paiList 手牌
* @param laiZi 癞子
* @param show 碰杠牌
* @return
*/
public static List<Integer> tingPai2(List<Integer> paiList, int laiZi, List<Integer> show) {
// 复制
List<Integer> tingTable = new ArrayList<>();
List<Integer> shouPai = new ArrayList<Integer>();
shouPai.addAll(paiList);
// list转hashmap(hm是用来判断一条杠)
HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
for (Integer integer : shouPai) {
if (hm.get(integer) == null) {
hm.put(integer, 1);
} else {
hm.put(hm.get(integer), hm.get(integer) + 1);
}
}
int pai = 0;// 添加的牌
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 9; j++) {
boolean bool = false;
pai = Integer.parseInt(i + "" + j);
if (hm.get(pai) == null || hm.get(pai) < 4) {
shouPai.add(pai);
bool = true;
}
if (huLaizi(shouPai, laiZi, show).size() > 0) {
tingTable.add(pai);
}
if (bool) {
shouPai.remove(shouPai.size() - 1);
}
}
}
return tingTable;
}
最后
以上就是醉熏彩虹为你收集整理的麻将AI算法(下)的全部内容,希望文章能够帮你解决麻将AI算法(下)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复