【发布时间】:2019-05-17 08:53:03
【问题描述】:
我正在为大学编写一个 java 项目,从数学的角度来探索二十一点。现在,我偶然发现发牌员在一只鞋中因 8 副牌而爆牌(取决于向上的牌)的可能性。
所以我通过数百万次模拟得到了这些结果(每次套牌都是不同的、满的和重新洗牌的)。如您所见,我的应用程序获得的几率和正确的几率(来自wizardofodds.com 网站)从 TWO 到 非常相似九个。但是 TEN 和 ACE 有问题。差别太大了,不容忽视。那么有人可以向我解释一下我错过了什么吗?
下面我附上了这个问题的必要源代码(我已经从不相关的类中排除了很多其他方法)。
非常感谢任何帮助。提前感谢您阅读本文。
主类
public static void main(String[] args) {
for (Value value : Value.values())
Card card = new Card(value);
int range = 1_000_000;
long res = IntStream.range(0, range).sequential().filter(e -> isBusted(card)).count();
System.out.println(value + "\t" + res * 1.0 / range);
}
}
public static boolean isBusted(Card card) {
Deck deck = new Deck();
deck.init(8);
Hand hand = new Hand(card);
while (hand.points() < 17) {
hand.add(deck.draw());
}
return hand.points() > 21;
}
Deck 类的一部分
public class Deck {
private ArrayList<Card> cards;
public Deck() {
cards = new ArrayList<>();
init(8);
}
public void init(int size) {
cards.clear();
for (int i = 0; i < size; i++) {
for (Suit suit : Suit.values()) {
for (Value value : Value.values()) {
cards.add(new Card(suit, value));
}
}
}
Collections.shuffle(cards);
}
public Card draw() {
Card card = cards.get(0);
cards.remove(card);
return card;
}
}
Hand 类的一部分
public class Hand {
private ArrayList<Card> cards;
public Hand(Card... cards) {
this.cards = new ArrayList<>(Arrays.asList(cards));
}
public void add(Card card) {
this.cards.add(card);
}
public int countAces() {
return (int) cards.stream().filter(Card::isAce).count();
}
public int points() {
int points = cards.stream().mapToInt(e -> e.value().points()).sum();
for (int i = 0; i < countAces(); i++) {
points += (points >= 11) ? 1 : 11;
}
return points;
}
}
卡片类的一部分
public class Card {
private Suit suit;
private Value value;
public Card(Value value) {
this.suit = Suit.CLUBS;
this.value = value;
}
public Value value() {
return value;
}
public boolean isAce() {
return value.equals(Value.ACE);
}
}
Value 类的一部分
public enum Value {
TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE;
public int points() {
if (ordinal() <= 7) {
return ordinal() + 2;
}
if (ordinal() >= 8 && ordinal() <= 11) {
return 10;
} else {
return 0;
}
}
}
【问题讨论】:
-
也许是因为你的第一张牌没有从牌堆中抽出?有 8 包,有 32 个 10 和 A;如果第一张牌是 10 或 A,则应该还剩 31 个(少于未绘制的值),但 isBusted() 以所有 32 个开始。
-
感谢您的回答。我也在考虑这个问题。但是当我试图从牌堆中抽出这张牌并据此计算时,机会变得更糟了。所以我决定在我想出 Aces 和 Tens 的解决方案之前不包括这个。
标签: java statistics blackjack