2015-09-25 48 views
1

我目前正在尝试制定一个扑克算法,以确定赢得牌局的机会。它需要非常快速,因为每次都需要循环数十万只手。PHP获取所有扑克独特的牌局结果

我正在努力做的是能够获得所有可能出现在董事会的独特的手。一块板子包含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

误解了你的问题,所以我编辑了我的答案。 – m69

回答

2

你在做什么基本上没问题,但是不要每次从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个组合。您可以进一步修剪这些组合,因为对于某些人来说,西装并不重要,但这可能会变得非常复杂。


起初,我误解你的问题,并给了下面的答案,这并不能完全解决您的具体问题。我没有删除它,因为它已经有了upvote,所以有人显然觉得它有用。

用所有卡创建一个数组。创建一个仍有剩余卡数的变量: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());

+0

非常感谢!第一部分中的for循环确实解决了我的问题 - 我无法正确地将头部中的数据可视化,但是现在看到代码后它运行得非常好。 – Patchesoft

0

创建所有卡阵列来拔卡从

创建充分利用阵列卡时已经使用

卡空数组所有卡将它添加到第二阵列,并从中删除拳头阵列(未设置),所以你不能再捡起来......

$chosen_card = array_rand($card_set);  // just choosing a card randomly to simulate whatever way you currently pick one 
$known_cards[] = $card_set[$chosen_card]; // copy the card to the know_cards array 
unset($card_set[$chosen_card]);   // remove cards from unused cards 

这样$ chosen_card在任何时候只有未使用的卡和$ known_cards已全部alredy取卡。

0

如果你只是想从一组已知的所有独特的组合,可以实现如下算法:在重新阅读更加用心,我意识到自己

$card_set = [1,2,3,4,5]; 
$k = 3; 
$n = count($card_set); 
$combs = []; 
$stack = [[[],0,0]]; 

while (!empty($stack)){ 
    $params = array_pop($stack); 

    $current_hand = $params[0]; 
    $i = $params[1]; 
    $len = $params[2]; 

    if ($len == $k){ 
    array_push($combs,$current_hand); 
    } else { 
    if ($i < $n - 1){ 
     array_push($stack,[$current_hand,$i + 1,$len]); 
    } 
    if ($i < $n){ 
     array_push($current_hand,$card_set[$i]); 
     array_push($stack,[$current_hand,$i + 1,$len + 1]); 
    } 
    } 
} 

print_r($combs);