棋牌算法——“贰柒拾”(字牌)

目录

百度百科:

玩法介绍:

核心算法:

1. 编号&获取

2. 吃 & 摆

3. 对(碰)

4、开(杠,下雨)

5、胡 & 听牌提示


百度百科:

棋牌算法——“贰柒拾”(字牌)_第1张图片

棋牌算法——“贰柒拾”(字牌)_第2张图片

棋牌算法——“贰柒拾”(字牌)_第3张图片


玩法介绍:

贰柒拾的玩法有很多种,主要有“乐山贰柒拾”,“犍为贰柒拾”,“眉山贰柒拾”,“四十张三人”,“两人贰柒拾”等,不同玩法之间其核心的打牌逻辑都是相同的,区别在于一些算分和番型不同而已。具体的打牌规则和各玩法介绍,由于篇幅较大,对核心的处理逻辑没有影响,这里就不做过多的介绍。


核心算法:

温馨提示:本文主要对胡牌逻辑进行分析,想要理解算法,请务必先学会打牌规则及玩法

1. 编号&获取

编号:首先需要分别将红黑牌进行编号,因为没有压牌规则,所以不同花色可以单独编组。如红牌1-10 、黑牌11-20,这里建议通过一个花色码进行移位编号。

获取:寻找牌值时,需根据花色与牌值进行寻找。

2. 吃 & 摆

单独的吃操作其实很简单,但贰柒拾的吃操作之前,必须先对摆操作进行校验,摆操作和吃操作的都是一样的牌型,只不过多了一层约束。首先,根据目标牌寻找手牌中可以吃的组合,检查目标牌是否存在?

--存在:进入检查摆牌逻辑,如果摆牌成功,即可吃,如果摆牌失败,即不能吃

--不存在:可直接吃

3. 对(碰)

检查手牌有且只有两张时可进行对操作

4、开(杠,下雨)

检查手牌有且只有3张可进行开操作

5、胡 & 听牌提示

先对红黑牌进行分类并排序,然后进行组合判断,由于红牌的牌型胡数大于黑牌,所以先对红牌进行组合判断。这里以红牌为例,黑牌逻辑相同,不再赘述。

获取第一张牌,判断该牌是否为目标牌(进行标记),获取该牌的张数,根据不同的张数组成不同的“组合”,张数可能如下:

1、4张,可组成一磙

2、3张,可组成一坎(包含目标牌则可组成对)

3、1&2张,可组成吃,吃的话需要去寻找相邻的牌(包括2710)(这里涉及到红吃黑,所以也需要去黑牌里找)

如能组合成功,将组合成功的牌全部移除,然后再取一张,重复如此,直至牌全部移除(红黑),则可胡。

如其递归过程出现组合失败,则目标牌不可胡。退出判断

4、胡牌之后判断番型胡数,可在组合判断的过程对一些牌型进行收集,如圈牌,胡数,2710,坤,漂,天,地等。

代码:(java)

 /**
     * 胡牌检查
     *
     * @param result
     * @param
     * @return
     */
    public static ErQiShiTingResult realCheckHu(ErQiShiTingResult result) {

        if (result.getZhuCard().size() == 0 && result.getFuCard().size() == 0) {
            if (result.getYouNum() >= result.getNeedYouNum()) {
                result.setHu(true);
            }
            return result;
        }

        List zhuCard = result.getZhuCard();
        Byte card = result.getCard();
        ErQiShiTingResult r;

        if (zhuCard.size() > 0) {
            Byte one = zhuCard.get(0);
            int oneNum = getCardNumInList(one, zhuCard);
            if (oneNum == 4) {
                if (one == card) {
                    // 三张摸一张的情况
                    // r = removeLianZi(copyResult, one);
                    // if (r.isHu()) {
                    // 	return r;
                    // }
                    return removeGunKai(result, one);
                } else {
                    // 判断磙
                    return removeGun(result, one);
                }

            } else if (oneNum == 3) {

                if (one == card) {

                    // 根据标识和圈牌 判断优先算圈胡还是算二七十
                    if (result.isFlag() && card == result.getQuanCard()) {
                        r = removeDuiZi(result, one);
                        if (r.isHu()) {
                            return r;
                        }
                        r = removeErQiShi(result, one);
                        if (r.isHu()) {
                            return r;
                        }
                    } else {
                        r = removeErQiShi(result, one);
                        if (r.isHu()) {
                            return r;
                        }
                        r = removeDuiZi(result, one);
                        if (r.isHu()) {
                            return r;
                        }
                    }

                    r = selectMaxHu(result, one);
                    if (r.isHu()) {
                        return r;
                    }
                    // r = removeZhuangZi(result, one);
                    // if (r.isHu()) {
                    //     return r;
                    // }
                    //
                    // r = removeDazi1(result, one);
                    // if (r.isHu()) {
                    //     return r;
                    // }
                    //
                    // r = removeLianZi(result, one);
                    // if (r.isHu()) {
                    //     return r;
                    // }

                } else {
                    // 判断坎
                    return removeKan(result, one);

                }
            } else if (oneNum == 2) {

                r = removeErQiShi(result, one);
                if (r.isHu()) {
                    return r;
                }

                r = selectMaxHu(result, one);
                if (r.isHu()) {
                    return r;
                }

                // r = removeZhuangZi(result, one);
                // if (r.isHu()) {
                //     return r;
                // }
                //
                // r = removeDazi1(result, one);
                // if (r.isHu()) {
                //     return r;
                // }
                //
                // r = removeLianZi(result, one);
                // if (r.isHu()) {
                //     return r;
                // }
            } else if (oneNum == 1) {
                r = removeErQiShi(result, one);
                if (r.isHu()) {
                    return r;
                }
                r = removeLianZi(result, one);
                if (r.isHu()) {
                    return r;
                }
            }
        } else {
            r = realCheckHu(result.swap());
            if (r.isHu()) {
                return r;
            }
        }
        return result;
    }

 

你可能感兴趣的:(棋牌算法)