php麻将,php实现四川麻将胡牌(基本胡)

用1-9 一万到九万 10-18 一筒到九筒 19-27 一条到九条 这里就无视缺门了,缺门的问题很简单就不用我多说了。

代码:

//1-9 一万到九万 10-18 一筒到九筒 19-27 一条到九条

$paiArr = [1,1,1,1,2,2,2,2,3,3,3,3,4,4]; //123 123 123 123 44

$paiArr1 = [1,2,2,2,3,3,3,4,4,10,10,10,11,11];// 123 234 234 101010 1111

$paiArr2 = [7,7,7,8,8,8,9,9,9,10,10,11,11,11];//789 789 789 111111 1010

$paiArr3 = [1,2,3,4,5,6,7,8,9,10,11,12,13,13];//123 456 789 101112 1313

asort($paiArr);//每个都要从小到大排序的

asort($paiArr1);//每个都要从小到大排序的

asort($paiArr2);//每个都要从小到大排序的

asort($paiArr3);//每个都要从小到大排序的

echo checkHu($paiArr);

echo checkHu($paiArr1);

echo checkHu($paiArr2);

echo checkHu($paiArr3);

function checkHu($arr){//主函数

$jiangArr = checkJiang($arr);

foreach ($jiangArr as $key=>$index){

$tmpArr = $arr;

unset($tmpArr[$index]);//去除一对将

unset($tmpArr[$index+1]);//去除一对将

$tmpArr = array_values($tmpArr);

for ($i =1;$i<=4;$i++){//最多4个123型的牌,四次循环

$count1 = count($tmpArr);

$tmpArr = check123Pai($tmpArr);

$count2 = count($tmpArr);

if ($count2 == $count1)break;//如果已经找不到123型的牌就结束

}

for ($i =1;$i<=4;$i++){//最多4个111型的牌,四次循环

$count1 = count($tmpArr);

$tmpArr = check111Pai($tmpArr);

$count2 = count($tmpArr);

if ($count2 == $count1)break;//如果已经找不到111型的牌就结束

}

if (count($tmpArr)==0){

return 1;

}

}

return 0;

}

function check123Pai($arr){//找出123类型牌,并将这些牌去除(从第一个牌开始算,看看后面有没有比它大1的,然后再找有没有比它大2的,都有的话就把三张牌剔除,此时数组key变化了,需要array_values一下)

$count = count($arr);

for ($i=0;$i<=$count-3;$i++){

$minPai = $arr[$i];

$max = $minPai>18? 27 : ($minPai>9? 18:9);//这里保证9 10 11这种牌不算(九万一筒二筒不能算的)

for ($j=$i+1;$j<=$count-2;$j++){

if ($arr[$j]

for ($k=$j+1;$k<=$count-1;$k++){

if ($arr[$k]<=$max&&$arr[$k]==$arr[$j]+1 ){

unset($arr[$i]);

unset($arr[$j]);

unset($arr[$k]);

return array_values($arr);

}

}

}

}

}

return $arr;

}

function check111Pai($arr){//找出111类型牌并将这些牌去除(从第一个牌开始算,每次加3,保证三张一样就行,这里有人会问那要是1111这种牌怎么算。这里就涉及到算法的思想了,我先剔除了将,又剔除了123型的牌,如果还有1111型的牌,那肯定胡不了)

$count = count($arr);

for ($i=0;$i<=$count-3;$i=$i+3){

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

unset($arr[$i]);

unset($arr[$i+1]);

unset($arr[$i+2]);

return array_values($arr);

}

}

return $arr;

}

function checkJiang($arr){//返回一对将的offset

$count = count($arr);

$jiangOffset = [];

//里面会有重复的

for ($i=0;$i<=$count-2;$i++){

if ($arr[$i] ==$arr[$i+1]){

$jiangOffset[] = $i;

}

}

//去重

$repeatArr = [];

$tmpCount = count($jiangOffset)-2;

for ($i=0;$i<=$tmpCount;$i++){

if ($arr[$jiangOffset[$i]] ==$arr[$jiangOffset[$i+1]]){

$repeatArr[] = $jiangOffset[$i+1];

}

}

foreach ($jiangOffset as $key=>$value){

if (in_array($value,$repeatArr)){

unset($jiangOffset[$key]);

}

}

return array_values($jiangOffset);

}

function tingPai($arr){//返回听牌的数据

$mineArr = [];

asort($arr);

for ($i=0;$i<=count($arr)-4;$i+=4){

if ($arr[$i] ==$arr[$i+3]){

$mineArr[] = $arr[$i];

}

}

$tingPaiArr = [];

for ($i=1;$i<=27;$i++){

if (in_array($i,$mineArr)){

continue;

}

$arr1 = $arr;

$arr1[] = $i;

asort($arr1);

if (checkHu($arr1)){

$tingPaiArr[] = $i;

}

}

return $tingPaiArr;

}

思路

规则:麻将四坎牌一对将代表基本胡,坎牌比如一万二万三万,三筒三筒三筒。一对将就相同的两张牌比如一条一条,类似于斗地主里的对子。基本胡的基础上才衍生出对对胡,清一色啥的。

首先找出牌里的一对将,当然程序不知道哪对将才能胡牌,这里找出所有的将进行遍历。然后先把将去掉,剩下的判断111型的牌与123型的牌。这里问题来了,先判断哪个类型?这里必须先判断123型,再判断111型,具体原因是笔者实践得出来的。其他算法可能不一样,笔者的算法就是这个顺序。判断能胡牌了,然后再判断什么天胡地胡啥的就方便了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值