我正在努力将一个项目放在一起进行练习。我正在尝试使用R来计算蒙特卡罗模拟中的扑克牌。
我遇到了如何处理我的直道,直冲和皇室冲洗的问题。直道和直冲的代码不包括在内,但我确实试图“伪代码”皇家同花顺。我希望如果我可以在皇家同花顺上获得一些方向,那我就可以弄清楚如何处理直冲和直道。在我添加royalflush的代码之前,代码按预期运行。代码如下:
poker.sim <- function (Msim=10000,n=5) {
# This is a function to simulate Poker draws from a standard card deck
# We will be using a Grand Loop approach
#
# Create the card deck
denom = rep(c("A",2:10,"J","Q","K"),4)
suit = rep(c("S","H","D","C"),each=13)
carddeck = data.frame(denom,suit)
# Initialize the twosuit, onepair, twopair, threeofakind, flush, fullhouse, and fourofakind as counters and for storage later...
count.twosuit = 0
count.onepair = 0
count.twopair = 0
count.threeofakind = 0
count.flush = 0
count.fullhouse = 0
count.fourofakind = 0
count.royalflush = 0
# Begin the Grand Loop
for(i in 1:Msim)
{
# determine card numbers for this hand
select = sample(nrow(carddeck),n)
# select rows from the card deck for this hand
hand = carddeck[select,]
# Check for TWOSUIT and increment the counter if twosuit occurs
# This statement is counting every instance in which only two suits occur in a five-card hand.
if(length(unique(hand[,2]))==2) count.twosuit = count.twosuit+1
# Check for ONEPAIR and increment the counter if onepair occurs
# What this loop is doing is setting the length of the hand to 4 possible cards.
# The first, second, and third cards can be any cards occurring only once.
# The last two cards must be the same.
tab = sort(table(as.vector(hand[,1])))
if(length(tab) ==4)
{
if(all(tab == c(1,1,1,2))) count.onepair = count.onepair+1
}
# Check for TWOPAIR and increment the counter if twopair occurs
# What this loop is doing is setting the length of the hand to be 3 possible cards.
# The first card will occur only once.
# The last two cards will occur twice each.
if(length(tab) ==3)
{
if(all(tab == c(1,2,2))) count.twopair = count.twopair+1
}
# Check for THREEOFAKIND and increment the counter if threeofakind occurs.
# What this function is doing is setting the length of the hand to 3 possible cards.
# The first and second cards occur once each and can be any card.
# The last three cards must be the same.
if(length(tab) ==3)
{
if(all(tab == c(1,1,3))) count.threeofakind = count.threeofakind+1
}
# Check for FLUSH and increment the counter if a flush occurs.
# This statement is counting every instance in which only one suit occurs in a five-card hand.
if (length(unique(hand[,2]))==1) count.flush = count.flush+1
#Check for a FULLHOUSE and increment the counter if fullhouse occurs
# What this loop is doing is setting the length of the hand to 2 possible cards.
# The first occurring twice, and the second occurring 3 times. Or vice versa.
if(length(tab) ==2)
{
if(all(tab == c(2,3))) count.fullhouse = count.fullhouse+1
}
# Check for FOUROFAKIND and increment the counter if fourofakind occurs.
# What this loop is doing is setting the length of the hand to 2 possible cards.
# The first occurring only once, and the second occurring 4 times.
if(length(tab) ==2)
{
if(all(tab == c(1,4))) count.fourofakind = count.fourofakind+1
}
# Check for ROYALFLUSH and increment the counter if royalflush occurs.
# This will be restricted to only one suit AND when a run of 10,J,Q,K,A occurs.
if(length(unique(hand[,2]))==1)
{
if(tab == c(10,J,Q,K,A) count.royalflush = count.royalflush+1
}
} # Close the Grand Loop
# Then, we will count the twosuits, onepairs, twopairs, threeofakinds, flushes, fullhouses, and fourofakinds
# and divide them by the number of iterations of the simulation to get their respective probabilities.
p.twosuit = count.twosuit/Msim
p.onepair = count.onepair/Msim
p.twopair = count.twopair/Msim
p.threeofakind = count.threeofakind/Msim
p.flush = count.flush/Msim
p.fullhouse = count.fullhouse/Msim
p.fourofakind = count.fourofakind/Msim
p.royalflush = count.royalflush/Msim
# To output the results
out = list(Msim,p.twosuit,p.onepair,p.twopair,p.threeofakind,p.flush,p.fullhouse,p.fourofakind,p.royalflush)
names(out) = c("Msim","p.twosuit","p.onepair","p.twopair","p.threeofakind","p.flush","p.fullhouse","p.fourofakind","p.royalflush")
out
}
答案 0 :(得分:0)
只关注皇家同花顺部分,我认为你检查牌是10,J,Q,K,A的逻辑是不行的。我会改用setqual
来检查hand[, 1]
的元素是否与向量c("10","J","Q","K","A")
相同。
因此我们有:
if(length(unique(hand[ , 2])) == 1)
{
if(setequal(hand[ , 1], c("10","J","Q","K","A")))
count.royalflush = count.royalflush + 1
}
为了检查我们是否有直线,我们需要更复杂的条件。我们将创建一个检查直接
的函数is_straight <- function(hand) {
# first we want to encode "J", "Q", "K" to 11, 12, 13, so we can use diff later
# we take the denominators from the hand as a character vector
hand_denom <- as.character(hand[ , 1])
# and then map acording values
hand_denom[hand_denom == "J"] <- 11
hand_denom[hand_denom == "Q"] <- 12
hand_denom[hand_denom == "K"] <- 13
# we need to check whether we treat ace as high or low and encode it accordingly
# if any of the cards is a two, then ace will be treated as 1 if it's a straight
# otherwise, we'll treat it as 14
hand_denom[hand_denom == "A"] <- ifelse(any(hand_denom == "2"), 1, 14)
# now we just check if the numeric values are successive (i.e. diff is always 1)
all(diff(sort(as.numeric(hand_denom))) == 1)
}
您显然在代码中将其用作if (is_straight(hand)) <straight handling>
。