8
$\begingroup$

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 ?

$\endgroup$
6
  • 2
    $\begingroup$ It'd be fun to see your code once you write it :) Sorry, I don't remember coming across such a thing... $\endgroup$
    – Tal Galili
    Aug 6 '10 at 11:04
  • $\begingroup$ 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. $\endgroup$
    – warren
    Aug 6 '10 at 11:47
  • $\begingroup$ Seems off-topic. I am not sure I see the link to statistical analysis in the question. This seems appropriate for stackoverflow.com. $\endgroup$
    – user28
    Aug 6 '10 at 12:21
  • $\begingroup$ Strikant - since it can be solved with simulation, I think keeping the question will be o.k. $\endgroup$
    – Tal Galili
    Aug 6 '10 at 12:45
  • $\begingroup$ I agree with it Tal. It's a statistical computing problem. $\endgroup$ Aug 6 '10 at 12:58
11
$\begingroup$

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".
$\endgroup$
1
  • $\begingroup$ That's perfect ! I was hoping for a pointer but that's a really good answer. Thanks. $\endgroup$ Aug 8 '10 at 20:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.