mks212
mks212

Reputation: 921

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)
}

Upvotes: 7

Views: 10318

Answers (4)

MichaelChirico
MichaelChirico

Reputation: 34703

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♣"

Upvotes: 5

Nexislink
Nexislink

Reputation: 21

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
}

Upvotes: 2

joran
joran

Reputation: 173567

If I had to simulate a deck (or multiple decks) I would probably prefer to use a single integer vector in conjunction with some reference vectors, and then simply use modular arithmetic and indexing to determine suit, rank and value.

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

Upvotes: 4

josliber
josliber

Reputation: 44310

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.

Upvotes: 7

Related Questions