# How could I predict the results of a simple card game?

I want to predict the results of a simple card game, to judge on average, how long a game will last.

My 'simple' game is;

• Cards are dealt from a randomised deck to n players (typically 2-4)
• Each player gets five cards
• The top card from the deck is turned over
• Each player takes it in turns to either place a card of the same face value (i.e 1-10, J, Q, K, A), the same suit (i.e Hearts, Diamonds, Spades, Clubs) or any suit of magic card (a jack)
• If the player can place a card they do, otherwise they must take a card from the deck
• Play continues in turn until all but one player has no cards left

I'm guessing that I could write code to play a mythical game and report the result, then run that code thousands of times.

Has anyone done this ? Can they suggest code that does a similar job (my favoured language is R, but anything would do) ? Is there a better way ?

• It'd be fun to see your code once you write it :) Sorry, I don't remember coming across such a thing... Commented Aug 6, 2010 at 11:04
• I did something similar a while back to analyze the most-frequently-landed-on spaces in Monopoly (wrote a small simulator)... not sure if there's another way of doing it. Commented Aug 6, 2010 at 11:47
• Seems off-topic. I am not sure I see the link to statistical analysis in the question. This seems appropriate for stackoverflow.com.
– user28
Commented Aug 6, 2010 at 12:21
• Strikant - since it can be solved with simulation, I think keeping the question will be o.k. Commented Aug 6, 2010 at 12:45
• I agree with it Tal. It's a statistical computing problem. Commented Aug 6, 2010 at 12:58

## 1 Answer

The easiest way is just to simulate the game lots of times. The R code below simulates a single game.

nplayers = 4
#Create an empty data frame to keep track
#of card number, suit and if it's magic
empty.hand = data.frame(number = numeric(52),
suit = numeric(52),
magic  = numeric(52))

#A list of players who are in the game
players =list()
for(i in 1:nplayers)
players[[i]] = empty.hand

#Simulate shuffling the deck
deck = empty.hand
deck$number = rep(1:13, 4) deck$suit = as.character(rep(c("H", "C", "S", "D"), each=13))
deck$magic = rep(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), each=4) deck = deck[sample(1:52, 52),] #Deal out five cards per person for(i in 1:length(players)){ r = (5*i-4):(5*i) players[[i]][r,] = deck[r,] } #Play the game i = 5*length(players)+1 current = deck[i,] while(i < 53){ for(j in 1:length(players)){ playersdeck = players[[j]] #Need to test for magic and suit also - left as an exercise! if(is.element(current$number, playersdeck$number)){ #Update current card current = playersdeck[match(current$number,
playersdeck$number),] #Remove card from players deck playersdeck[match(current$number, playersdeck$number),] = c(0, 0, 0) } else { #Add card to players deck playersdeck[i,] = deck[i,] i = i + 1 } players[[j]] = playersdeck #Has someone won or have we run out of card if(sum(playersdeck$number) == 0 | i > 52){
i = 53
break
}
}
}

#How many cards are left for each player
for(i in 1:length(players))
{
cat(sum(players[[i]]\$number !=0), "\n")
}


Some comments

1. You will need to add a couple of lines for magic cards and suits, but data structure is already there. I presume you didn't want a complete solution? ;)
2. To estimate the average game length, just place the above code in a function and call lots of times.
3. Rather than dynamically increasing a vector when a player gets a card, I find it easier just to create a sparse data frame that is more than sufficient. In this case, each player has a data frame with 52 rows, which they will never fill (unless it's a 1 player game).
4. There is a small element of strategy with this game. What should you do if you can play more than one card. For example, if 7H comes up, and you have in your hand 7S, 8H and the JC. All three of these cards are "playable".
• That's perfect ! I was hoping for a pointer but that's a really good answer. Thanks. Commented Aug 8, 2010 at 20:11