擁有一張代表5張拾取完整牌組中的5張牌的數組(52張牌)。因此,隨機手看起來像這樣['H3','H6','D3','D4','S4'](這裏是h 2對4和3)。
我正在尋找一種方式來了解隨機5張牌這種性質:如何檢測抽牌遊戲中的「手牌」
- 什麼手的名字就是它了。即:「四種一種」,「三種一種」等 上。
- 這隻手的概率是多少,請記住它是一個完美的隨機數 。
- 我可以選擇的數據結構
- 我使用C#
擁有一張代表5張拾取完整牌組中的5張牌的數組(52張牌)。因此,隨機手看起來像這樣['H3','H6','D3','D4','S4'](這裏是h 2對4和3)。
我正在尋找一種方式來了解隨機5張牌這種性質:如何檢測抽牌遊戲中的「手牌」
首先設置一些數據結構來表示套裝,行列,牌和手牌。有很多方法可以做到這一點以獲得良好的性能,例如使用位向量,但假設我們想讓它變得可讀:爲套裝和行列製作枚舉,爲卡片製作一個結構,爲一隻手製作一個類。順便說一句,這種類型的例子是你希望你是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;
}
}
對於不同的手的概率:那些你應該能夠在紙上比程序更容易做,但一旦你有一個分類程序,您可以輕鬆獲得統計信息,方法是生成所有可能的手,對它們進行分類,並根據評估的手形對結果進行分組/計數。
識別手很容易,一旦你考慮到,有基於價值的層次結構。因此,雖然同花順也是同花順,滿屋也是兩對,但您始終會選擇價值更高的分類。
這意味着如果您按照價值從高到低的順序檢查您的五張牌,則第一次匹配將是正確的。 (類似於strategy pattern這裏可能非常有用。)
至於概率,我只是look them up。 (請注意,全套牌是52張牌不是54.)
如果我可以選擇數據結構什麼是最好的選擇?以便能夠計算概率和手名。 – 2015-03-31 14:13:10
@HaddarMacdasi無論你感到舒服。我可能會使用一個包含兩個枚舉類型的類,一個用於西裝,一個用於等級。再一次,計算概率沒有意義,它們已經是衆所周知的並且有一個簡單的閉合公式。 – biziclop 2015-03-31 14:15:31
關於每手牌的概率,這是一個簡單的計數問題,考慮到有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'])。這將幫助您非常有效地檢測雙人,兩對,三人,四人,滿屋和直道。 檢測沖洗非常簡單 - 只需檢查所有五張卡片是否來自同一套服裝。你完成了!
您需要知道撲克牌的手牌以及您的數據結構如何表示牌?然後參加500或600級的高校概率數學課(或在維基百科上查看)。 – crashmstr 2015-03-31 13:03:48
看起來像你被處理了兩對 - 四和三。 – alex 2015-03-31 13:04:15
手是一個什麼樣的數組?字符串?還有別的嗎?你可以自由選擇數據結構嗎?這是你正在問的東西(它應該是什麼)還是已經給出的數據結構?有沒有使用特定的編程語言? – 2015-03-31 13:52:36