2015-03-31 29 views
1

擁有一張代表5張拾取完整牌組中的5張牌的數組(52張牌)。因此,隨機手看起來像這樣['H3','H6','D3','D4','S4'](這裏是h 2對4和3)。
我正在尋找一種方式來了解隨機5張牌這種性質:如何檢測抽牌遊戲中的「手牌」

  • 什麼手的名字就是它了。即:「四種一種」,「三種一種」等 上。
  • 這隻手的概率是多少,請記住它是一個完美的隨機數 。
  • 我可以選擇的數據結構
  • 我使用C#
+0

您需要知道撲克牌的手牌以及您的數據結構如何表示牌?然後參加500或600級的高校概率數學課(或在維基百科上查看)。 – crashmstr 2015-03-31 13:03:48

+2

看起來像你被處理了兩對 - 四和三。 – alex 2015-03-31 13:04:15

+1

手是一個什麼樣的數組?字符串?還有別的嗎?你可以自由選擇數據結構嗎?這是你正在問的東西(它應該是什麼)還是已經給出的數據結構?有沒有使用特定的編程語言? – 2015-03-31 13:52:36

回答

1

首先設置一些數據結構來表示套裝,行列,牌和手牌。有很多方法可以做到這一點以獲得良好的性能,例如使用位向量,但假設我們想讓它變得可讀:爲套裝和行列製作枚舉,爲卡片製作一個結構,爲一隻手製作一個類。順便說一句,這種類型的例子是你希望你是using F#

注意:代碼僅用於說明目的:它從未見過編譯器。不要期望粘貼這個&運行。

enum Suit { Spades, Hearts, Diamonds, Clubs } 
enum Rank { Two, Three, Four, Five, Six, Seven, 
      Eight, Nine, Ten, Jack, Queen, King, Ace } 

enum HandType { Nothing, Pair, TwoPair, ThreeOfAKind, Straight, 
    Flush, FullHouse, FourOfAKind, StraightFlush }  

public struct Card 
{ 
    public Suit Suit { get; private set; } 
    public Rank Rank { get; private set; } 
    public Card(Rank rank, Suit suit) 
    { 
     Suit = suit; 
     Rank = rank; 
    }  
} 

public class Hand 
{ 
    public IReadOnlyList<Card> Cards { get; private set }; 
    public Hand(IEnumerable<Card> cards) 
    { 
     this.Cards = cards.OrderByDescending(c => c.Rank).ToList(); 
    } 
} 

該評估可以通過一種方法來完成,該方法需要手並返回手的種類。注意這隻有分類爲的手,它實際上並沒有弄清楚完整的等級,這樣一個更高的直線擊球等等。我已經離開了實際執行中,但這裏是一個骨架:

public static class HandEvaluator 
{ 
    public static HandType GetHandType(Hand hand) 
    {   
     bool isFlush = hand.Cards.Distinct(c => c.Suit).Count() == 1; 
     bool isStraight = // five consecutive ranks. Mind the wheel straight Ace->5! 
     if (isStraight && isFlush) 
     return HandType.StraightFlush;   

     // group cards by rank, then find the group count & sizes 
     var groups = hand.Cards.GroupBy(c => c.Rank); 

     if (/* max group size = 4 */) 
      return HandType.FourOfAKind; 
     if (/* two groups and max group size = 3 */) 
      return HandType.FullHouse; 
     if (isFlush) 
     return HandType.Flush; 
     if (isStraight) 
     return HandType.Straight; 
     if (/* three groups and max group size 3 */) 
      return HandType.ThreeOfAKind; 

     // ... And so on for two pair, pair. 

     return HandType.Nothing; 
    } 
} 

對於不同的手的概率:那些你應該能夠在紙上比程序更容易做,但一旦你有一個分類程序,您可以輕鬆獲得統計信息,方法是生成所有可能的手,對它們進行分類,並根據評估的手形對結果進行分組/計數。

4

識別手很容易,一旦你考慮到,有基於價值的層次結構。因此,雖然同花順也是同花順,滿屋也是兩對,但您始終會選擇價值更高的分類。

這意味着如果您按照價值從高到低的順序檢查您的五張牌,則第一次匹配將是正確的。 (類似於strategy pattern這裏可能非常有用。)

至於概率,我只是look them up。 (請注意,全套牌是52張牌不是54.)

+0

如果我可以選擇數據結構什麼是最好的選擇?以便能夠計算概率和手名。 – 2015-03-31 14:13:10

+0

@HaddarMacdasi無論你感到舒服。我可能會使用一個包含兩個枚舉類型的類,一個用於西裝,一個用於等級。再一次,計算概率沒有意義,它們已經是衆所周知的並且有一個簡單的閉合公式。 – biziclop 2015-03-31 14:15:31

1

關於每手牌的概率,這是一個簡單的計數問題,考慮到有52個選擇5 = 2,598,960個不同的牌,所以你只需要算多少雙手爲每種類型的手的資格和2598960.

把它例如有4次不同的王室刷新 - > 4/2598960 = 0.000153907%的機率

有4 * 10 = 40個不同的直線沖刷 - > 40/2,598,960 = 0.00153907%的機率

有13 * 48 = 624個不同的方形 - > 624/2598960 = 0.024009603%的機率

等等..

如果你不喜歡計數問題,你可以使用你的程序來枚舉這些2598960手,指望有多少紅,四邊形等。

關於檢測手的代碼 - 我會按照排序順序存儲手(根據卡的等級/高度,忽略該套裝即['H3','D3','D4','S4 」, 'H6'])。這將幫助您非常有效地檢測雙人,兩對,三人,四人,滿屋和直道。 檢測沖洗非常簡單 - 只需檢查所有五張卡片是否來自同一套服裝。你完成了!