php 麻将胡牌规则

// # tag 11-19:筒  21-29:万 31-39:条 41:红中 51:东风 61:西风 71:南风 81:北风 91:白板  ps:看具体需求
$arr  = [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,41,51,61,71,81,91]; 

// 除过碰牌和刚牌外剩余的牌 听了的牌 例:
$tag_arr = [14,15,16,17,18,19,22,22,23,23,35,36,37];

示例:

    public function index(){  
		
		// # tag 11-19:筒  21-29:万 31-39:条 41:红中 51:东风 61:西风 71:南风 81:北风 91:白板  ps:看具体需求
		$arr  = [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,41,51,61,71,81,91]; 

		// 除过碰牌和刚牌外剩余的牌 听了的牌 例:
		// 四筒 五筒 六筒 七筒 八筒 九筒 二万 二万 三万 三万 五万 六万 七万
		$tag_arr = [14,15,16,17,18,19,22,22,23,23,35,36,37];

		$result = getPromptArr($arr,$tag_arr); 
 
		var_dump($result);  
	}
	

输出结果:

array(3) { [0]=> int(22) [1]=> int(23) [2]=> int(41) }

胡牌为 :二万 三万 红中 ps:若无红中则全牌数组里可以去掉红中(41)

代码:

    /**
    * 获取胡牌数组
    * @param array     $arr            全牌集
    * @param string    $tag_arr        余牌集
    * @return array    
    */
    function getPromptArr($arr,$tag_arr){
        $success = [];
        foreach ($arr as $key => $value) {    
            if(!in_array($value, $success)){ 
                $tag_arr1 =  $tag_arr;
                array_push($tag_arr1,$value);
                sort($tag_arr1);
                $tag_count = array_count_values(array_filter($tag_arr1));
                // dump($tag_count);
                $type = getCardType($tag_count);
                // 四个红中 直接胡  
                if (in_array(41, $tag_arr1) && $tag_count[41] == 4) {  
                    $result  = true;  
                }else{  
                    // 单调将
                    if(count($type['TrumpCard']) == 1 && count($type['OtherCard']) == 0){ 
                        
                        $result  = true;
                        
                    // 七对  
                    }else if (count($type['TrumpCard']) == 7 ) {
                        
                        $result  = true;
                    }else if (count($type['TrumpCard']) == 6 && in_array(41, $tag_arr1) || count($type['TrumpCard']) == 5 && in_array(41, $tag_arr1) && $tag_count[41] == 2  || count($type['TrumpCard']) == 4 && in_array(41, $tag_arr1) && $tag_count[41] == 3){
                        
                        $result  = true; 
                    }else{  
                        if (mahjongWinning($tag_arr1)) {  
                            
                            $result  = true;   
                        }else if(count($type['TrumpCard']) == 1 && 
                        mahjongWinning($type['OtherCard'])){  
                            
                            $result  = true; 
                        }else{
                        
                            $data_card = [];    
                            $TrumpCard = [];
                            foreach ($tag_arr1  as $key1 => $value1) { 
                                $ac = array_count_values($tag_arr1); 
                                if (!in_array($value1, $TrumpCard)) {
                                    if ($ac[$value1]>=2) {
                                        $tag_arr2 = $tag_arr1;
                                        $TrumpCard[] = $value1; 
                                        array_splice($tag_arr2,$key1,2);
                                        $data_card[] = $tag_arr2;
                                    }
                                }
                            }   
                            
                            foreach ($data_card as $key2 => $value2) {
                                $result_m  = mahjongWinning($value2);
                                if ($result_m) { 
                                    $result  = false; 
                                    $success[] = $value; 
                                }  
                            }  
                            $result  = false; 
                        }                 
                    } 
                }   
                $tag_arr1 = [];
                if ($result) {
                    $success[] = $value;  
                } 
            }               
        }  
        $success = array_unique($success);
        $arr = [];
        foreach ($success as $key => $value) {
            $arr[] = $value;
        } 
         
        return $arr;
    }
    /**
     * 胡不胡
     * @param 	array 	$mahjong_arr  	需要排序的牌
     * @param 	array 	$result  		别人打出的牌
     * @return 	array
     */
    function mahjongWinning($mahjong_arr = []){
    	$result = checkOthercard($mahjong_arr);
    	return $result;
    }

第一步 取牌牌型

    // 第一步 取牌牌型
    function getCardType($tag_arr = []){ 
    	$OtherCard 	= [];
    	$TrumpCard 	= [];
    	$ThreeCard 	= [];
    	foreach ($tag_arr as $key => $value) {
    		switch ($value) {
    			case 1:
    				# 余牌
    				$OtherCard[] 	= $key;
    				break;
    			case 2:
    				# 将牌
    				if ($key == 41) {
    					$OtherCard[] 	= $key; 
    					$OtherCard[] 	= $key;
    				}else{   
    					$TrumpCard[] 	= $key;
    				} 
    				break;
    			case 3:
    				# 将牌
    				if ($key == 41) { 
    					$OtherCard[] 	= $key; 
    					$OtherCard[] 	= $key;
    					$OtherCard[] 	= $key;
    				}else{
    					$OtherCard[] 	= $key;
    					$TrumpCard[] 	= $key;  
    				}  
    				break; 
    			case 4:
    				# 将牌 
    				if ($key != 41) {	
    					$TrumpCard[] 	= $key;  
    					$TrumpCard[] 	= $key;  
    				} 
    				break;
    		}
    	}
    
    	return ['OtherCard'=>$OtherCard,'TrumpCard'=>$TrumpCard];
    }

第二步 监测余牌

    //第二步 监测余牌
    function checkOthercard($OtherCard = []){   
    	if(count($OtherCard)  == 0){
    
    		return true;
    	}else{
    		     
    		return stepTwo($OtherCard);
    	}
    }

第三步 去除余牌中的坎子

    //第三步 去除余牌中的坎子
    function stepTwo($OtherCard = []){
    	foreach ($OtherCard as $key => $value) {
    		$ac = array_count_values($OtherCard); 
    		if ($ac[$value] >=3 && $value !=41) {    
    			array_splice($OtherCard,$key,3);
    			return checkOthercard($OtherCard);    
    		}
    	}
    
    	$result = stepThree($OtherCard); 
    	if ($result) {
    		return $result;
    	}else{  
    		if(in_array(41,$OtherCard)){ 
    			rsort($OtherCard);
    			return  stepThree2($OtherCard); 
    		}else{
    			return false;
    		}   
    	} 
    }

第四步 正序去除余牌中的顺子

  //第四步 正序去除余牌中的顺子
  function stepThree($OtherCard = []){
  	$OtherCard_0 = [];
  	foreach ($OtherCard as $key => $value) {
  		if(in_array($value+1,$OtherCard) && in_array($value+2,$OtherCard)){   
  
  			$ac = array_count_values($OtherCard);  
  			if ($ac[$value] == 1 && $ac[$value+1] == 1 && $ac[$value+2] == 1 || $ac[$value] == 1 && $ac[$value+1] == 1 && $ac[$value+2] == 2) {
  
  				array_splice($OtherCard,$key,3);
  				return checkOthercard($OtherCard);
  			}else if ($ac[$value] == 2 && $ac[$value+1] == 1 && $ac[$value+2] == 1) {
  
  				array_splice($OtherCard,$key+1,3);
  				return checkOthercard($OtherCard); 
  				 
  			}else if ($ac[$value] == 1 && $ac[$value+1] == 2 && $ac[$value+2] == 1) {
  
  				array_splice($OtherCard,$key,1);
  				array_splice($OtherCard,$key+1,2);
  				return checkOthercard($OtherCard); 
  				 
  			}else if ($ac[$value] == 2 && $ac[$value+1] == 2 && $ac[$value+2] == 1) {
  
  				array_splice($OtherCard,$key,1);
  				array_splice($OtherCard,$key+2,2);
  				return checkOthercard($OtherCard); 
  				
  			}else if ($ac[$value] == 1 && $ac[$value+1] == 2 && $ac[$value+2] == 2) {
  
  				array_splice($OtherCard,$key,2);
  				array_splice($OtherCard,$key+1,1);
  				return checkOthercard($OtherCard); 
  				 
  			}else if ($ac[$value] == 2 && $ac[$value+1] == 2 && $ac[$value+2] == 2) {
  
  				array_splice($OtherCard,$key,1);
  				array_splice($OtherCard,$key+1,1);
  				array_splice($OtherCard,$key+2,1);
  				return checkOthercard($OtherCard); 
  				 
  			}else if ($ac[$value] == 2 && $ac[$value+1] == 1 && $ac[$value+2] == 2){
  
  				array_splice($OtherCard,$key,1);
  				array_splice($OtherCard,$key+1,1);
  				array_splice($OtherCard,$key+1,1);  
  				return checkOthercard($OtherCard); 
  			}   
  			
  		}else{   
  			$OtherCard_0[] = $value; 
  		}
  	}  
    	
  	if(!empty($OtherCard_0)){  
  		if (in_array(41,$OtherCard_0)) {    
  			sort($OtherCard_0);         
  			return is_lanzi($OtherCard_0);   
  		}else{    
  
  			return false;
  		}
  	} 
  }

第五步 倒序去除余牌中的顺子

    //第五步 倒序去除余牌中的顺子
    function stepThree2($OtherCard = []){   
    	$OtherCard_0 = []; 
    	
    	foreach ($OtherCard as $key => $value) { 
    
    		if(in_array($value-1,$OtherCard) && in_array($value-2,$OtherCard)){   
     
    			$ac = array_count_values($OtherCard);  
    			if ($ac[$value] == 1 && $ac[$value-1] == 1 && $ac[$value-2] == 1 || $ac[$value] == 1 && $ac[$value-1] == 1 && $ac[$value-2] == 2) {
    
    				array_splice($OtherCard,$key,3);
    				sort($OtherCard);
    
    				return checkOthercard($OtherCard);
    			}else if ($ac[$value] == 2 && $ac[$value-1] == 1 && $ac[$value-2] == 1) {
    
    				array_splice($OtherCard,$key+1,3);
    				sort($OtherCard);
    				return checkOthercard($OtherCard); 
    				 
    			}else if ($ac[$value] == 1 && $ac[$value-1] == 2 && $ac[$value-2] == 1) {
    
    				array_splice($OtherCard,$key,1);
    				array_splice($OtherCard,$key+1,2);
    				sort($OtherCard);
    				return checkOthercard($OtherCard); 
    				 
    			}else if ($ac[$value] == 2 && $ac[$value-1] == 2 && $ac[$value-2] == 1) {
    
    				array_splice($OtherCard,$key,1);
    				array_splice($OtherCard,$key+2,2);
    				sort($OtherCard);
    				return checkOthercard($OtherCard); 
    				
    			}else if ($ac[$value] == 1 && $ac[$value-1] == 2 && $ac[$value-2] == 2) {
    
    				array_splice($OtherCard,$key,2);
    				array_splice($OtherCard,$key+1,1);
    				sort($OtherCard);
    				return checkOthercard($OtherCard); 
    				 
    			}else if ($ac[$value] == 2 && $ac[$value-1] == 2 && $ac[$value-2] == 2) {
    
    				array_splice($OtherCard,$key,1);
    				array_splice($OtherCard,$key+1,1);
    				array_splice($OtherCard,$key+2,1);
    				sort($OtherCard);
    				return checkOthercard($OtherCard); 
    				 
    			}else if ($ac[$value] == 2 && $ac[$value-1] == 1 && $ac[$value-2] == 2){
    
    				array_splice($OtherCard,$key,1);
    				array_splice($OtherCard,$key+1,1);
    				array_splice($OtherCard,$key+1,1);  
    				sort($OtherCard);
    				return checkOthercard($OtherCard); 
    			}   
    			
    		}else{   
    			$OtherCard_0[] = $value; 
    		}
    	}  
    	      
    	if(!empty($OtherCard_0)){  
    		if (in_array(41,$OtherCard_0)) {    
    			sort($OtherCard_0);          
    			return is_lanzi($OtherCard_0);   
    		}else{    
    
    			return false;
    		}
    	} 
    }

第六步 判断余牌有没有红中 和是否能胡牌

  //第六步 判断余牌有没有红中 和是否能胡牌 
  function is_lanzi($OtherCard){ 
  	// 红中的数量
  	$count_hong = array_count_values($OtherCard)[41];
  
      $count = count($OtherCard); 
      switch ($count_hong) { //红中数量
      	case 1:
      		switch ($count) {//余牌数量
      			case 1:
      			case 2:
      				return true;
      				break;
      			case 3:
      				if ($OtherCard[0] == $OtherCard[1]) {
      					return true;
      				}else{
      					$OtherCard_0 = checkHong($OtherCard);   
  	    				if (empty($OtherCard_0)) { 
  	    				    return true;
  	    				}else{
  	    					return false;  
  	    				} 
      				} 
      				break;
      			default:
      				return false;
      				break;
      		}
  	    	break;
      	case 2:
      		switch ($count) {//余牌数量
      			case 2:
      			case 3:
      			case 4:
      				return true;
      				break;
      			case 5:
      			case 6:
      				$OtherCard_0 = checkHong($OtherCard); 
  
  					array_push($OtherCard_0,41); 
  					// array_push($OtherCard_0,41);  
  					      
  					if ($OtherCard_0) {
  					    return is_lanzi($OtherCard_0);     
  					}   
      				break;
      			default:
      				return false;
      				break;
      		}
      		break;
      	case 3:
      		switch ($count) {//余牌数量
      			case 3:
      			case 4:
      			case 5:
      			case 6:
      				return true;
      				break;
      			case 7: 
      			case 9: 
      			case 8: 
      				$OtherCard_0 = checkHong($OtherCard);  
  					array_push($OtherCard_0,41);  
  					array_push($OtherCard_0,41); 
  					if ($OtherCard_0) {
  					    return is_lanzi($OtherCard_0);     
  					}   
      				break; 
      			default:
      				return false;
      				break;
      		}
      		break;
      	default:
      		# code...
      		break;
      }
  }

第七步 监测余牌加红中是否有效组合

   //第七步 监测余牌加红中是否有效组合
   function checkHong($OtherCard){    
      	$card  = $OtherCard[0];
      	$card1 = $card + 1;
      	$card2 = $card + 2; 
      	if(in_array($card1, $OtherCard) && substr($card,0,1) == substr($card1,0,1)){
      
      		array_splice($OtherCard,0,2);
      	}else if(in_array($card+2, $OtherCard) && substr($card,0,1) == substr($card2,0,1)){ 
      
      		array_splice($OtherCard,0,2);
      	}
       
      	$OtherCard_0 = [];
      	foreach ($OtherCard as $key => $value) {
      		if ($value != 41) { 
      			if ($value != $card) {
      				$OtherCard_0[] = $value;
      			}
      		}
      	} 
      	return  $OtherCard_0;    
   }
   
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值