如何编写有放回抽样的黑杰克模拟代码:基于5000次双发牌重复试验估算黑杰克概率
Got it, let's work through this step by step to get your simulation up and running correctly. The key pieces you're missing are defining a proper standard deck for sampling, implementing the with-replacement draw logic, and wrapping everything in a repeatable trial loop.
First, let's map a real 52-card deck to point values:
- 4 Aces (each worth 1, which we'll adjust to 11 later if needed)
- 4 cards each for 2 through 9
- 16 cards worth 10 (10, Jack, Queen, King — 4 suits each)
In R, we can define this deck with:
# Define a standard 52-card deck using point values deck <- c(rep(1, 4), rep(2:9, each = 4), rep(10, 16))
Your handValue function has solid core logic, so we'll tweak it for readability while keeping the key checks:
handValue <- function(cards) { value <- sum(cards) # Adjust Ace from 1 to 11 if it doesn't make the hand bust if (any(cards == 1) && value <= 11) { value <- value + 10 } # Return 0 for bust, 21.5 for Blackjack, else the hand value if (value > 21) { return(0) } else if (value == 21 && length(cards) == 2) { return(21.5) # Unique marker for Blackjack } else { return(value) } }
The critical part here is using sample(..., replace = TRUE) to simulate drawing cards with replacement. We'll run 5000 trials with a vectorized approach for efficiency:
set.seed(5000) # Ensure reproducibility of your results num_trials <- 5000 # Run all trials: draw 2 cards with replacement, get hand value for each trial_results <- sapply(1:num_trials, function(x) { hand <- sample(deck, 2, replace = TRUE) # This is the with-replacement logic! handValue(hand) }) # Count how many trials resulted in Blackjack (marked by 21.5) blackjack_count <- sum(trial_results == 21.5) # Calculate the relative frequency (estimated probability) estimated_probability <- blackjack_count / num_trials
Add a simple print statement to see your estimate:
cat("Out of", num_trials, "with-replacement trials:\n") cat("- Number of Blackjacks:", blackjack_count, "\n") cat("- Estimated probability:", round(estimated_probability, 4), "\n")
Since Blackjack only applies to 2-card hands, you could skip the full hand value function and directly check for the valid combinations (Ace + 10-point card, in either order):
blackjack_count_simple <- sum(sapply(1:num_trials, function(x) { hand <- sample(deck, 2, replace = TRUE) (hand[1] == 1 && hand[2] == 10) || (hand[1] == 10 && hand[2] == 1) }))
This will give you the same count, and might be easier to follow for this specific simulation.
Putting it all together:
set.seed(5000) # Define standard deck point values deck <- c(rep(1, 4), rep(2:9, each = 4), rep(10, 16)) # Hand value calculator handValue <- function(cards) { value <- sum(cards) if (any(cards == 1) && value <= 11) { value <- value + 10 } if (value > 21) { return(0) } else if (value == 21 && length(cards) == 2) { return(21.5) } else { return(value) } } # Run 5000 with-replacement trials num_trials <- 5000 trial_results <- sapply(1:num_trials, function(x) { hand <- sample(deck, 2, replace = TRUE) handValue(hand) }) # Calculate and print results blackjack_count <- sum(trial_results == 21.5) estimated_probability <- blackjack_count / num_trials cat("Out of", num_trials, "with-replacement trials:\n") cat("- Number of Blackjacks:", blackjack_count, "\n") cat("- Estimated probability:", round(estimated_probability, 4), "\n")
内容的提问来源于stack exchange,提问作者devonwilliams064




