在 R 中创建一副牌而不使用 While 和 Double For 循环

Posted

技术标签:

【中文标题】在 R 中创建一副牌而不使用 While 和 Double For 循环【英文标题】:Creating A Deck Of Cards In R Without Using While And Double For Loop 【发布时间】:2014-09-01 07:53:50 【问题描述】:

我正在 R 中创建一个二十一点模拟器。下面的代码成功地创建了我想要的牌组。 (对于那些玩的,我稍后会处理 Ace 的值)。

我的问题是,有没有更好的方法来创建不涉及 while 循环和双 for 循环的牌组?我对双 for 循环有更多的问题。 while 循环可能是不可避免的,因为创建的牌组数量是可变的。

我还初始化了一个空数据框,我知道这不是最佳做法,但是,在这种情况下,数据集非常小,不会影响性能。

最后,R 中是否有 i++ 的等价物?我也一直在用java编程,已经习惯了。

谢谢。

createDeck <- function(totalNumOfDecks = 2)

  suits <- c("Diamonds", "Clubs", "Hearts", "Spades")
  cards <- c("Ace", "Deuce", "Three", "Four","Five", 
             "Six", "Seven", "Eight", "Nine", "Ten", 
             "Jack", "Queen", "King")
  values <- c(0,2,3,4,5,
              6,7,8,9,10,
              10,10,10)

  deck <- data.frame(Suit=character(0), Card=character(0), Value=numeric(0))

  numOfDecks = 1

  while (numOfDecks <= totalNumOfDecks)
    for (i in suits)
      for (j in cards)
        deck <- rbind.data.frame(deck, cbind.data.frame(j, i, values[match(j, cards)]))
      
    
    numOfDecks = numOfDecks + 1
  

  print(deck)

【问题讨论】:

?expand.grid。但坦率地说,只使用 52 个级别的单一因素可能会更容易。 如果 josilber 用字符串创建 N 副牌的方法适合你,那么我建议你,因为你可能想在某个时候洗牌,你可以创建一个“洗牌器” " 类似 cardorder&lt;-sample(1:(N*52),N*52) 的东西,并使用结果向量重新排序 deck 行。 ...只是为了扩展我的评论:我的意思是我可能只使用整数向量 0:51 作为卡片,然后使用模算术来确定花色和等级,以及索引另一个向量来确定值。这可能比推送 data.frame 快得多。 @CarlWitthoft - 我不打算洗牌,而是随机取出一张牌。 @joran 我对你的想法很感兴趣,但是在这种情况下,模算术有什么帮助呢?我无法建立连接。 【参考方案1】:

expand.grid 函数应该会有所帮助:

# Define suits, cards, values
suits <- c("Diamonds", "Clubs", "Hearts", "Spades")
cards <- c("Ace", "Deuce", "Three", "Four","Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King")
values <- c(0, 2:9, rep(10, 4))
totalNumOfDecks <- 2

# Build deck, replicated proper number of times
deck <- expand.grid(cards=cards, suits=suits)
deck$value <- values
deck <- deck[rep(seq(nrow(deck)), totalNumOfDecks),]

expand.grid 的调用计算所有纸牌和花色配对。 value 变量是通过为每个花色回收 value 向量而创建的。最后,rep(seq(nrow(deck))) 以适当的次数重复第 1-52 行以获得您的套牌的多个副本。

【讨论】:

【参考方案2】:

如果我必须模拟一个牌组(或多个牌组),我可能更喜欢将单个整数向量与一些参考向量结合使用,然后简单地使用模运算和索引来确定花色、排名和价值。

#Setup
suits <- c('Clubs','Diamonds','Hearts','Spades')
card <- c('Ace','Two','Three','Four','Five',
                    'Six','Seven','Eight','Nine','Ten',
                    'Jack','Queen','King')
value <- c(0,2:10,rep(10,3))
deck <- 0:51

#Full deck
suits[(deck %/% 13) + 1]
card[(deck %% 13) + 1]
value[(deck %% 13) + 1]

#Some random cards
hand <- sample(deck,5)
suits[(hand %/% 13) + 1]
card[(hand %% 13) + 1]
value[(hand %% 13) + 1]

【讨论】:

【参考方案3】:

这与我最近的paste.grid 问题有关;请参阅那里了解其他一些选项,包括简单的 levels(interaction(...)) 方法。

我自己做了一个套牌,它使用 unicode 字符作为西装,所以看起来很时髦;这就是我所做的:

cards = c(2:10, "J", "Q", "K", "A")
suits = c("♠", "♥", "♦", "♣")
deck <- paste0(rep(cards, length(suits)),  #card values
               rep(suits, each = length(cards))) #suits
deck
#  [1] "2♠"  "3♠"  "4♠"  "5♠"  "6♠"  "7♠"  "8♠"  "9♠"  "10♠" "J♠"  "Q♠"  "K♠" 
# [13] "A♠"  "2♥"  "3♥"  "4♥"  "5♥"  "6♥"  "7♥"  "8♥"  "9♥"  "10♥" "J♥"  "Q♥" 
# [25] "K♥"  "A♥"  "2♦"  "3♦"  "4♦"  "5♦"  "6♦"  "7♦"  "8♦"  "9♦"  "10♦" "J♦" 
# [37] "Q♦"  "K♦"  "A♦"  "2♣"  "3♣"  "4♣"  "5♣"  "6♣"  "7♣"  "8♣"  "9♣"  "10♣"
# [49] "J♣"  "Q♣"  "K♣"  "A♣"

【讨论】:

【参考方案4】:
buildDeck <- function(noOfDecks=1)
    suits <- c("Clubs", "Spades", "Diamonds", "Hearts")
    cards <-c("Ace", 2:10, "Jack", "Queen", "King")
    Deck <- paste(cards, rep(suits, each=13), sep="-")
    d<-rep(Deck,noOfDecks) #Build decks
    shuffledDeck <-sample(d,length(d)) #Shuffle decks
    shuffledDeck

【讨论】:

以上是关于在 R 中创建一副牌而不使用 While 和 Double For 循环的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 phpmyadmin 在存储过程中创建一段时间,错误 #1064

自动化Google幻灯片制作

如何在 C++ 中创建重复直到循环?

在 R 中创建我自己的蜘蛛图而不使用任何库

do-while循环算5的阶乘

如何在 Azure 存储容器中创建目录而不创建额外文件?