How to make a deck of cards in R
Just for the fun of it, I wanted to see how to create a complete deck of playing cards in the least amount of steps possible. Obviously, I could have just imported a premade dataset based on scraping a webpage or a csv file that someone created already but what fun would that be? So here we go!
Goal: We need to create a deck of cards that includes 4 different suits of 13 different values, and 13 different faces.
- Make the suits in order by naming the four suits and listing them 13 times so that all 3 lists are the same length.
suits <- c('spades', 'clubs', 'diamonds', 'hearts')
suit <- unlist(map(suits, rep, 13))
head(suit)
## [1] "spades" "spades" "spades" "spades" "spades" "spades"
- Make the faces by listing out all 13 and we can duplicate it from there.
faces <- c('king', 'queen', 'jack', 'ten', 'nine', 'eight', 'seven', 'six', 'five', 'four', 'three', 'two', 'ace')
face <- rep(faces, 4)
head(face)
## [1] "king" "queen" "jack" "ten" "nine" "eight"
- Make the values of the cards by listing out the values and then duplicating that 4xs
value <- rep(13:1, 4)
head(value)
## [1] 13 12 11 10 9 8
- Make the deck by combining the 3 different lists.
deck <- data.frame(face, suit, value)
head(deck)
## face suit value
## 1 king spades 13
## 2 queen spades 12
## 3 jack spades 11
## 4 ten spades 10
## 5 nine spades 9
## 6 eight spades 8
tail(deck)
## face suit value
## 47 six hearts 6
## 48 five hearts 5
## 49 four hearts 4
## 50 three hearts 3
## 51 two hearts 2
## 52 ace hearts 1
deck %>%
group_by(suit) %>%
summarise(cards = n(),
totalValue = sum(value))
## # A tibble: 4 × 3
## suit cards totalValue
## <chr> <int> <int>
## 1 clubs 13 91
## 2 diamonds 13 91
## 3 hearts 13 91
## 4 spades 13 91
Now we need to create the deal function
The following is a simple deal function that will deal out 7 random cards (rows) from the deck and not replace those cards back into the deck during the random sample process.
deal <- function(x) {
sample_n(deck, x, replace = F)
}
deal(7)
## face suit value
## 1 queen hearts 12
## 2 six diamonds 6
## 3 eight spades 8
## 4 three diamonds 3
## 5 four clubs 4
## 6 nine hearts 9
## 7 jack spades 11
Let’s play a game of blackjack
Now that we have the deck compiled we can start playing a game. Blackjack will be a great place to start since it is fairly straight forward. The biggest problem we are going to have is dealing cards from a single deck without having it reshuffle using another function call. The remaining items in the deck must be saved as the new deck.
There is a simple solution to keeping the cards that were drawn from being pulled again. The ‘anti_join()’ function can help us with that.
We will need to remove the items from the dealers hand and save it as a list item. Then we need to deal out the 2 cards for the player. If the user wants another card then he will need to ask for a new card while supplying the dealer hand along with the user hand. It is important that these rows are not included in the deck when asked.
Let’s edit the deal function to return all 3 elements if needed.
deal <- function(x, set = NULL){
hand <- set$myhand
dealerhand <- set$dealerhand
myhand = list()
#remove the existing hand from the deck if it is included
if(!is.null(hand)) {
deck <- deck %>% anti_join(hand)
}
#remove the existing dealer's hand from the deck if it is included
if(!is.null(dealerhand)) {
deck <- deck %>% anti_join(dealerhand)
}
#if there is not dealer hand included then we need to get him 2 cards
if(is.null(dealerhand)) {
dealerhand <- sample_n(deck, 2, replace = F)
#once this is done we need to remove those 2 cards from the deck
deck <- deck %>% anti_join(dealerhand)
}
#the new cards need to be drawn from the deck
newhand <- sample_n(deck, x, replace = F)
#if the hand is not null then
if(!is.null(hand)) {
myhand <- rbind(hand, newhand)
} else {
myhand <- newhand
}
hand <- list(myhand = myhand, dealerhand = dealerhand)
return(hand)
}
#Deal the cards and get your set
set <- deal(2)
## Joining, by = c("face", "suit", "value")
set$myhand
## face suit value
## 1 ten diamonds 10
## 2 queen clubs 12
set$dealerhand
## face suit value
## 1 ace spades 1
## 2 two spades 2
#play on if you feel lucky!
set <- deal(1, set)
## Joining, by = c("face", "suit", "value")
## Joining, by = c("face", "suit", "value")
str(set)
## List of 2
## $ myhand :'data.frame': 3 obs. of 3 variables:
## ..$ face : chr [1:3] "ten" "queen" "five"
## ..$ suit : chr [1:3] "diamonds" "clubs" "diamonds"
## ..$ value: int [1:3] 10 12 5
## $ dealerhand:'data.frame': 2 obs. of 3 variables:
## ..$ face : chr [1:2] "ace" "two"
## ..$ suit : chr [1:2] "spades" "spades"
## ..$ value: int [1:2] 1 2
Now we have the dealers hand and the players hand. This is just a start but a fun excercise for me and my 11 year old son, Garrett.