用PHP实现一个关于德州扑克算法的程序(三):顺子

用上一篇文章的算法已经可以解决大部分牌型的计算,但是还缺少另外一种牌型的计算,那就是顺子。
顺子的特点是至少有5张点数连续的牌面,而且输入的数据是字母与数字混合的数组,不利于排序。因此必须对这样的情况进行转换:

function pointToNum($arr){
    $num=0;
    //统计在这副牌型中点数为数字的情况,从而判断A是做14合适还是作1合适
    foreach($arr as $p){
        if(!is_numeric($p))
           $num++;
    }

    foreach($arr as $p){
        switch($p){
            case "A":
                if($num>=5){
                    $poi[]=14;
                }else{
                    $poi[]=1;//A还可以作为1使用
                }
                break;
            case "K":
                $poi[]=13;
                break;
            case "Q":
                $poi[]=12;
                break;
            case "J":
                $poi[]=11;
                break;
            case "T":
                $poi[]=10;
                break;
            default:
                $poi[]=$p;
                break;
        }
    }
    return $poi;
}

经过转换后再进行相应的排序计算,计算之后,又必须按照相反的途径把转换之后的数据再转换回来:

function numToPoint($arr){
    foreach($arr as $p){
        switch($p){
            case "14":
            case "1":
                $poi[]="A";
                break;
            case "13":
                $poi[]="K";
                break;
            case "12":
                $poi[]="Q";
                break;
            case "11":
                $poi[]="J";
                break;
            case "10":
                $poi[]="T";
                break;
            default :
                $poi[]=$p;
        }
    }
    return $poi;
}

然后再开始写判断顺子的主要代码:

function isStraight($cards){

    //只取出点数,不需要花色
    foreach($cards as $c){
        $point.=$c[1];
    }
    //把由点数组成的字符串转换为数组,并且去掉其中重复的元素
    $po=array_unique(str_split($point));
    //经过去重的数组如果元素少于5个,那么就已经没有达到顺子至少5张不同牌组成的基本条件
    if(count($po)<5){
        return false;
    }else{
        //把字母点数全部转换成容易排序的数字点数
        $po=pointToNum($po);
        //倒序排序
        arsort($po);
        //重新索引数组
        $a1=array_values($po);
        //设置一个变量j。按照顺序计算两个相邻元素是否符合顺子的情况,即元素i与元素i+1是否相差为1。如果是则j+1,如果不是则j-1,但是j不小于0。当j累加到4时,说明顺子的情况满足了,则返回这个由顺子组成的数组
        $j=0;
        for($i=1;$i<count($a1);$i++){
            //判断相邻元素的差值是否为1
            if($a1[$i]==$a1[$i-1]-1){
                $j++;
                //如果两个元素相差为1,则同时取出两个元素放入一个新数组
                $a2[]=array_search($a1[$i-1],$po);
                $a2[]=array_search($a1[$i],$po);
                //当j==4时,则说明已经符合了顺子的条件可以取出顺子数组,而且由于采用的是倒序排序,所以这个顺子必然是牌型中最大的顺子
                if($j==4){
                    $a2=array_unique($a2);//去掉重复值
                    $a2=array_values($a2);//重建索引
                    $a2=array_slice($a2,0,5);//取出5个元素                    
                    for($i=0;$i<count($a2);$i++){
                        $result[]=$po[$a2[$i]];
                    }
                    break;                    
                }
            }else{
                //在判断过程中,一旦发现相邻元素差值为1的情况有变化,则j立即减1
                $j=$j==0?0:--$j;                
            }
        }
        //把数字点数再转换回字母点数
        $arr=numToPoint($result);
        return $arr;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值