Возможность получить пару из 5-карточного покера - PullRequest
0 голосов
/ 08 мая 2019

Мне нужно найти процент вероятности для получения одной пары карт из 5-карточной руки путем симуляции.

До сих пор я создал классы "Карта" (функции: значение карты, масть, сравнение с другой картой по значению) и "Рука" (функции: addCard и isOnePair, которая возвращает значение true, только если экземпляр руки имеет одну пару карточек в нем).

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 ]

1 голос
/ 09 мая 2019

Все, что вас волнует, это то, что есть 52 карты, и они равномерно распределены по 13 разрядам. Вам не нужно моделировать колоду. Вы просто хотите выбрать 5 случайных чисел от 0 до 51 без дубликатов, а затем подсчитать, сколько раз ранг одного номера совпадает с рангом другого числа, учитывая, что ранги повторяются в порядке 4 раза по 52 выбираемым числам. Если это происходит только один раз, у вас есть рука с одной парой. Это займет всего один цикл из 5 итераций.

Этот код оценивает вероятность одной пары в 5-карточной раздаче, выполняя итерации по 200К. Это происходит на моем 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.

0 голосов
/ 09 мая 2019
  • Сначала создайте колоду 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 + "%");
...