2014-07-10 22 views
4

我在R中創建了一個二十一點模擬器。下面的代碼成功地創建了我想要的副牌。 (對於那些比賽,我會在稍後處理一個Ace的價值)。在沒有使用while和double for循環的情況下在R中創建一副牌

我的問題是,是否有更好的方式來創建不涉及while循環加雙循環的套牌? double 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) 
} 
+1

請參閱'?expand.grid'。但坦率地說,只用52個等級的單一因素可能會更容易。 – joran

+2

如果josilber用字符串創建N套牌的方法適用於你,那麼讓我建議,因爲大概你想在某個時候洗牌,你創建了一個「洗牌機」,比如'cardorder <樣本(1:(N * 52),N * 52)'並使用結果向量重新排序'deck'行。 –

+1

...只是爲了擴展我的評論:我的意思是我可能只是使用一個整數向量0:51作爲卡片,然後使用模塊化算術來確定西裝和等級,並索引另一個向量來確定價值。這可能比推動data.frame快得多,速度更快。 – joran

回答

6

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行的適當次數得到你的牌組的多個副本。

3

如果我必須模擬一個套牌(或多個套牌),我可能更願意將一個整數向量與某些參考向量結合使用,然後使用模塊化算術和索引來確定套牌,等級和價值。

#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] 
1
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 
} 
1

這關係到我最近paste.grid的問題;在那裏看到一些其他的選擇,包括直接的levels(interaction(...))方法。

剛做了一個甲板我自己,它使用unicode字符的西裝,所以它看起來時髦;這是我做的:

deck <- paste0(rep(c(2:10, "J", "Q", "K", "A"), 4), #card values 
       rep(c("♠", "♥", "♦", "♣"), each = 13)) #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♣" 
相關問題