我设法创建了一个算法来检查扑克牌的排名。它100%正确工作,但速度很慢。我一直在分析代码,而直接检查功能是其中最慢的部分之一。
所以我的问题是,有没有更好的方法来计算一只手是否伸直?
以下是一些细节:
7张牌,2张牌,5张牌。 A可以高或低。
每张卡都分配了一个值: 2 = 2 3 = 3 .. 9 = 9 T = 10 J = 11 Q = 12 K = 13 A = 14
该脚本包含所有7张卡的数组:
$cards = array(12,5,6,7,4,11,3);
所以现在我需要能够将它排序到一个数组中:
它需要快速;循环和迭代非常昂贵。这就是我目前使用的,当它试图分析说15000手时,它会对脚本产生影响。
对于上述内容,我使用了:
有没有人有任何关于如何改进这方面的例子?也许甚至用另一种我可能会看到的语言看看它是如何完成的?
答案 0 :(得分:4)
不要使用数组重复数据删除和排序,而是考虑使用位掩码,并将位设置为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!
}
}
答案 1 :(得分:1)
考虑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快速搜索&#34;直接查看扑克(desired_lang)
&#34;将为您提供其他实施。
答案 2 :(得分:1)
您可以对卡片进行排序并在阵列中循环它们 - 始终保存最后一张卡片并将其与当前卡片进行比较。
$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;
}
}
答案 3 :(得分:0)
你可能会这样,你不需要排序或任何东西(假设2是2和14是王牌):
$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;