Reputation: 4791
I want to simulate different poker hands. Through painful trial and error, I got the ranks, suits, the deck and a function to draw any given number of cards as:
suits <- c("spd","hrt","dimd","clbs")
ranks <- c(1:10,"J","Q","K")
deck <- as.matrix(expand.grid('rank' = ranks, 'suit' = suits))
draw <- function (n) deck[sample(nrow(deck), n), ]
draw(5) # Drawing 5 cards from the deck...
Output:
rank suit
[1,] "4" "dimd"
[2,] "6" "dimd"
[3,] "8" "spd"
[4,] "K" "hrt"
[5,] "8" "clbs"
Now I want to find out through simulation the probability of getting different hands. I did come up with some possible loops with a counter for the number of successes
but I am stuck.
Here is an example... Let me try to figure out how many full houses I get in 1000 simulations. Since a full house is defined as "three matching cards of one rank and two matching cards of another rank", I figured that the key part of the function would be to have a boolean within an if
statement that takes advantage of the R function unique()==2
, meaning 2 unique ranks - with 5 cards dealt, 2 unique ranks could be a full house (another possibility is four-of-a-kind with any other rank).
iterations <- 1000
counter <- 0
for (i in iterations){
s <- draw(5)
if(length(unique(s[,1])) == 2) counter <- counter + 1
}
counter
Output: [1] 0
I have tried multiple other things, including counter[i] <- 1
for successful cases, and with the idea of running a sum(counter)
at the end, but all without getting the loop to work.
Upvotes: 3
Views: 218
Reputation: 4570
suits <- c("spd","hrt","dimd","clbs")
ranks <- c(1:10,"J","Q","K")
deck <- as.data.frame(expand.grid('rank' = ranks, 'suit' = suits))
draw <- function (n) deck[sample(nrow(deck), n), ]
iterations <- 1000
counter <- 0
for (i in 1:iterations) {
hand <- draw(5)
rank_table <- table(hand[, 1])
if (length(names(rank_table)) == 2 & min(rank_table) > 1) counter <- counter + 1
# could have four of a rank, one of another;
# need to ensure two of a rank, three of another
}
counter
[1] 1
This result is not far from what is expected http://www.math.hawaii.edu/~ramsey/Probability/PokerHands.html
Upvotes: 0
Reputation: 44658
In your code you have:
for(i in 1000) {
print(i)
} # 1000
It would only print once because i
would iterate once as 1000
.
Here's an alternative approach using rle
.
iterations <- 10000
draws <- list()
for (i in 1:iterations){
s <- draw(5)
draws[[i]] <- all(rle(sort(s[,1]))$lengths %in% c(2,3))
if(draws[[i]]) {
print(s)
}
}
summary(unlist(draws))
Upvotes: 1
Reputation: 10483
Using a data frame as follows, it seems to produce the result you are looking for:
suits <- c("spd","hrt","dimd","clbs")
ranks <- c(1:10,"J","Q","K")
deck <- as.data.frame(expand.grid('rank' = ranks, 'suit' = suits))
draw <- function (n) deck[sample(nrow(deck), n), ]
counter <- 0;
for (i in 1:1000) {
df <- draw(5);
counter <- counter + (length(unique(df$rank)) == 2)
}
counter
[1] 156
Upvotes: 1