麻将开金算法java代_麻将基本胡的算法——Java

算法思想

胡的条件

必须有一对将(两个相同的牌)

除了将,其余牌必须为顺子或刻子

算法(精简版)

提取所有将牌

去除所有刻子

去除所有顺子

没有牌了,胡;还有牌,不胡

算法(完整版)

提取所有将牌(如果要胡,将牌是必须存在的,而且将牌可能会有多种)

取一对将牌,如果没有将牌了,则表示不能胡

将手牌去除选取的将牌

将剩余的手牌去除所有的刻子,去除所有的刻子后如果手牌没有了,则胡;手牌还有,则继续第5步判断

将手牌去除所有的顺子,去除所有的顺子后如果手牌没有了,则胡;手牌还有,则回到第2步重新判断

Java实现

代码

import java.util.Arrays;

/**

* @author Yawei Xi

* @date 2018-10-9

*/

public class MahjongCore {

/**

* 麻将所有牌型

* 一万,二万,三万,四万,五万,六万,七万,八万,九万

* 一筒,二筒,三筒,四筒,五筒,六筒,七筒,八筒,九筒

* 一条,二条,三条,四条,五条,六条,七条,八条,九条

* 东,西,南,北,中,发,白

*/

private static final int[] ALL_CARDS = new int[]{

11, 12, 13, 14, 15, 16, 17, 18, 19,

21, 22, 23, 24, 25, 26, 27, 28, 29,

31, 32, 33, 34, 35, 36, 37, 38, 39,

50, 60, 70, 80, 90, 100, 110

};

/**

* 判断手牌是否胡了

*

* @param cards 手牌

* @return 胡了(true), 没有胡(false)

*/

public static boolean isHu(int[] cards) {

if (null == cards) {

return false;

}

// 胡的牌的个数必须是2或5或8或11或14

if (cards.length != 2 && cards.length != 5 && cards.length != 8 && cards.length != 11 && cards.length != 14) {

return false;

}

// 将手牌中的将取出来

int[] js = getJiangs(cards);

if (null == js || js.length <= 0) {

return false;

}

for (int j : js) {

int[] tempCards = Arrays.copyOf(cards, cards.length);

tempCards = removeOne(tempCards, j);

tempCards = removeOne(tempCards, j);

Arrays.sort(tempCards);

// 去掉所有的刻子

tempCards = removeAllKe(tempCards);

if (tempCards.length <= 0) {

return true;

}

// 去掉所有的顺子

tempCards = removeAllShun(tempCards);

if (tempCards.length <= 0) {

return true;

}

}

return false;

}

/**

* 获取牌组中所有的“将”

*

* @param cards 牌组

* @return 所有的“将”组成的数组

*/

private static int[] getJiangs(int[] cards) {

int[] res = new int[0];

if (null != cards && cards.length > 1) {

for (int i = 0; i < cards.length - 1; i++) {

if (cards[i] == cards[i + 1]) {

res = add(res, cards[i]);

i++;

}

}

}

return res;

}

/**

* 去掉牌组中所有的刻子

*

* @param cards 牌组

*/

private static int[] removeAllKe(int[] cards) {

for (int i = 0; i < cards.length - 2; i++) {

if (cards[i] == cards[i + 1] && cards[i] == cards[i + 2]) {

cards = removeOne(cards, cards[i]);

cards = removeOne(cards, cards[i]);

cards = removeOne(cards, cards[i]);

}

}

return cards;

}

/**

* 去掉牌组中所有的顺子

*

* @param cards 牌组

*/

private static int[] removeAllShun(int[] cards) {

int[] res = Arrays.copyOf(cards, cards.length);

for (int i = 0; i < cards.length - 2; i++) {

if (cards[i] + 1 == cards[i + 1] && cards[i + 1] + 1 == cards[i + 2]) {

res = removeOne(res, cards[i]);

res = removeOne(res, cards[i + 1]);

res = removeOne(res, cards[i + 2]);

}

}

return res;

}

/**

* 获取去掉花色的牌的值

*

* @param card 原牌值

* @return 去掉花色的牌的值

*/

private static int getCardWithoutSuit(int card) {

return card % 10;

}

/**

* 将牌card加到牌组cards中

*

* @param cards 牌组

* @param card 牌

* @return 添加后的牌组

*/

private static int[] add(int[] cards, int card) {

int[] res = new int[cards.length + 1];

System.arraycopy(cards, 0, res, 0, cards.length);

res[res.length - 1] = card;

return res;

}

/**

* 在牌组中去掉一张牌

*

* @param cards 牌组

* @param card 要去掉的牌

* @return 去掉牌后的牌组

*/

private static int[] removeOne(int[] cards, int card) {

if (null == cards || cards.length <= 0) {

return cards;

}

Arrays.sort(cards);

int index = Arrays.binarySearch(cards, card);

if (index >= 0) {

int[] res = new int[cards.length - 1];

int j = 0;

for (int i = 0; i < cards.length; i++) {

if (i != index) {

res[j++] = cards[i];

}

}

return res;

}

return cards;

}

}

测试用例

/**

* @author Yawei Xi

* @date 2018-10-9

*/

public class Test {

public static void main(String[] args) {

// 空牌组

int[] a = {};

// 一万、一万

int[] b = {11, 11};

// 一万、二万、三万、四万、四万

int[] c = {11, 12, 13, 14, 14};

// 一万、二万、三万、二条、三条、四条、四万、四万

int[] d = {11, 12, 13, 32, 33, 34, 14, 14};

// 一万、二万、三万、二条、三条、四条、东风、东风、东风、四万、四万

int[] e = {11, 12, 13, 32, 33, 34, 50, 50, 50, 14, 14};

// 一万、二万、三万、二条、三条、四条、东风、东风、东风、五万、五万、五万、四万、四万

int[] f = {11, 12, 13, 32, 33, 34, 50, 50, 50, 15, 15, 15, 14, 14};

System.out.println("a牌型是否胡:" + (MahjongCore.isHu(a) ? "胡" : "不胡"));

System.out.println("b牌型是否胡:" + (MahjongCore.isHu(b) ? "胡" : "不胡"));

System.out.println("c牌型是否胡:" + (MahjongCore.isHu(c) ? "胡" : "不胡"));

System.out.println("d牌型是否胡:" + (MahjongCore.isHu(d) ? "胡" : "不胡"));

System.out.println("e牌型是否胡:" + (MahjongCore.isHu(e) ? "胡" : "不胡"));

System.out.println("f牌型是否胡:" + (MahjongCore.isHu(f) ? "胡" : "不胡"));

}

}

测试结果

a牌型是否胡:不胡

b牌型是否胡:胡

c牌型是否胡:胡

d牌型是否胡:胡

e牌型是否胡:胡

f牌型是否胡:胡

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值