def test_get_face_up_card_AND_get_face_down_card(self): d = Dealer() empty_cc = CardCollection() dest_cc = CardCollection() d.add_card_to_hand(3) self.assertEqual(d.get_face_up_card(), 3) d.add_card_to_hand(4) self.assertEqual(d.get_face_down_card(), 4)
def test_add_card_to_hand_AND_move_all_card(self): d = Dealer() empty_cc = CardCollection() dest_cc = CardCollection() d.add_card_to_hand(3) d.add_card_to_hand(4) d.add_card_to_hand(10) self.assertEqual(empty_cc, dest_cc) d.move_all_cards(dest_cc) self.assertEqual(empty_cc, d.hand) expected_dest = CardCollection() expected_dest[3] = 1 expected_dest[4] = 1 expected_dest[10] = 1 self.assertEqual(dest_cc, expected_dest)
def simulate(numHands): card_cut_ptr = [random.randint(CUT_MIN, CUT_MAX)] draw_pile = Deck(NUM_DECKS) discard_pile = CardCollection() dealer = Dealer() player1 = Player() players = [player1] log = [] for _ in range(numHands): # deal cards for _ in range(2): for p in players + [dealer]: p.add_card_to_hand(draw_pile.pop_a_card()) for p in players + [dealer]: play_round(p, card_cut_ptr, draw_pile, discard_pile) for p in players: evaluate_round(p, dealer) log.append(p.wallet) clear_table(players + [dealer], discard_pile) return log
def test_move_all_cards(self): cc1 = CardCollection() cc2 = CardCollection() cc1[2] = 2 cc1[5] = 1 cc1[10] = 1 cc1.move_all_cards(cc2) self.assertEqual(cc2[2], 2) self.assertEqual(cc2[5], 1) self.assertEqual(cc2[10], 1) self.assertEqual(cc1[2], 0) self.assertEqual(cc1[5], 0) self.assertEqual(cc1[10], 0) self.assertEqual(cc1[4], 0) self.assertEqual(cc2[6], 0) self.assertEqual(cc2[11], 0)
class Player(): def __init__(self): self.hand = CardCollection() self.split_hand = CardCollection() self.wallet = 1000 self.wager = 2 def set_wager(self, wager) -> None: if type(wager) is not int or type(wager) is not float: raise TypeError('wager must be an int or float') if wager <= 0: raise ValueError('wager must be greater than 0') self.wager = wager def get_wallet_amount(self): return self.wallet def get_hand_value(self) -> int: return self.hand.get_total_value() def get_hand_len(self) -> int: return len(self.hand) def move_all_cards(self, dest : CardCollection) -> None: self.hand.move_all_cards(dest) self.split_hand.move_all_cards(dest) def __str__(self) -> str: return str(self.get_hand_value()) + ' ' + str(self.hand) def add_card_to_hand(self, card_value : int) -> None: if type(card_value) is not int: raise TypeError('card_value must be type int') if not (2 <= card_value <= 11): raise ValueError('card_value must be between 2 and 11') self.hand[card_value] += 1 def make_call(self, dealer_face_up_card=None, deck=None) -> Call: if self.get_hand_value() < 17: return Call.HIT return Call.STAND
def evaluate_round(player, dealer): if len(player.split_hand) != 0: tmp = CardCollection() player.split_hand.move_all_cards(tmp) #FIXME: #evaluate_round(player, dealer) print('FIXME: split hands') player_val = player.get_hand_value() dealer_val = dealer.get_hand_value() player_win = dealer_val < player_val <= 21 if player_val == 21 and len(player.hand) == 2 and player_win: player.wallet += player.wager * BLACKJACK_ODDS elif not player_win: player.wallet -= player.wager
class Dealer(): def __init__(self, strategy=None): self.hand = CardCollection() self.strategy = strategy self.face_up_card = None self.face_down_card = None def get_hand_len(self) -> int: return len(self.hand) def get_hand_value(self) -> int: return self.hand.get_total_value() def __str__(self) -> str: return str(self.get_hand_value()) + ' ' + str(self.hand) def add_card_to_hand(self, card_value : int): self.hand[card_value] += 1 if self.get_hand_len() == 1: self.face_up_card = card_value if self.get_hand_len() == 2: self.face_down_card = card_value def get_face_up_card(self): return self.face_up_card def get_face_down_card(self): return self.face_down_card def make_call(self, dealer_face_up_card=None, deck=None) -> Call: if self.get_hand_value() < 17: return Call.HIT return Call.STAND def move_all_cards(self, dest : CardCollection) -> None: self.face_up_card, self.face_down_card = None, None self.hand.move_all_cards(dest)
class Deck(): def __init__(self, num_decks: int): self.cards = CardCollection() for value in range(2, 10): # 1-9 cards self.cards[value] = 4 * num_decks self.cards[10] = 16 * num_decks # 10, Q, K, J self.cards[11] = 4 * num_decks # A def __repr__(self) -> str: return str(self.cards) def get_num_cards(self) -> int: return self.cards.get_num_cards() def __len__(self) -> int: return self.get_num_cards() def get_card_weights(self) -> List[int]: return [self.cards.get(key) for key in self.cards] def get_card_probabilities(self) -> List[float]: length = float(self.get_num_cards()) if length <= 0: raise Exception('No Cards in Deck') return [float(i) / length for i in self.get_card_weights()] def pop_a_card(self) -> int: """ Model removing the top card from the deck and returning the card value. """ if self.get_num_cards() <= 0: raise Exception('Can not pop card. Card deck has no cards.') w = self.get_card_weights() card_key = int(random.choices(list(self.cards), weights=w)[0]) self.cards[card_key] -= 1 return card_key
def __init__(self, num_decks: int): self.cards = CardCollection() for value in range(2, 10): # 1-9 cards self.cards[value] = 4 * num_decks self.cards[10] = 16 * num_decks # 10, Q, K, J self.cards[11] = 4 * num_decks # A
def __init__(self): self.hand = CardCollection() self.split_hand = CardCollection() self.wallet = 1000 self.wager = 2
def __init__(self, strategy=None): self.hand = CardCollection() self.strategy = strategy self.face_up_card = None self.face_down_card = None
def setUp(self): self.cc = CardCollection()
class TestCardCollectionMethods(unittest.TestCase): def setUp(self): self.cc = CardCollection() def test_init(self): for k in self.cc: self.assertEqual(self.cc.get(k), 0) def test_set_get(self): self.cc[2] = 1 self.cc[11] = 2 self.assertEqual(self.cc.get(2), 1) self.assertEqual(self.cc.get(11), 2) self.assertEqual(self.cc.get(3), 0) self.assertEqual(self.cc.get(4), 0) self.assertEqual(self.cc.get(8), 0) @unittest.expectedFailure def test_bad_get(self): self.assertRaises(TypeError, self.cc.get("2")) self.assertRaises(TypeError, self.cc.get(True)) self.assertRaises(ValueError, self.cc.get(1)) self.assertRaises(ValueError, self.cc.get(12)) @unittest.expectedFailure def test_bad_set(self): with self.assertRaises(TypeError): self.cc["2"] = 1 with self.assertRaises(ValueError): self.cc[1] = 2 with self.assertRaises(ValueError): self.cc[12] = 2 def test_repr_(self): a = '{2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0}' self.assertEqual(str(self.cc), a) def test_iter_(self): self.cc[5] = 2 for k in self.cc: if k == 5: self.assertEqual(self.cc.get(k), 2) else: self.assertEqual(self.cc.get(k), 0) def test_get_num_cards(self): self.assertEqual(self.cc.get_num_cards(), 0) self.cc[2] = 1 self.assertEqual(self.cc.get_num_cards(), 1) self.cc[3] = 1 self.assertEqual(self.cc.get_num_cards(), 2) self.cc[8] = 2 self.assertEqual(self.cc.get_num_cards(), 4) def test__len__(self): self.assertEqual(len(self.cc), 0) self.cc[2] = 1 self.assertEqual(len(self.cc), 1) self.cc[3] = 1 self.assertEqual(len(self.cc), 2) self.cc[8] = 2 self.assertEqual(len(self.cc), 4) def test_move_all_cards(self): cc1 = CardCollection() cc2 = CardCollection() cc1[2] = 2 cc1[5] = 1 cc1[10] = 1 cc1.move_all_cards(cc2) self.assertEqual(cc2[2], 2) self.assertEqual(cc2[5], 1) self.assertEqual(cc2[10], 1) self.assertEqual(cc1[2], 0) self.assertEqual(cc1[5], 0) self.assertEqual(cc1[10], 0) self.assertEqual(cc1[4], 0) self.assertEqual(cc2[6], 0) self.assertEqual(cc2[11], 0) def test_get_aceis11_total(self): self.cc[10] = 1 self.assertEqual(self.cc._get_aceis11_total(), 10) self.cc[2] = 3 self.assertEqual(self.cc._get_aceis11_total(), 16) self.cc[11] = 1 self.assertEqual(self.cc._get_aceis11_total(), 27) def test_get_aceis1_toal(self): self.cc[10] = 1 self.assertEqual(self.cc._get_aceis1_total(), 10) self.cc[2] = 3 self.assertEqual(self.cc._get_aceis1_total(), 16) self.cc[11] = 1 self.assertEqual(self.cc._get_aceis1_total(), 17) def test_get_total_value(self): self.cc[11] = 1 self.assertEqual(self.cc.get_total_value(), 11) self.cc[3] = 1 self.assertEqual(self.cc.get_total_value(), 14) self.cc[2] = 1 self.assertEqual(self.cc.get_total_value(), 16) self.cc[10] = 1 self.assertEqual(self.cc.get_total_value(), 16) self.cc[2] = 2 self.assertEqual(self.cc.get_total_value(), 18) self.cc[5] = 1 self.assertEqual(self.cc.get_total_value(), 23)