Skip to content

Instantly share code, notes, and snippets.

@johndgiese
Created March 31, 2015 16:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johndgiese/d33d3ef0417a2ef0f939 to your computer and use it in GitHub Desktop.
Save johndgiese/d33d3ef0417a2ef0f939 to your computer and use it in GitHub Desktop.
Analysis of Card Game My Younger Brother Plays
"""
The card game we are analyzing plays as follows:
1. Shuffle a deck of 52 playing cards
2. Player is dealt N cards into the "face down pile"
3. Turn over a card and place it in the "face up pile":
- if it is an ace, deal 4 cards from the deck to the "face down pile"
- if it is a king deal 3
- if it is a queen deal 2
- if it is a jack deal 1
4. Repeat step three until the deck or the "face down pile" is empty
Cards are represented as the integers 0 - 51.
The `play` function simulates playing this game, and returns three
lists of integers representing the "face up pile", the "face down pile",
and the deck.
"""
import random
def is_ace(card):
return card % 13 == 0
def is_king(card):
return card % 13 == 1
def is_queen(card):
return card % 13 == 2
def is_jack(card):
return card % 13 == 3
def init_deck():
return list(range(52))
def deal(deck):
card = random.choice(deck)
deck.remove(card)
return card, deck
def deal_n(deck, n):
pile = []
for i in range(n):
if len(deck) == 0:
break
card, deck = deal(deck)
pile.append(card)
return pile, deck
def play(starting_with):
deck = init_deck()
face_down_pile, deck = deal_n(deck, starting_with)
face_up_pile = []
while len(face_down_pile) > 0 and len(deck) > 0:
card, face_down_pile = deal(face_down_pile)
if is_ace(card):
drawn_cards, deck = deal_n(deck, 4)
elif is_king(card):
drawn_cards, deck = deal_n(deck, 3)
elif is_queen(card):
drawn_cards, deck = deal_n(deck, 2)
elif is_jack(card):
drawn_cards, deck = deal_n(deck, 1)
else:
drawn_cards = []
face_down_pile.extend(drawn_cards)
face_up_pile.append(card)
return face_down_pile, face_up_pile, deck
"""
Plot the distribution of the number of turned over cards,
starting with various numbers of initial cards.
"""
from cards import play
import numpy as np
import matplotlib.pyplot as plt
import seaborn
num_trials = 1000000
starting_with_array = range(6, 14)
for starting_with in starting_with_array:
num_dealt = []
for ii in range(num_trials):
face_down_pile, face_up_pile, _ = play(starting_with)
num_dealt.append(len(face_up_pile) + len(face_down_pile))
num_dealt_as_array = np.asarray(num_dealt)
y, binEdges = np.histogram(num_dealt_as_array, bins=40)
y = y/float(num_trials)
bincenters = 0.5*(binEdges[1:] + binEdges[:-1])
plt.plot(bincenters, y, '-')
plt.legend(["Starting with " + str(n) for n in starting_with_array], loc=2)
plt.xlabel('Number of cards dealt')
plt.ylabel('Frequency')
plt.title('Ride The Bus!!!')
plt.grid(True)
plt.xlim(10, 52)
plt.show()
from cards import is_jack, is_ace, is_king, is_queen, play
def num_jacks(cards):
return len(list(filter(is_jack, cards)))
def num_queens(cards):
return len(list(filter(is_queen, cards)))
def num_kings(cards):
return len(list(filter(is_king, cards)))
def num_aces(cards):
return len(list(filter(is_ace, cards)))
for starting_with in range(12):
for ii in range(100):
face_down_pile, face_up_pile, deck = play(starting_with)
expected_num_cards_in_face_up_pile = starting_with + num_jacks(face_up_pile) \
+ num_queens(face_up_pile)*2 + num_kings(face_up_pile)*3 + num_aces(face_up_pile)*4
assert expected_num_cards_in_face_up_pile == len(face_up_pile)
for starting_with in range(52):
for ii in range(100):
face_down_pile, face_up_pile, deck = play(starting_with)
assert len(face_up_pile) + len(face_down_pile) + len(deck) == 52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment