PHP 获取扑克的所有独特棋盘结果

标签 php algorithm for-loop poker

我目前正在尝试制作一种扑克牌算法来确定赢得一手牌的机会。它需要非常快,因为它每次都必须循环通过数十万只不同的手。

我正在努力做的是能够让所有可能出现在公共(public)牌面的独特牌局。一个棋盘包含 5 张牌。

每次有一张牌出现在棋盘上,那张牌就不能再出现了。

因此,为了获得所有可能的棋盘组合,我一直在做的是使用 for 循环遍历所有可能的结果。

对于这个例子,我将只拿到棋盘的前 3 张牌。

代码是这样的:

// $card_set_count is the amount of cards left in the deck after taking away the
// user's hand cards.
for($i=0;$i<$card_set_count;$i++) {
    // First known card
    $known_card1 = $card_set[$i];

    for($j=0;$j<$card_set_count;$j++) {
        // Second known card
        $known_card2 = $card_set[$j];
        // Skip the card if we already have it out
        if($known_card1 == $known_card2) continue;

        for($k=0;$k<$card_set_count;$k++) {
            // Third Known Card
            $known_card3 = $card_set[$k];
            // Skip card if the card is already out
            if($known_card3 == $known_card2 || $known_card1 == $known_card3) continue

            // Create board
            $board = array();
            $board[] = $known_card1;
            $board[] = $known_card2;
            $board[] = $known_card3;
        }
    }
}

这确实为我提供了所有可能的棋盘组合。唯一的问题是它也给我重复的值,例如板:

广告 6d 4c

相同

4c 广告 6d

我可以在我的棋盘列表上运行 array_unique(),但问题是我的 forloop 必须循环遍历 91020 手牌。这对我的算法来说太慢了。

我只是想知道是否有人对遍历可能的板有更好的想法。

将棋盘值存储在一个数组中,然后测试卡片值是否在列表中仍然很慢。有没有一种方法可以只循环遍历独特的棋盘组合?

最佳答案

你所做的基本上没问题,但不是每次都从 0 迭代到 $card_set_count,第二张牌应该只从第一张牌之后的牌中挑选,并且第三张牌只能从第二张牌之后的牌中挑选,如下所示:

for($i=0;$i<$card_set_count - 2;$i++) {
    for($j=$i + 1;$j<$card_set_count - 1;$j++) {
        for($k=$j + 1;$k<$card_set_count;$k++) {
            $board = array();
            $board[] = $card_set[$i];
            $board[] = $card_set[$j];
            $board[] = $card_set[$k];
            // evaluate hand ...
        }
    }
}

如果牌组中还剩 50 张牌,则有 19600 种组合。您可以进一步修剪这些组合,因为对于某些牌来说花色并不重要,但这可能会变得非常复杂。


起初我误读了你的问题,并在下面给出了答案,这并没有完全解决你的具体问题。我没有删除它,因为它已经有一个赞成票,所以显然有人发现它很有用。

创建一个包含所有卡片的数组。创建一个包含剩余卡片数量的变量:cardsLeft = 52。然后,当你需要选择一张牌时,随机选择1到52张牌,将选择的牌与52号牌交换,并将cardsLeft设置为51。下一张牌,你从1到51号牌中选择, 将其与卡片 51 交换,将 cardsLeft 设置为 50,依此类推...
每当您需要使用新牌组开始新游戏时,只需将 cardsLeft 重置为 52。无需重新初始化或洗牌数组。

我已经很多年没用过 php 了,但这里有一个 Javascript 的例子;这是不言自明的。运行代码片段为三名玩家画一手扑克牌(请参阅控制台中的输出)。

function Deck() {
    this.cards = [];
    this.left = 52;
    for (var suit = 0; suit < 4; suit++) {
        for (var number = 0; number < 13; number++) {
            this.cards.push("23456789TJQKA".charAt(number) + "cdhs".charAt(suit));
        }
    }
}
Deck.prototype.draw = function() {
    if (this.left == 0) this.shuffle();
    var pick = Math.floor(Math.random() * this.left);
    var swap = this.cards[pick];
    this.cards[pick] = this.cards[--this.left];
    this.cards[this.left] = swap;
    return swap;
}
Deck.prototype.shuffle = function() {
    this.left = 52;
}

var d = new Deck();
document.write("player 1: " + d.draw() + "," + d.draw() + "<BR>");
document.write("player 2: " + d.draw() + "," + d.draw() + "<BR>");
document.write("player 3: " + d.draw() + "," + d.draw() + "<BR>");
document.write("flop: " + d.draw() + "," + d.draw()+ "," + d.draw() + "<BR>");
document.write("turn: " + d.draw() + "<BR>");
document.write("river: " + d.draw());

关于PHP 获取扑克的所有独特棋盘结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32787189/

相关文章:

php - Laravel 4 - 从模型中返回平均分数?

php - Services_Twilio_TinyHttpException 错误 PHP

javascript - 使用 vanillaJS 无限绘制/取消绘制 SVG 路径循环

php - ./和 ../在 PHP 中的区别

php - 从 API 获取数据时诊断瓶颈

algorithm - 特殊的二叉树,一个棘手的问题?

algorithm - 无序二叉树的用例是什么?

java - Java中的合并排序实现问题

javascript - 从 javascript for 循环创建 JSON 字符串

c - 将 for 循环中的值存储到数组中