2015-09-25 30 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);