Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating A Deck Of Cards In R Without Using While And Double For Loop

I am creating a blackjack simulator in R. The code below succeeds in creating the deck(s) of cards that I want. (For those that play, I will deal with the value of an Ace later).

My question is, is there a better way to create the deck that doesn't involve a while loop plus a double for loop? I have more of an issue with the double for loop. The while loop is likely unavoidable since the number of decks created is variable.

I also initialize an empty data frame which I know isn't the best practice, however, the data set is so small in this case that it won't effect performance.

And lastly, is there an equivalent of i++ in R? I have been programming in java as well and have gotten used to it.

Thanks.

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)
}
like image 246
mks212 Avatar asked Jul 10 '14 19:07

mks212


2 Answers

The expand.grid function should be helpful:

# 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),]

The call to expand.grid computes all pairing of cards and suits. The value variable is created by recycling the value vector for each suit. Finally, rep(seq(nrow(deck))) repeats rows 1-52 the proper number of times to get multiple copies of your deck.

like image 171
josliber Avatar answered Sep 18 '22 10:09

josliber


This is related to my recent paste.grid question; see there for some other options, including the straightforward levels(interaction(...)) approach.

Just made a deck myself and it uses the unicode characters for the suits so it looks snazzy; here's what I did:

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♣"
like image 22
MichaelChirico Avatar answered Sep 18 '22 10:09

MichaelChirico