大众麻将算番算法

闲来无事,再把全套麻将算番代码贴出,供有缘人参考,该算法以标准的国标麻将81种番编写,并严格遵守5大算番规则,不重复原则,不拆移原则,不得相同的原则,就高不就低原则,套算一次原则。

<?php
/**
 * Created by PhpStorm.
 * User: guochao<gc_mike@163.com>
 * Date: 18/10/10
 * Time: 下午3:30
 */

namespace components\mahjongAi;
use components\Utility;

/**
 *
 * 算番规则.
 *     1.不重复原则

        当某个番种,由于组牌的条件所决定,在其成立的同时,必然并存着其他番种,则其他番种不重复计分。

    2.不拆移原则

        确定一个番种后,不能将其自身再拆开互相组成新的番种计分。

    3.不得相同的原则

        凡已组合过某一番种的牌,不能再同其他一副牌组成相同的番种计分

    4.就高不就低原则

        有两副以上的牌,有可能组成两个以上的番种,而只能选其中一种计分时,可选择分高的番种计分。

    5.套算一次原则

        如有尚未组合过的一副牌,只可同已组合过的相应一副牌套算一次。
 *
 *
 * Class MJCalcScoring
 * @package app\components
 */
class MJCalcScoring extends MJBase{
   

    private static $_handCards;
    private static $_knownCards;
    private static $_handCardsCountMap;
    private static $_splitArr;

    /**
     * 和牌所用到的参数.
     * @var $params = [
     *           'is_last_card' => 1,
     *           'is_zi_mo' => 1,
     *           'is_gang_mo_pai' => 0,
     *           'is_qiang_gang_hu' => 0,
     *           'ming_gang_count' => 0,
     *           'an_gang_count' => 0,
     *           'is_hu_jue_zhang' => 0,
     *           'men_fen' => 2,
     *           'quan_fen' => 1,
     *           'hu_card' => 11,
     *           'is_ting' => 0,
     *           'flower_count' => 1
     *      ]
     */
    private static $_params;



    /**
     * 构造方法.
     *
     * @param $handCards
     * @param $knownCards
     */
    public function __construct($handCards,$knownCards = [],$params = [], $isSplitCard = true){
   

        sort($handCards);
        self::$_handCards = $handCards;
        self::$_knownCards = $knownCards;

        if(!empty($knownCards)){
   
            array_walk_recursive($knownCards, function($value) use (&$handCards) {
   
                array_push($handCards, $value);
            });
        }
        self::$_handCardsCountMap = array_count_values($handCards);

        if($isSplitCard){
   
            self::$_splitArr = $this->_splitCard();
            echo "===========拆牌结果==================\n";
            print_r(self::$_splitArr);
            echo "=============================\n";
        }
        self::$_params = $params;
    }

    /**
     * 算番.
     */
    public function calHandCardsPoints(){
   

        $fanCateList = [];
        if($this->_isDaSiXi()){
   
            $fanCateList[] = self::F_DaSiXi;
        }elseif($this->_isDaSanYuan()){
   
            $fanCateList[] = self::F_DaSanYuan;
        }elseif($this->_isShiSanYao()){
   
            $fanCateList[] = self::F_ShiSanYao;
        }elseif($this->_isJiuLianBaoDeng()){
   
            $fanCateList[] = self::F_JiuLianBaoDeng;
        }elseif($this->_isLianQiDui()){
   
            $fanCateList[] = self::F_LianQiDui;
        }elseif($this->_isLvYiSe()){
   
            $fanCateList[] = self::F_LvYiSe;
        }elseif($this->_isSiGang()){
   
            $fanCateList[] = self::F_SiGang;
        }elseif($this->_isXiaoSanYuan()){
   
            $fanCateList[] = self::F_XiaoSanYuan;
        }elseif($this->_isXiaoSiXi()){
   
            $fanCateList[] = self::F_XiaoSiXi;
        }elseif($this->_isQingYaoJiu()){
   
            $fanCateList[] = self::F_QingYaoJiu;
        }elseif($this->_isYiSeShuangLongHui()){
   
            $fanCateList[] = self::F_YiSeShuangLongHui;
        }elseif($this->_isZiYiSe()){
   
            $fanCateList[] = self::F_ZiYiSe;
        }elseif($this->_isSiAnKe()){
   
            $fanCateList[] = self::F_SiAnKe;
        }elseif($this->_isYiSeSiJieGao()){
   
            $fanCateList[] = self::F_YiSeSiJieGao;
        }elseif($this->_isYiSeSiTongShun()){
   
            $fanCateList[] = self::F_YiSeSiTongShun;
        }elseif($this->_isYiSeSiBuGao()){
   
            $fanCateList[] = self::F_YiSeSiBuGao;
        }elseif(!in_array(self::F_ShiSanYao,$fanCateList) && $this->_isHunYaoJiu()){
   
            $fanCateList[] = self::F_HunYaoJiu;
        }elseif(empty(array_intersect([self::F_SiGang],$fanCateList)) && $this->_isSanGang()){
   
            $fanCateList[] = self::F_SanGang;
        }elseif(empty(array_intersect([self::F_SiGang,self::F_YiSeShuangLongHui],$fanCateList)) && $this->_isQiDui()){
   
            $fanCateList[] = self::F_QiDui;
        }elseif($this->_isQiXingBuKao()){
   
            $fanCateList[] = self::F_QiXingBuKao;
        }elseif($this->_isQuanShuangKe()){
   
            $fanCateList[] = self::F_QuanShuangKe;
        }elseif($this->_isQuanDa()){
   
            $fanCateList[] = self::F_QuanDa;
        }elseif($this->_isQuanZhong()){
   
            $fanCateList[] = self::F_QuanZhong;
        }elseif(empty(array_intersect([self::F_YiSeSiTongShun,self::F_YiSeSanTongShun],$fanCateList)) && $this->_isYiSeSanJieGao()){
   
            $fanCateList[] = self::F_YiSeSanJieGao;
        }elseif(empty(array_intersect([self::F_YiSeSiJieGao,self::F_YiSeSanJieGao],$fanCateList)) && $this->_isYiSeSanTongShun()){
   
            $fanCateList[] = self::F_YiSeSanTongShun;
        }elseif($this->_isQingLong()){
   
            $fanCateList[] = self::F_QingLong;
        }elseif($this->_isYiSeSanBuGao()){
   
            $fanCateList[] = self::F_YiSeSanBuGao;
        }elseif($this->_isSanSeShuangLongHui()){
   
            $fanCateList[] = self::F_SanSeShuangLongHui;
        }elseif($this->_isShiSanBuKao()){
   
            $fanCateList[] = self::F_ShiSanBuKao;
        }elseif($this->_isZhuHeLong()){
   
            $fanCateList[] = self::F_ZhuHeLong;
        }elseif(empty(array_intersect([self::F_DaSiXi,self::F_XiaoSiXi],$fanCateList)) && $this->_isSanFenKe()){
   
            $fanCateList[] = self::F_SanFenKe;
        }elseif($this->_isSanSeSanTongShun()){
   
            $fanCateList[] = self::F_SanSeSanTongShun;
        }elseif($this->_isSanSeSanJieGao()){
   
            $fanCateList[] = self::F_SanSeSanJieGao;
        }elseif($this->_isSanSeSanBuGao()){
   
            $fanCateList[] = self::F_SanSeSanBuGao;
        }

        if($this->_isQuanXiao()){
   
            $fanCateList[] = self::F_QuanXiao;
        }
        if(empty(array_intersect([self::F_JiuLianBaoDeng,self::F_QiDui,self::F_YiSeShuangLongHui],$fanCateList))){
   
            if($this->_isQingYiSe()){
   
                $fanCateList[] = self::F_QingYiSe;
            }
        }

        if($this->_isQuanDaiWu()){
   
            $fanCateList[] = self::F_QuanDaiWu;
        }
        if($this->_isSanAnKe()){
   
            $fanCateList[] = self::F_SanAnKe;
        }
        if(empty(array_intersect([self::F_QingYaoJiu],$fanCateList))){
   
            if($this->_isSanTongKe()){
   
                $fanCateList[] = self::F_SanTongKe;
            }
        }

        if($this->_isDaYvWu()){
   
            $fanCateList[] = self::F_DaYvWu;
        }
        if($this->_isXiaoYvWu()){
   
            $fanCateList[] = self::F_XiaoYvWu;
        }
        if($this->_isHuaLong()){
   
            $fanCateList[] = self::F_HuaLong;
        }
        if($this->_isTuiBuDao()){
   
            $fanCateList[] = self::F_TuiBuDao;
        }
        if($this->_isHaiDiLaoYue()){
   
            $fanCateList[] = self::F_HaiDiLaoYue;
        }
        if($this->_isMiaoShouHuiChun()){
   
            $fanCateList[] = self::F_MiaoShouHuiChun;
        }
        if($this->_isGangShangKaiHua()){
   
            $fanCateList[] = self::F_GangShangKaiHua;
        }
        if($this->_isQiangGangHu()){
   
            $fanCateList[] = self::F_QiangGangHu;
        }
        if(!in_array(self::F_LvYiSe,$fanCateList)){
   
            if($this->_isHunYiSe()){
   
                $fanCateList[] = self::F_HunYiSe;
            }
        }
        if(empty(array_intersect([self::F_DaSiXi,self::F_SiGang,self::F_QingYaoJiu,self::F_ZiYiSe,self::F_SiAnKe,self::F_YiSeSiJieGao,self::F_HunYaoJiu,self::F_QuanShuangKe],$fanCateList))){
   
            if($this->_isPengPengHu()){
   
                $fanCateList[] = self::F_PengPengHu;
            }
        }

        if(empty(array_intersect([self::F_ShiSanYao,self::F_QiXingBuKao,self::F_ShiSanBuKao],$fanCateList))){
   
            if($this->_isWuMenQi()){
   
                $fanCateList[] = self::F_WuMenQi;
            }
        }
        if($this->_isQuanQiuRen()){
   
            $fanCateList[] = self::F_QuanQiuRen;
        }elseif(empty(array_intersect([self::F_QiDui,self::F_QiXingBuKao,self::F_ShiSanBuKao],$fanCateList)) && $this->_isBuQiuRen()){
   
            $fanCateList[] = self::F_BuQiuRen;
        }
        if(empty(array_intersect([self::F_SanGang],$fanCateList)) && $this->_isShuangAnGang()){
   
            $fanCateList[] = self::F_ShuangAnGang;
        }elseif(empty(array_intersect([self::F_SiGang,self::F_SanGang],$fanCateList)) && $this->_isShuangMingGang()){
   
            $fanCateList[] = self::F_ShuangMingGang;
        }
        if(!in_array(self::F_DaSanYuan,$fanCateList)){
   
            if($this->_isShuangJianKe()){
   
                $fanCateList[] = self::F_ShuangJianKe;
            }
        }
        if(empty(array_intersect([self::F_QingYaoJiu,self::F_HunYaoJiu],$fanCateList))){
   
            if($this->_isQuanDaiYao()){
   
                $fanCateList[] = self::F_QuanDaiYao;
            }
        }
        if(empty(array_intersect([self::F_QiangGangHu],$fanCateList))){
   
            if($this->_isHuJueZhang()){
   
                $fanCateList[] = self::F_HuJueZhang;
            }
        }
        if(empty(array_intersect([self::F_QingYaoJiu,self::F_YiSeShuangLongHui,self::F_YiSeSiBuGao,self::F_SanSeShuangLongHui],$fanCateList))){
   
            if($this->_isPingHu()){
   
                $fanCateList[] = self::F_PingHu;
            }
        }
        if(empty(array_intersect([self::F_QingYaoJiu,self::F_QuanShuangKe,self::F_QuanZhong,self::F_QuanDaiWu],$fanCateList))){
   
            if($this->_isDuanYaoJiu()){
   
                $fanCateList[] = self::F_DuanYaoJiu;
            }
        }
        if(empty(array_intersect([self::F_YiSeSiTongShun],$fanCateList))){
   
            if($this->_isSiGuiYi()){
   
                $fanCateList[] = self::F_SiGuiYi;
            }
        }
        if(empty(array_intersect([self::F_QingYaoJiu],$fanCateList))){
   
            if($this->_isLiangTongKe()){
   
                $fanCateList[] = self::F_LiangTongKe;
            }
        }
        if(empty(array_intersect([self::F_SanAnKe],$fanCateList))){
   
            if($this->_isShuangAnKe()){
   
                $fanCateList[] = self::F_ShuangAnKe;
            }
        }
        if(empty(array_intersect([self::F_ShiSanYao,self::F_SiAnKe,self::F_QiXingBuKao,self::F_ShiSanBuKao],$fanCateList))){
   
            if($this->_isMenQing()){
   
                $fanCateList[] = self::F_MenQing;
            }
        }
        if(!in_array(self::F_DaSiXi,$fanCateList)){
   
            if($this->_isMenFenKe()){
   
                $fanCateList[] = self::F_MenFenKe;
            }
        }
//        if(!in_array(self::F_DaSiXi,$fanCateList)){
   
//            if($this->_isQuanFenke()){
   
//                $fanCateList[] = self::F_QuanFenKe;
//            }
//        }
        if(empty(array_intersect([self::F_DaSanYuan,self::F_ShuangJianKe],$fanCateList))){
   
            if($this->_isJianke()){
   
                $fanCateList[] = self::F_JianKe;
            }
        }
        if(empty(array_intersect([self::F_SanGang,self::F_ShuangAnGang],$fanCateList))){
   
            if($this->_isAnGang()){
   
                $fanCateList[] = self::F_AnGang;
            }
        }



        // 般逢老连
        if(empty(array_intersect([self::F_YiSeShuangLongHui,self::F_YiSeSiTongShun,self::F_YiSeSiBuGao,self::F_SanSeShuangLongHui],$fanCateList))){
   
            $sz = 0;
            $szList = [];
            foreach(self::$_splitArr as $item){
   
                if(count($item) == 3 && $item[0] + 2 == $item[2]){
   
                    $szList[] = $item;
                    $sz ++;
                }
            }
            $s = 0;
            $logArr = [];
            if(!empty($szList))for($i = 0; $i < $sz; $i ++){
   
                for($j = $i + 1; $j <= $sz - 1; $j ++){
   

                    if($s == $sz - 1){
   
                        break 2;
                    }
                    $groupArr = [$szList[$i],$szList[$j]];
                    if(empty(array_intersect([self::F_YiSeSanTongShun],$fanCateList))){
   
                        if($this->_isYiBanGao($groupArr)){
   
                            if(isset($logArr[self::F_YiBanGao]) && $logArr[self::F_YiBanGao] == $groupArr){
   
                                continue;
                            }
                            $fanCateList[] = self::F_YiBanGao;
                            $logArr[self::F_YiBanGao] = $groupArr;
                            $s ++;
                        }
                    }
                    if($this->_isXiXiangFen($groupArr)){
   
                        if(isset($logArr[self::F_XiXiangFen]) && $logArr[self::F_XiXiangFen] == $groupArr){
   
                            continue;
                        }
                        $fanCateList[] = self::F_XiXiangFen;
                        $logArr[self::F_XiXiangFen] = $groupArr;
                        $s ++;
                    }
                    if(empty(array_intersect([self::F_QiDui],$fanCateList))){
   
                        if(isset($logArr[self::F_LianLiu]) && $logArr[self::F_LianLiu] == $groupArr){
   
                            continue;
                        }
                        if($this->_isLianLiu($groupArr)){
   
                            $fanCateList[] = self::F_LianLiu;
                            $logArr[self::F_LianLiu] = $groupArr;
                            $s ++;
                        }
                    }
                    if($this->_isLaoShaoPei($groupArr)){
   
                        if(isset($logArr[self::F_LaoShaoPei]) && $logArr[self::F_LaoShaoPei] == $groupArr){
   
                            continue;
                        }
                        $fanCateList[] = self::F_LaoShaoPei;
                        $logArr[self::F_LaoShaoPei] = $groupArr;
                        $s ++;
                    }
                }
            }
        }


        if(empty(array_intersect([self::F_TuiBuDao],$fanCateList))){
   
            if($this->_isQueYiMen()){
   
                $fanCateList[] = self::F_QueYiMen;
            }
        }
        // 箭刻不计幺九刻
        if(empty(array_intersect([self::F_DaSiXi,self::F_QingYaoJiu,self::F_XiaoSiXi,self::F_HunYaoJiu],$fanCateList))){
   
            if($this->_isYaoJiuKe()){
   
                $fanCateList[] = self::F_YaoJiuKe;
            }
        }
        if(empty(array_intersect([self::F_QingYaoJiu,self::F_YiSeShuangLongHui,self::F_QingYiSe,self::F_QuanDa,self::F_QuanZhong,self::F_QuanXiao,self::F_SanSeShuangLongHui,self::F_DaYvWu,self::F_XiaoYvWu],$fanCateList))){
   
            if($this->_isWuZi()){
   
                $fanCateList[] = self::F_WuZi;
            }
        }
        if(empty(array_intersect([self::F_SiGang,self::F_SanGang,self::F_ShuangMingGang],$fanCateList))){
   
            if($this->_isMingGang()){
   
                $fanCateList[] = self::F_MingGang;
            }
        }

        if($this->_isBianZhang()){
   
            $fanCateList[] = self::F_BianZhang;
        }elseif($this->_isKanZhang()){
   
            $fanCateList[] = self::F_KanZhang;
        }
        if(empty(array_intersect([self::F_ShiSanYao,self::F_SiGang,self::F_QiDui,self::F_QiXingBuKao,self::F_ShiSanBuKao,self::F_QuanQiuRen],$fanCateList))){
   
            if($this->_isDanDiao()){
   
                $fanCateList[] = self::F_DanDiao;
            }
        }
        if(empty(array_intersect([self::F_SiAnKe,self::F_MiaoShouHuiChun,self::F_GangShangKaiHua,self::F_BuQiuRen],$fanCateList))){
   
            if($this->_isZiMo()){
   
                $fanCateList[] = self::F_ZiMo;
            }
        }

        // 一色三同顺、清龙、一色三步高、花龙、三色三同顺、三色三步高
        if(array_intersect([self::F_YiSeSanTongShun,self::F_QingLong,self::F_YiSeSanBuGao,self::F_HuaLong,self::F_SanSeSanTongShun,self::F_SanSeSanBuGao],$fanCateList)){
   
            $isHasBFLL = false;

            foreach($fanCateList as $fanName){
   
                if(in_array($fanName,[self::F_YiBanGao,self::F_XiXiangFen,self::F_LaoShaoPei,self::F_LianLiu])){
   
                    if($isHasBFLL){
   
                        array_splice($fanCateList,array_search($fanName,$fanCateList),1);
                        continue;
                    }
                    $isHasBFLL = true;
                }
            }
        }

        // 无番和
        if(empty($fanCateList) && self::$_params['is_ting'] == 0){
   
            $fanCateList[] = self::F_WuFanHu;
        }

        if(self::$_params['is_ting'] == 1){
   
            $fanCateList[] = self::F_TingCard;
        }
        if(self::$_params['flower_count'] > 0){
   
            $fanCateList[] = self::F_FlowerCard;
        }

        // 格式化番种类
        $result = [];
        $totalScore = 0;
        foreach($fanCateList as $key => $fanName){
   
            $score = Utility::recursive_array_search($fanName,self::$fanScoreMap);
            $result[$key]['fan_name'] = self::$fanNameMap[$fanName];
            if($fanName == self::F_FlowerCard){
   
                $result[$key]['score'] = self::$_params['flower_count'];
                $score = self::
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值