检查扑克直

Check for poker straight

我已经成功地创建了一个算法来检查一手牌的排名。它 100% 正确地工作,但速度很慢。我一直在分析代码,check straight 函数是其中最慢的部分之一。

所以我的问题是,有没有更好的方法来计算一手牌是否顺子?

这里有一些细节:

7 张牌,持有人 2 张,牌面 5 张。 A 可高可低。

每张卡片都分配了一个值: 2 = 2 3 = 3 .. 9 = 9 T = 10 J = 11 问 = 12 K = 13 A = 14

该脚本包含所有 7 张卡片的数组:

$cards = array(12,5,6,7,4,11,3);

所以现在我需要能够将其排序到一个数组中:

要快;循环和迭代非常昂贵。这是我目前使用的,当它试图分析 15000 手牌时,它会对脚本造成影响。

对于以上,我使用了:

有没有人有任何我可以改进的例子?甚至可以用另一种语言,我也许可以看看它是如何完成的?

与其使用数组重复数据删除和排序,不如考虑使用位掩码,并将设置卡值的位设置为 1。位掩码的工作方式类似于 Set 数据结构,并且在检测连续元素时具有额外的优势。

for ($i = 0; $i < count($cards); $i++) {
    $card = $cards[$i];
    // For each card value, set the bit
    if ($card == 14) {
        // If card is an ace, also set bit 1 for wheel
        $cardBitmask |= 0x2;
    }
    $cardBitmask |= (1 << $card);
}

// To compare, you simply write a for loop checking for 5 consecutive bits
for($i = 10; $i > 0; $i--)
{
    if ($cardBitmask & (0x1F << $i) == (0x1F << $i)) {
        // Straight $i high was found!
    }
} 

考虑 this link 的 Java 实施。我把它放在这里了:

public static boolean isStraight( Card[] h )
{
  int i, testRank;

  if ( h.length != 5 )
     return(false);

  sortByRank(h);      // Sort the poker hand by the rank of each card      

  /* ===========================
     Check if hand has an Ace
     =========================== */
  if ( h[4].rank() == 14 )
  {
     /* =================================
        Check straight using an Ace
        ================================= */
     boolean a = h[0].rank() == 2 && h[1].rank() == 3 &&
                 h[2].rank() == 4 && h[3].rank() == 5 ;
     boolean b = h[0].rank() == 10 && h[1].rank() == 11 &&        
                 h[2].rank() == 12 && h[3].rank() == 13 ;

     return ( a || b );
  }
  else
  {
     /* ===========================================
        General case: check for increasing values
        =========================================== */
     testRank = h[0].rank() + 1;

     for ( i = 1; i < 5; i++ )
     {
        if ( h[i].rank() != testRank )
           return(false);        // Straight failed...

        testRank++;   // Next card in hand
     }

     return(true);        // Straight found !
  }
}

快速 Google 搜索 "check for poker straight (desired_lang)" 将为您提供其他实现。

你可以这样走,你不需要排序或任何东西(假设2是2,14是ace):

$cards = [12,5,6,7,4,11,3];

function _inc(&$i) {
    if ($i == 14) 
        $i = 2;
    else
        $i++;
    return $i;
}

$straight = false;
for($i = 2; $i <= 14; $i++) {
    $ind = $i;
    if (!in_array($ind, $cards)) continue;
    $s = [$ind, _inc($ind), _inc($ind), _inc($ind), _inc($ind)];    
    $straight = count(array_intersect($s, $cards)) == count($s);
    if ($straight) break;
}

print $straight;

您可以对卡片进行排序并在数组中循环遍历它们 - 始终保存最后一张卡片并将它们与当前卡片进行比较。

$cards = array(12,5,6,7,4,11,3);
sort($cards);

$last = 0;
$count = 0;
$wheel = false;
foreach ($cards as $card) {
    if ($card == $last) {
        continue;
    } else if ($card == ++$last) {
        $count++;
    } else {
        if ($last == 6) $wheel = true;
        $count = 1;
        $last = $card;
    }

    if ($count == 5 || ($card == 14 && $wheel)) {
        echo "straight $last";
        $straight = range($last - 4, $last);
        break;
    }
}