I'm writing a java project for the university where am I exploring blackjack from the math point of view. Right now I've stumbled upon the probability of dealer busting (depending on the up card) for 8 decks in a shoe.
So I got those results through the millions of simulations (each time deck is different, full and reshuffled). As you can see, the odds that I've acquired with my application and the correct ones (from the wizardofodds.com website) are quite similar from TWO to NINE. But there's something wrong about TEN and ACE. The difference is just too much to be ignored. So can somebody please explain to me what am I missing?
Below I've attached necessary source codes for this issue (I've excluded a lot of other methods from classes that are not related).
Would appreciate any help so much. Thank you in advance for reading this.
Main class
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;
}
Part of the Deck class
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;
}
}
Part of the Hand class
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;
}
}
Part of the Card class
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);
}
}
Part of the Value class
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;
}
}
}