R- Monte Carlo 扑克牌计数器

R- Monte Carlo Poker Hand Counter

我正在尝试整理一个练习项目。我正在尝试使用 R.

在 Monte Carlo 模拟中计算扑克手数

我对如何处理我的顺子、同花顺和皇家同花顺感到困惑。不包括顺子和同花顺代码,但我确实尝试 "pseudo-code" 皇家同花顺。我希望如果我能在皇家同花顺上得到一些指导,我就能弄清楚如何处理同花顺和顺子。在我添加皇家同花顺代码之前的代码 运行。代码如下:

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
}

只关注皇家同花顺部分,我认为您检查牌是否为 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>