从五张牌手牌中获得对子的可能性

时间:2019-05-08 20:04:31

标签: java probability poker

我需要找到一个概率百分比,才能通过仿真从5张牌中得到一对牌。

到目前为止,我已经创建了“卡片”(功能:卡片价值,花色,按值与另一张卡片进行比较)和“手”(功能:addCard和isOnePair),它们仅在手的实例具有一对卡)。

Card.java:

public enum CardValue { s2, s3, s4, s5, s6, s7, s8, s9, s10, J, Q, K, A }

public enum CardSuit { C, D, H, S }

private CardValue value;
private CardSuit suit;

public Card(CardValue value, CardSuit suit) {
    this.value = value;
    this.suit = suit;
}

@Override
public boolean equals(Object obj) {
    if(obj == this) {
        return true;
    }
    if(!(obj instanceof Card)) {
        return false;
    }
    Card card = (Card)obj;
    return card.value == this.value;
}

Hand.java

private Set<Card> hand;

public Hand() {
    this.hand = new HashSet<>();
}

public void addCard(Card card) {
    this.hand.add(card);
}

@Override
public String toString() {
    return this.hand.toString();
}

private boolean isOnePair() {
    int counter = 0;
    for(Card card : hand){
        for(Card card2 : hand) {
            if(card.equals(card2)) {
                counter++;
            }
        }
        if(counter == 2) {
            return true;
        }
        counter = 0;
    }

    return false;
}

2 个答案:

答案 0 :(得分:1)

您所关心的是,共有52张牌,它们平均分布在13个等级上。您无需模拟甲板。您只想选择0到51之间的5个随机数字,没有重复项,然后考虑一个数字在52个可选择的数字中按顺序重复4次,然后计算一个数字的排名与另一个数字的排名相匹配的次数。如果这种情况仅发生一次,那么您将拥有一对。这只需要5次迭代的一个循环。

此代码通过运行200K次迭代来估算5张牌中恰好一对的概率。它几乎是在Macbook Pro上即时完成的:

import java.util.Random;

public class OnePair {

    // Initialize a random number generator
    private static Random random = new Random(System.currentTimeMillis());

    private static boolean doOne() {

        // Keep track of cards we've picked so we don't pick the same card twice
        boolean[] cards = new boolean[52];

        // Keep track of ranks we've seeen before
        boolean[] ranks = new boolean[13];

        // Keep track of how many times ranks have matched
        int count = 0;

        // For each of 5 cards...
        for (int i = 0 ; i < 5 ; i++) {

            // Pick a random card we haven't picked before
            int card;
            while (true) {
                card = random.nextInt(52);
                if (!cards[card]) {
                    cards[card] = true;
                    break;
                }
            }

            // If we've seen this rank before, increase our total matches
            if (ranks[card % 13])
                count += 1;

            // Remember that we've seen this rank
            ranks[card % 13] = true;
        }

        // Return if we saw exactly one pair, in which case count will be 1
        return count == 1;
    }

    public static void main(String[] args) {

        long count = 200000;
        long paired = 0;

        for (int i = 0 ; i < count ; i++)
            if (doOne())
                paired += 1;

        System.out.println((float)paired / count);

    }
}

我得到的结果采样:

0.42265
0.42181
0.42112
0.422675
0.423895

我发现了针对同一问题的统计计算,得出的概率为0.422569。

答案 1 :(得分:0)

  • 首先,创建一个List牌组,其中包含所有可能的Card
  • 然后,对于模拟的每次迭代,请洗牌并绘制前5个Card
  • 检查是否有一对,如果有,则增加一个计数器。
  • 将计数器除以迭代总数。

示例:

Random rand = new Random();

final int NUMBER_OF_VALUES = Card.CardValue.values().length;
final int NUMBER_OF_SUITS = Card.CardSuit.values().length;
final int NUMBER_OF_CARDS_IN_HAND = 5;
Card.CardValue value;
Card.CardSuit suit;
Hand hand;
List<Card> deck = new ArrayList<>();

// Deck creation
for(int i = 0; i < NUMBER_OF_VALUES; i++) {
    for(int j = 0; j <  NUMBER_OF_SUITS; j++)
        deck.add(new Card(Card.CardValue.values()[i], Card.CardSuit.values()[j]));
}

int counter = 0;
final int TOTAL = 100000;

// Simulation
for(int i = 0; i < TOTAL; i++) {
    Collections.shuffle(deck);
    hand = new Hand();
    for(int j = 0; j < NUMBER_OF_CARDS_IN_HAND; j++)
        hand.addCard(deck.get(j));
    if(hand.isOnePair()) counter++;
}

System.out.println("Probability: " + 100 * counter / (double)TOTAL + "%");