Files
Socket/freedom/utils/CardPositionNn.php
li 4d0154f3ac fix: 四条判断优先级调整为高于五公
JJJJK 这种牌既是五公又是四条,客户要求四条 > 五公,
将四条判断移到五公之前
2026-02-11 17:36:15 +08:00

732 lines
23 KiB
PHP

<?php
namespace freedom\utils;
/**
* TODO 卡牌工具类(NN)
* Class CardPositionNn
* @package freedom\utils
*/
class CardPositionNn
{
/**
* TODO 发牌顺序 [识别]
* @param int $id 卡牌
* @return array;
*/
public static function nnOrderSb(int $id): array
{
$order = array();
//闲一先发牌
if($id == 1){
$order[0]="player_1_card_1";
$order[1]="player_1_card_2";
$order[2]="player_1_card_3";
$order[3]="player_1_card_4";
$order[4]="player_1_card_5";
$order[5]="player_2_card_1";
$order[6]="player_2_card_2";
$order[7]="player_2_card_3";
$order[8]="player_2_card_4";
$order[9]="player_2_card_5";
$order[10]="player_3_card_1";
$order[11]="player_3_card_2";
$order[12]="player_3_card_3";
$order[13]="player_3_card_4";
$order[14]="player_3_card_5";
$order[15]="banker_card_1";
$order[16]="banker_card_2";
$order[17]="banker_card_3";
$order[18]="banker_card_4";
$order[19]="banker_card_5";
}
if($id == 2){
$order[0]="player_2_card_1";
$order[1]="player_2_card_2";
$order[2]="player_2_card_3";
$order[3]="player_2_card_4";
$order[4]="player_2_card_5";
$order[5]="player_3_card_1";
$order[6]="player_3_card_2";
$order[7]="player_3_card_3";
$order[8]="player_3_card_4";
$order[9]="player_3_card_5";
$order[10]="banker_card_1";
$order[11]="banker_card_2";
$order[12]="banker_card_3";
$order[13]="banker_card_4";
$order[14]="banker_card_5";
$order[15]="player_1_card_1";
$order[16]="player_1_card_2";
$order[17]="player_1_card_3";
$order[18]="player_1_card_4";
$order[19]="player_1_card_5";
}
if($id == 3){
$order[0]="player_3_card_1";
$order[1]="player_3_card_2";
$order[2]="player_3_card_3";
$order[3]="player_3_card_4";
$order[4]="player_3_card_5";
$order[5]="banker_card_1";
$order[6]="banker_card_2";
$order[7]="banker_card_3";
$order[8]="banker_card_4";
$order[9]="banker_card_5";
$order[10]="player_1_card_1";
$order[11]="player_1_card_2";
$order[12]="player_1_card_3";
$order[13]="player_1_card_4";
$order[14]="player_1_card_5";
$order[15]="player_2_card_1";
$order[16]="player_2_card_2";
$order[17]="player_2_card_3";
$order[18]="player_2_card_4";
$order[19]="player_2_card_5";
}
if($id == 4){
$order[0]="banker_card_1";
$order[1]="banker_card_2";
$order[2]="banker_card_3";
$order[3]="banker_card_4";
$order[4]="banker_card_5";
$order[5]="player_1_card_1";
$order[6]="player_1_card_2";
$order[7]="player_1_card_3";
$order[8]="player_1_card_4";
$order[9]="player_1_card_5";
$order[10]="player_2_card_1";
$order[11]="player_2_card_2";
$order[12]="player_2_card_3";
$order[13]="player_2_card_4";
$order[14]="player_2_card_5";
$order[15]="player_3_card_1";
$order[16]="player_3_card_2";
$order[17]="player_3_card_3";
$order[18]="player_3_card_4";
$order[19]="player_3_card_5";
}
return $order;
}
/**
* TODO 发牌顺序 [识别]
* @param int $id 卡牌
* @return array;
*/
public static function nnOrderNumSb(int $id): array
{
$orderNum = array();
//闲一先发牌
if($id == 1){
$orderNum[0]="11";
$orderNum[1]="12";
$orderNum[2]="13";
$orderNum[3]="14";
$orderNum[4]="15";
$orderNum[5]="21";
$orderNum[6]="22";
$orderNum[7]="23";
$orderNum[8]="24";
$orderNum[9]="25";
$orderNum[10]="31";
$orderNum[11]="32";
$orderNum[12]="33";
$orderNum[13]="34";
$orderNum[14]="35";
$orderNum[15]="41";
$orderNum[16]="42";
$orderNum[17]="43";
$orderNum[18]="44";
$orderNum[19]="45";
}
if($id == 2){
$orderNum[0]="21";
$orderNum[1]="22";
$orderNum[2]="23";
$orderNum[3]="24";
$orderNum[4]="25";
$orderNum[5]="31";
$orderNum[6]="32";
$orderNum[7]="33";
$orderNum[8]="34";
$orderNum[9]="35";
$orderNum[10]="41";
$orderNum[11]="42";
$orderNum[12]="43";
$orderNum[13]="44";
$orderNum[14]="45";
$orderNum[15]="11";
$orderNum[16]="12";
$orderNum[17]="13";
$orderNum[18]="14";
$orderNum[19]="15";
}
if($id == 3){
$orderNum[0]="31";
$orderNum[1]="32";
$orderNum[2]="33";
$orderNum[3]="34";
$orderNum[4]="35";
$orderNum[5]="41";
$orderNum[6]="42";
$orderNum[7]="43";
$orderNum[8]="44";
$orderNum[9]="45";
$orderNum[10]="11";
$orderNum[11]="12";
$orderNum[12]="13";
$orderNum[13]="14";
$orderNum[14]="15";
$orderNum[15]="21";
$orderNum[16]="22";
$orderNum[17]="23";
$orderNum[18]="24";
$orderNum[19]="25";
}
if($id == 4){
$orderNum[0]="41";
$orderNum[1]="42";
$orderNum[2]="43";
$orderNum[3]="44";
$orderNum[4]="45";
$orderNum[5]="11";
$orderNum[6]="12";
$orderNum[7]="13";
$orderNum[8]="14";
$orderNum[9]="15";
$orderNum[10]="21";
$orderNum[11]="22";
$orderNum[12]="23";
$orderNum[13]="24";
$orderNum[14]="25";
$orderNum[15]="31";
$orderNum[16]="32";
$orderNum[17]="33";
$orderNum[18]="34";
$orderNum[19]="35";
}
return $orderNum;
}
/**
* TODO 发牌顺序
* @param int $id 卡牌
* @return array;
*/
public static function nnOrder(int $id): array
{
$order = array();
//庄一先发牌
if($id == 1){
$order[0]="player_1_card_1";
$order[1]="player_2_card_1";
$order[2]="player_3_card_1";
$order[3]="banker_card_1";
$order[4]="player_1_card_2";
$order[5]="player_2_card_2";
$order[6]="player_3_card_2";
$order[7]="banker_card_2";
$order[8]="player_1_card_3";
$order[9]="player_2_card_3";
$order[10]="player_3_card_3";
$order[11]="banker_card_3";
$order[12]="player_1_card_4";
$order[13]="player_2_card_4";
$order[14]="player_3_card_4";
$order[15]="banker_card_4";
$order[16]="player_1_card_5";
$order[17]="player_2_card_5";
$order[18]="player_3_card_5";
$order[19]="banker_card_5";
}
if($id == 2){
$order[0]="player_2_card_1";
$order[1]="player_3_card_1";
$order[2]="banker_card_1";
$order[3]="player_1_card_1";
$order[4]="player_2_card_2";
$order[5]="player_3_card_2";
$order[6]="banker_card_2";
$order[7]="player_1_card_2";
$order[8]="player_2_card_3";
$order[9]="player_3_card_3";
$order[10]="banker_card_3";
$order[11]="player_1_card_3";
$order[12]="player_2_card_4";
$order[13]="player_3_card_4";
$order[14]="banker_card_4";
$order[15]="player_1_card_4";
$order[16]="player_2_card_5";
$order[17]="player_3_card_5";
$order[18]="banker_card_5";
$order[19]="player_1_card_5";
}
if($id == 3){
$order[0]="player_3_card_1";
$order[1]="banker_card_1";
$order[2]="player_1_card_1";
$order[3]="player_2_card_1";
$order[4]="player_3_card_2";
$order[5]="banker_card_2";
$order[6]="player_1_card_2";
$order[7]="player_2_card_2";
$order[8]="player_3_card_3";
$order[9]="banker_card_3";
$order[10]="player_1_card_3";
$order[11]="player_2_card_3";
$order[12]="player_3_card_4";
$order[13]="banker_card_4";
$order[14]="player_1_card_4";
$order[15]="player_2_card_4";
$order[16]="player_3_card_5";
$order[17]="banker_card_5";
$order[18]="player_1_card_5";
$order[19]="player_2_card_5";
}
if($id == 4){
$order[0]="banker_card_1";
$order[1]="player_1_card_1";
$order[2]="player_2_card_1";
$order[3]="player_3_card_1";
$order[4]="banker_card_2";
$order[5]="player_1_card_2";
$order[6]="player_2_card_2";
$order[7]="player_3_card_2";
$order[8]="banker_card_3";
$order[9]="player_1_card_3";
$order[10]="player_2_card_3";
$order[11]="player_3_card_3";
$order[12]="banker_card_4";
$order[13]="player_1_card_4";
$order[14]="player_2_card_4";
$order[15]="player_3_card_4";
$order[16]="banker_card_5";
$order[17]="player_1_card_5";
$order[18]="player_2_card_5";
$order[19]="player_3_card_5";
}
return $order;
}
/**
* TODO 发牌顺序
* @param int $id 卡牌
* @return array;
*/
public static function nnOrderNum(int $id): array
{
$orderNum = array();
//庄一先发牌
if($id == 1){
$orderNum[0]="11";
$orderNum[1]="21";
$orderNum[2]="31";
$orderNum[3]="41";
$orderNum[4]="12";
$orderNum[5]="22";
$orderNum[6]="32";
$orderNum[7]="42";
$orderNum[8]="13";
$orderNum[9]="23";
$orderNum[10]="33";
$orderNum[11]="43";
$orderNum[12]="14";
$orderNum[13]="24";
$orderNum[14]="34";
$orderNum[15]="44";
$orderNum[16]="15";
$orderNum[17]="25";
$orderNum[18]="35";
$orderNum[19]="45";
}
if($id == 2){
$orderNum[0]="21";
$orderNum[1]="31";
$orderNum[2]="41";
$orderNum[3]="11";
$orderNum[4]="22";
$orderNum[5]="32";
$orderNum[6]="42";
$orderNum[7]="12";
$orderNum[8]="23";
$orderNum[9]="33";
$orderNum[10]="43";
$orderNum[11]="13";
$orderNum[12]="24";
$orderNum[13]="34";
$orderNum[14]="44";
$orderNum[15]="14";
$orderNum[16]="25";
$orderNum[17]="35";
$orderNum[18]="45";
$orderNum[19]="15";
}
if($id == 3){
$orderNum[0]="31";
$orderNum[1]="41";
$orderNum[2]="11";
$orderNum[3]="21";
$orderNum[4]="32";
$orderNum[5]="42";
$orderNum[6]="12";
$orderNum[7]="22";
$orderNum[8]="33";
$orderNum[9]="43";
$orderNum[10]="13";
$orderNum[11]="23";
$orderNum[12]="34";
$orderNum[13]="44";
$orderNum[14]="14";
$orderNum[15]="24";
$orderNum[16]="35";
$orderNum[17]="45";
$orderNum[18]="15";
$orderNum[19]="25";
}
if($id == 4){
$orderNum[0]="41";
$orderNum[1]="11";
$orderNum[2]="21";
$orderNum[3]="31";
$orderNum[4]="42";
$orderNum[5]="12";
$orderNum[6]="22";
$orderNum[7]="32";
$orderNum[8]="43";
$orderNum[9]="13";
$orderNum[10]="23";
$orderNum[11]="33";
$orderNum[12]="44";
$orderNum[13]="14";
$orderNum[14]="24";
$orderNum[15]="34";
$orderNum[16]="45";
$orderNum[17]="15";
$orderNum[18]="25";
$orderNum[19]="35";
}
return $orderNum;
}
/**
* TODO 发牌第一家
* @param int $id 卡牌
* @return int|bool;
*/
public static function nnPosition(int $id){
$num = CardPosition::interchangeCard($id);
if($num == false){
return false;
}else{
$positionNum = $num%4;
}
if($positionNum == 0){
$positionNum = 4;
}
return $positionNum;
}
/**
* TODO nn结果
* @param array $card 卡牌
* @return array;
*/
public static function JudgeCowCow(array $card): array
{
//获取五张牌中最大的牌
$compare = $card;
for($i=0;$i<4;$i++){
for($j=$i+1;$j<5;$j++){
if(substr($compare[$i],1,2) < substr($compare[$j],1,2)){
$a = $compare[$i];
$compare[$i] = $compare[$j];
$compare[$j]=$a;
}
}
}
$maxCard = substr($compare['0'],1,2);
if(substr($maxCard,0,1) == 0){
$maxCard = substr($maxCard,1,1);
}
$sameNum = 0;
for($i=0;$i<5; $i++){
$card[$i] = substr($card[$i],1,2);
if(substr($card[$i],0,1) == 0){
$card[$i] = substr($card[$i],1,1);
}
if($card[$i] == $maxCard){
$sameNum++;
}
}
$max = $compare['0'];
if($sameNum > 1){
$compare = array_slice($compare,0,$sameNum);
for($i=0;$i<$sameNum-1;$i++){//对5张牌从大到小排序。
for($j=$i+1;$j<$sameNum;$j++){
if($compare[$i] > $compare[$j]){
$a = $compare[$i];
$compare[$i] = $compare[$j];
$compare[$j]=$a;
}
}
}
$max = $compare['0'];
}
$cow = -1;
//计算5张牌总值,cow计算牛几。
$cardAll = 0;
$n= 0 ;//存储10、J、Q、K张数。
$king = 0;//存储J、Q、K张数。
$result = array();
//计算J、Q、K张数。
for($i=0;$i<5;$i++){
if($card[$i] >= 11){
$king++;
}
}
$word = '';
//判断四条(炸弹):4张相同点数,四条 > 五公
$cardNums = [];
for($i=0;$i<5;$i++){
$cardNums[] = $card[$i];
}
$counts = array_count_values($cardNums);
if(max($counts) >= 4){
$cow = 12;
$word = '四条';
$result['word'] = $word;
$result['cow'] = $cow;
$result['max'] = $max;
return $result;
}
if($king == 5){
$cow = 11;
$word = '五公';
$result['word'] = $word;
$result['cow'] = $cow;
$result['max'] = $max;
return $result;
}
for($i=0;$i<4;$i++){//对5张牌从大到小排序。
for($j=$i+1;$j<5;$j++){
if($card[$i] < $card[$j]){
$a = $card[$i];
$card[$i] = $card[$j];
$card[$j]=$a;
}
}
}
for($i=0;$i<5;$i++){
if($card[$i] >= 10){
$n++;
$card[$i] = 10;
}
$cardAll += $card[$i];
}
switch ($n){
case 0: //5张牌中没有一张10、J、Q、K。
for($i=0;$i<4;$i++){
for($j=$i + 1;$j<5;$j++){
if(($cardAll - $card[$i]- $card[$j])%10==0){
$cow=($card[$i] + $card[$j])%10;
}
}
}
break;
case 1: //5张牌中有一张10、J、Q、K。
//先判断是否有牛牛,不能判断剩余四张相加为10倍数为牛牛,如 Q 8 5 4 3
//只能先判断两张是否是10的倍数,如果是再判断剩余是否是10的倍数;有限判断出牛牛;再来判断三张是否有10的倍数,有的话有牛,否则无牛
for($i =1; $i < 4; $i ++){
for($j = $i +1; $j < 5; $j++){
if(($card[$i] + $card[$j]) % 10 == 0){
$cow=($cardAll - $card[0])%10;
}
}
}
//判断是否有牛
for($i=1; $i<5; $i++){ //剩下四张牌有三张加起来等于10
if(($cardAll - $card[0] - $card[$i])%10==0){
$cow=($cardAll-$card[0])%10;
break;
}
}
break;
case 2: //5张牌中有两张10、J、Q、K。 三张是个牛就有问题,应该优先输出
if(($cardAll - $card[0] - $card[1])%10 == 0){//优先牛牛输出 如 J Q 2 3 5;这里先检查剩余是否为牛牛,否则算法有漏洞
$cow = 0;
}else{
//10 10 6 5 3 n=2 i=3 j=4 cardAll = 34
for($i=$n;$i<4;$i++){//剩下三(四)张牌有两张加起来等于10。
for($j=$i+1;$j<5;$j++){
if(($card[$i]+$card[$j])==10){
$temp = $cardAll;
for($k=0;$k<$n;$k++){
$temp -= $card[$k]; // 18
$cow = $temp%10; //8
}
}
}
}
}
break;
case 3: //5张牌中有三张10、J、Q、K。
case 4: //5张牌中有四张10、J、Q、K。
case 5: //5张牌中五张都是10、J、Q、K。
for($i=0;$i<$n;$i++){//总值减去10、J、Q、K的牌。
$cardAll -= $card[$i];
}
$cow = $cardAll%10;
break;
}
switch ($cow){
case 0:
$word = 'NN';
break;
case 1:
$word = 'N1';
break;
case 2:
$word = 'N2';
break;
case 3:
$word = 'N3';
break;
case 4:
$word = 'N4';
break;
case 5:
$word = 'N5';
break;
case 6:
$word = 'N6';
break;
case 7:
$word = 'N7';
break;
case 8:
$word = 'N8';
break;
case 9:
$word = 'N9';
break;
case -1:
$word = 'N0';
break;
}
if($cow == -1){
$cow = 0;
}else if($cow == 0){
$cow = 10;
}
$result['word'] = $word;
$result['cow'] = $cow;
$result['max'] = $max;
return $result;
}
/**
* TODO NN比较两张牌大小
* @param int $card1 卡牌
* @param int $card2 卡牌
* @return int;
*/
public static function compareCard(int $card1, int $card2): int
{
$card1Num = CardPosition::interchangeCard($card1);
$card2Num = CardPosition::interchangeCard($card2);
$card1Color = CardPosition::interchangeColor($card1);
$card2Color = CardPosition::interchangeColor($card2);
if($card1Num > $card2Num){
return 1;
}elseif($card1Num < $card2Num){
return 0;
}else{
if($card1Color > $card2Color){
return 0;
}else{
return 1;
}
}
}
/**
* TODO NN识别固定位置
* @param int $position 位置
* @return string;
*/
public static function sbStaticCardPosition(int $position): string
{
$result = '';
switch($position) {
case 1:
$result = "player_1_card_1";
break;
case 2:
$result = "player_1_card_2";
break;
case 3:
$result = "player_1_card_3";
break;
case 4:
$result = "player_1_card_4";
break;
case 5:
$result = "player_1_card_5";
break;
case 6:
$result = "player_2_card_1";
break;
case 7:
$result = "player_2_card_2";
break;
case 8:
$result = "player_2_card_3";
break;
case 9:
$result = "player_2_card_4";
break;
case 10:
$result = "player_2_card_5";
break;
case 11:
$result = "player_3_card_1";
break;
case 12:
$result = "player_3_card_2";
break;
case 13:
$result = "player_3_card_3";
break;
case 14:
$result = "player_3_card_4";
break;
case 15:
$result = "player_3_card_5";
break;
case 16:
$result = "banker_card_1";
break;
case 17:
$result = "banker_card_2";
break;
case 18:
$result = "banker_card_3";
break;
case 19:
$result = "banker_card_4";
break;
case 20:
$result = "banker_card_5";
break;
}
return $result;
}
}