【问题标题】:Creating A Deck Of Cards In R Without Using While And Double For Loop在 R 中创建一副牌而不使用 While 和 Double For 循环
【发布时间】: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 我对你的想法很感兴趣,但是在这种情况下,模算术有什么帮助呢?我无法建立连接。

标签: r for-loop while-loop


【解决方案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
        }
        

        【讨论】:

          猜你喜欢
          • 2015-11-23
          • 2021-05-29
          • 1970-01-01
          • 2020-08-14
          • 2016-07-12
          • 2011-10-06
          • 2015-12-24
          • 2018-07-30
          • 2014-11-01
          相关资源
          最近更新 更多