在 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<-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 循环的主要内容,如果未能解决你的问题,请参考以下文章