根据德扑的规则,有四条、葫芦、三条、两对等牌型,暂时放下同花和顺子的情况,先研究一下这些牌型的算法该怎么写。
对于每个玩家来说,他面对的选择是从7张牌中选出5张牌组合成最大的牌型,所以输入参数是一个有7个元素组成的一维数组,如下面这种形式:
$cards=array("H7", "C7", "S7", "CJ", "CA", "HJ", "DK");
可以一眼看出这可以组成一副葫芦的牌型:三个7带两个J。因为与花色无关,所以只关心点数。取出点数:
foreach($cards as $c){
$point.=$c[1];
}
$po=str_split($point);//字符串转换为数组
$po_count=array_count_values($po);//统计各点数的个数
经过如上处理,最后形成的数组就是如下的形式:
$po_count=array("7"=>3,"J"=>2,"K"=>1,"A"=>1);
而点数中还还包含有T、J、Q、K、A等字母,不便于排序,所以必须进行一次转换
foreach(array_keys($arr) as $v) {
switch ($v) {
case "A":
$poi[] = 14;
break;
case "K":
$poi[] = 13;
break;
case "Q":
$poi[] = 12;
break;
case "J":
$poi[] = 11;
break;
case "T":
$poi[] = 10;
break;
default:
$poi[] = $v;
break;
}
}
经过这样的转换就可以进行排序了,转换之后形成了一个新的数组 poi。同时把点数的个数也形成一个新数组 num。
这两个数组同时组合成一个二维数组:
$puke=array(
"num"=>array_values($arr),
"poi"=>$poi
);
用倒序排序。按要求那个点数出现的次数最多就排在最前面,出现次数相同则以点数大的排前面,所以使用如下语句:
array_multisort($puke["num"], SORT_NUMERIC, SORT_DESC,
$puke["poi"],SORT_NUMERIC, SORT_DESC
);
这样经过处理之后已经达到了我们的要求,就需要把这个二维数组重新在组合成一维数组,而这个一维数组的键是 puke["poi"],值是 puke[“num”]
$arr1= array_combine($puke["poi"],$puke["num"]);
这样组合起来的数组的键名是不符合我们要求的,应为键名还是数字,而不是A,K,Q,J,T。所以又要做一次转换:
foreach($arr1 as $key=>$value){
switch($key){
case "14":
$arr2["A"]=$arr1["14"];
break;
case "13":
$arr2["K"]=$arr1["13"];
break;
case "12":
$arr2["Q"]=$arr1["12"];
break;
case "11":
$arr2["J"]=$arr1["11"];
break;
case "10":
$arr2["T"]=$arr1["10"];
break;
default:
$arr2[$key]=$value;
break;
}
}
经过这样的转换之后,就完全符合预期的要求了,排序这部分也就完成了。