您的位置:首页 > 编程语言 > PHP开发

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

2017-04-16 08:06 260 查看
用上一篇文章的算法已经可以解决大部分牌型的计算,但是还缺少另外一种牌型的计算,那就是顺子。

顺子的特点是至少有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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php 算法