Created
March 31, 2015 16:21
-
-
Save johndgiese/d33d3ef0417a2ef0f939 to your computer and use it in GitHub Desktop.
Analysis of Card Game My Younger Brother Plays
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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