Exemple #1
0
 def _init_hand(self, buy_in: int = 1):
     """This initializes a hand of blackjack with a minimum buy-in of :param buy_in dollars."""
     # zeroth check to make sure buy_in denom is in the standard chip denoms
     buy_in_key = ChipStack.get_chip_string(buy_in)
     if buy_in_key not in ChipStack.get_empty_stack().keys():
         raise KeyError(
             'The buy-in value of \'{}\' is not in the standard denominations'
             .format(buy_in_key))
     # also discard any cards in the hand already
     self.dealer.discard(
         self.discard_pile,
         [x.name for x in self.dealer.hand])  # TODO: refactor this...
     for player in self.players.values():
         player.discard(self.discard_pile, [x.name for x in player.hand])
     # first check if all players want to buy-in to the hand
     self.dealt_in_players = list(
         self.players.keys())  # deal in all players initially
     self.take_bets(min_bet=buy_in)
     # second deal hands to all players that are still dealt-in
     self.deal_cards(list(self.players.values()), n_cards=2,
                     n_visible=2)  # two face up
     self.deal_cards([self.dealer], n_cards=1, n_visible=1)  # one face up
     self.deal_cards([self.dealer], n_cards=1, n_visible=0)  # one face down
     # print out the hands for all players and their bets
     for player_name in self.dealt_in_players:
         self.players[player_name].view_hand(all_visible=True)
     self.dealer.view_hand()
     # lastly check for any naturals or busts before moving to game loop
     self.check_for_payouts(end_of_hand=False)
     return  # move to the next state of gameplay
Exemple #2
0
 def __init__(self,
              name: str = '',
              chips: Optional[ChipStack] = None,
              hand: Optional[CardHand] = None,
              pot: Optional[ChipStack] = None,
              action_set: Optional[ActionSet] = None) -> None:
     self.name: str = name
     if chips is None:
         chips = ChipStack()
     if hand is None:
         hand = CardHand()
     if pot is None:
         pot = ChipStack()
     self.pot = pot  # unless there is a shared pot object passed in, each player instance gets its own pot instance
     self.chips: ChipStack = chips  # empty stack unless otherwise specified
     self._player_hand: CardHand = hand
     if action_set is None:
         action_set = {
             'actions_basic':  # load only a basic set of instance methods for actions
             {
                 'view-hand': self.view_hand,
                 'draw': self.draw,
                 'discard': self.discard,
                 'transfer': self.transfer
             }
         }
     self.action_set: ActionSet = action_set
Exemple #3
0
 def __init__(self):
     # Setup the Players
     self.dealer: Player = Player(name='dealer',
                                  chips=ChipStack.from_dealer_stack())
     self.players: Dict[str, Player] = {
         'human': Player('human', ChipStack.from_standard_stack())
     }
     self.dealt_in_players: List[str] = list(
         self.players.keys())  # deal-in all players initially
     # Setup the Decks
     self.draw_pile: CardPile = CardPile.from_standard_deck()
     self.draw_pile.shuffle()
     self.discard_pile: CardPile = CardPile()
Exemple #4
0
 def test_filled_stack_from_amount(self):
     target = {
         '$1': 1,
         '$5': 1,
         '$10': 1,
         '$20': 0,
         '$25': 1,
         '$50': 1,
         '$100': 1
     }
     temp = ChipStack.filled_stack_from_amount(
         ChipStack.get_stack_value(target))
     for key in temp.keys():
         self.assertEqual(temp[key], target[key])
Exemple #5
0
 def test_transfer_chips_all(self):
     cs1 = ChipStack.from_standard_stack()
     cs2 = ChipStack()
     std_stack = cs1.stack.copy()
     empty_stack = cs2.stack.copy()
     # transfer everything from cs1 to cs2
     cs1.transfer_chips(cs2, cs1.stack)
     self.assertEqual(cs1.stack, empty_stack)
     self.assertEqual(cs2.stack, std_stack)
     # transfer emptied stack to cs2 again
     cs1.transfer_chips(cs2, cs1.stack)
     self.assertEqual(cs1.stack, empty_stack)
     self.assertEqual(cs2.stack, std_stack)
     # try to transfer a standard_stack from cs1 to cs2 again
     self.assertRaises(ValueError, cs1.transfer_chips, cs2, std_stack)
Exemple #6
0
 def check_for_payout(self, player: Player) -> bool:
     """
     This function checks to see if a single player (not a dealer) has gotten blackjack or busted.
     If they have, then return out_of_game=True for 'removal from dealt-in players logic'
     """
     out_of_game: bool = False
     (is_blackjack, payout_rate) = BlackJack.is_blackjack(player)
     if is_blackjack:
         # Dealer pays out to the player
         # assume rounding down is house cut
         payout_value: int = int(payout_rate * player.pot.stack_value)
         n_payout_chips: Dict[str, int] = ChipStack.get_chips_from_amount(
             payout_value, denom_pref='high')
         self.dealer.payout_chips(player.pot, n_payout_chips)
         # Remove player from dealt_in list
         self.dealt_in_players.remove(player.name)
         print('{0} has gotten blackjack and wins ${1}'.format(
             player.name, payout_value))
         out_of_game = True
     elif BlackJack.is_bust(player):
         # Player pays out to dealer
         player.payout_all(self.dealer.pot)
         # Remove player from dealt_in list
         self.dealt_in_players.remove(player.name)
         print('{0} has busted and loses ${1}'.format(
             player.name, player.pot.stack_value))
         out_of_game = True
     return out_of_game
Exemple #7
0
 def test_get_empty_stack(self):
     empty = {
         '$1': 0,
         '$5': 0,
         '$10': 0,
         '$20': 0,
         '$25': 0,
         '$50': 0,
         '$100': 0
     }
     self.assertEqual(ChipStack.get_empty_stack(), empty)
Exemple #8
0
 def test_transfer_chips_sample(self):
     sample = {'$1': 0, '$5': 5, '$10': 3}
     cs1 = ChipStack(sample)
     cs2 = ChipStack()
     sample_stack = cs1.stack.copy()
     empty_stack = cs2.stack.copy()
     # transfer everything from cs1 to cs2
     cs1.transfer_chips(cs2, cs1.stack)
     self.assertEqual(cs1.stack, empty_stack)
     self.assertEqual(cs2.stack, sample_stack)
     # transfer everything back
     cs2.transfer_chips(cs1, cs2.stack)
     self.assertEqual(cs1.stack, sample_stack)
     self.assertEqual(cs2.stack, empty_stack)
Exemple #9
0
 def test_init_from_amount(self):
     target = {
         '$1': 1,
         '$5': 1,
         '$10': 1,
         '$20': 0,
         '$25': 1,
         '$50': 1,
         '$100': 1
     }
     cs = ChipStack.from_amount(amount=191)
     for key in cs.stack.keys():
         self.assertEqual(cs.stack[key], target[key])
Exemple #10
0
 def test_standard_stack_init(self):
     std = {
         '$1': 25,
         '$5': 5,
         '$10': 3,
         '$20': 1,
         '$25': 0,
         '$50': 2,
         '$100': 1
     }
     cs = ChipStack.from_standard_stack()
     for key in cs.stack.keys():
         self.assertEqual(cs.stack[key], std[key])
Exemple #11
0
 def test_init_from_dealer(self):
     dealer = {
         '$1': 1000,
         '$5': 1000,
         '$10': 1000,
         '$20': 1000,
         '$25': 1000,
         '$50': 1000,
         '$100': 1000
     }
     cs = ChipStack.from_dealer_stack()
     self.assertEqual(cs.name, 'dealer')
     for key in cs.stack.keys():
         self.assertEqual(cs.stack[key], dealer[key])
Exemple #12
0
 def test_exchange_chips(self):
     cs = ChipStack.from_standard_stack()
     # exchange all 3 $10 chips for 30 $1 chips (all chips)
     cs.exchange_chips('$10', '$1')
     self.assertEqual(cs.stack['$10'], 0)
     self.assertEqual(cs.stack['$1'], 55)
     # exchange all 3 $10 chips for 30 $1 chips (all chips)
     cs.exchange_chips('$50', '$10', 1)
     self.assertEqual(cs.stack['$50'], 1)
     self.assertEqual(cs.stack['$10'], 5)
     # try to exchange 25 $1 chips for 1 $50 and get error
     self.assertRaises(ValueError, cs.exchange_chips, '$1', '$50', 25)
     # exchange all 55 $1 chips for 1 $50 chips (all chips)
     cs.exchange_chips('$1', '$50')
     self.assertEqual(cs.stack['$50'], 2)
     self.assertEqual(cs.stack['$1'], 5)
     # try to exchange chips for bad denominations
     self.assertRaises(KeyError, cs.exchange_chips, '$1', '#50')
     self.assertRaises(KeyError, cs.exchange_chips, '#1', '$50')
Exemple #13
0
 def test_add_amount_of_chips(self):
     # Test a simple case
     cs = ChipStack()
     cs.add_amount_of_chips(amount=201)  # sum of all the keys
     self.assertEqual(cs.stack['$1'], 1)  # 201 -> $1: 1 and $5: 40
     self.assertEqual(cs.stack['$5'], 0)  # 200 -> $5: 0 and $10: 20
     self.assertEqual(cs.stack['$10'], 0)  # 200 -> $10: 0 and $20: 10
     self.assertEqual(cs.stack['$20'], 0)  # 200 -> $20: 0 and $25: 8
     self.assertEqual(cs.stack['$25'], 0)  # 200 -> $25: 0 and $50: 4
     self.assertEqual(cs.stack['$50'], 0)  # 200 -> $50: 0 and $100: 2
     self.assertEqual(cs.stack['$100'], 2)
     # Test a case when adding the remainder of an exchange
     # NOTE: once the amount has been deposited into the lowest chip denoms, do not sort into higher as side effect
     cs = ChipStack({'$5': 0, '$10': 7, '$25': 0})
     remainder = 5
     cs.add_amount_of_chips(remainder)
     self.assertEqual(cs.stack['$1'], 0)  # 5 of $1 goes to 1 of $5
     self.assertEqual(cs.stack['$5'], 1)  # stays
     self.assertEqual(cs.stack['$10'], 7)
     self.assertEqual(cs.stack['$20'], 0)
     self.assertEqual(cs.stack['$25'], 0)
     self.assertEqual(cs.stack['$50'], 0)
     self.assertEqual(cs.stack['$100'], 0)
Exemple #14
0
 def test_remove_chips(self):
     # create a std stack and remove another empty stack
     cs = ChipStack.from_standard_stack()
     empty_stack = {
         '$1': 0,
         '$5': 0,
         '$10': 0,
         '$20': 0,
         '$25': 0,
         '$50': 0,
         '$100': 0
     }
     std_stack = cs.stack.copy()
     cs._remove_chips(empty_stack)
     self.assertEqual(cs.stack, std_stack)
     self.assertNotEqual(cs.stack, empty_stack)
     # remove a std stack from the std stack to see if empty
     cs._remove_chips(std_stack)
     self.assertEqual(cs.stack, empty_stack)
     # prevent chip quantities from going negative
     # see https://stackoverflow.com/questions/129507/how-do-you-test-that-a-python-function-throws-an-exception
     self.assertRaises(ValueError, cs._remove_chips, std_stack)
Exemple #15
0
 def test_add_chips(self):
     # create an empty stack and add another empty stack
     cs = ChipStack()
     empty_stack = {
         '$1': 0,
         '$5': 0,
         '$10': 0,
         '$20': 0,
         '$25': 0,
         '$50': 0,
         '$100': 0
     }
     stack = cs.stack.copy()
     cs._add_chips(empty_stack)
     self.assertEqual(cs.stack, stack)
     self.assertEqual(cs.stack, empty_stack)
     # create an standard stack and add its stack to
     cs2 = ChipStack.from_standard_stack()
     cs._add_chips(cs2.stack)
     self.assertEqual(cs.stack, cs2.stack)
Exemple #16
0
 def test_exchange_chips_with_remainders(self):
     cs = ChipStack()
     cs._add_chips({'$25': 3})
     cs.exchange_chips('$25', '$10')
     self.assertEqual(cs.stack['$10'], 7)
     self.assertEqual(cs.stack['$5'], 1)
     cs.stack = ChipStack.get_empty_stack()
     cs._add_chips({'$20': 6})
     cs.exchange_chips('$20', '$50')
     self.assertEqual(cs.stack['$50'], 2)
     self.assertEqual(cs.stack['$20'], 1)
Exemple #17
0
 def test_get_stack_value(self):
     cs = ChipStack.from_standard_stack()
     self.assertEqual(300, ChipStack.get_stack_value(cs.stack))
Exemple #18
0
    def check_for_payouts(self, end_of_hand: bool = False) -> None:
        """
        This function checks to see all players have gotten blackjack or busted.
        If they have, then they are removed from the dealt-in players list and payouts go accordingly.
        Additionally, if its the end of the hand, the scores vs. the dealer are checked and paid put
        """
        max_dealer_hand_value: int = max(BlackJack.get_hand_value(self.dealer))
        dealer_busted: bool = True if max_dealer_hand_value > 21 else False
        for player_name in self.dealt_in_players:
            if end_of_hand:
                # This will be used later for checking payouts at the end of a hand
                max_player_hand_value: int = max(
                    BlackJack.get_hand_value(self.players[player_name]))

            out_of_game = self.check_for_payout(self.players[player_name])
            if out_of_game:
                continue  # don't continue to check other conditions

            if end_of_hand and (max_player_hand_value > max_dealer_hand_value
                                or dealer_busted):
                # Dealer pays out to the player
                # assume rounding down is house cut
                payout_value: int = int(
                    1.5 * self.players[player_name].pot.stack_value)
                n_payout_chips: Dict[str,
                                     int] = ChipStack.get_chips_from_amount(
                                         payout_value, denom_pref='high')
                self.dealer.payout_chips(self.players[player_name].pot,
                                         n_payout_chips)
                # Remove player from dealt_in list
                self.dealt_in_players.remove(player_name)
                # Print the results
                self.players[player_name].view_hand(self.dealer,
                                                    all_visible=True)
                if dealer_busted:
                    print('Dealer busts so {0} wins ${1}'.format(
                        player_name, payout_value))
                else:
                    print('{0} beat the dealer and wins ${1}'.format(
                        player_name, payout_value))
            elif end_of_hand and not dealer_busted and (max_player_hand_value <
                                                        max_dealer_hand_value):
                # Player pays out to dealer
                self.players[player_name].payout_all(self.dealer.pot)
                # Remove player from dealt_in list
                self.dealt_in_players.remove(player_name)
                # Print the results
                self.players[player_name].view_hand(self.dealer,
                                                    all_visible=True)
                print(
                    'Dealer did not bust and beats {0}\'s hand. {0} loses ${1}'
                    .format(player_name, self.players[player_name].bet_value))
            elif end_of_hand and not dealer_busted and (
                    max_player_hand_value == max_dealer_hand_value):
                # Player does not lose their money, but doesn't get paid out.
                self.players[player_name].payout_all(
                    self.players[player_name].pot)  # return the money from pot
                # Remove player from dealt_in list
                self.dealt_in_players.remove(player_name)
                print('Dealer ties {0}\'s hand. {0} is returned ${1}'.format(
                    player_name, self.players[player_name].bet_value))
Exemple #19
0
 def test_stack_init_sample(self):
     sample = {'$1': 0, '$5': 5, '$10': 3}
     cs = ChipStack(sample)
     for key in cs.stack.keys():
         self.assertEqual(cs.stack[key], sample.get(key, 0))
Exemple #20
0
 def test_get_chip_value(self):
     self.assertEqual(5, ChipStack.get_chip_value('$5'))
     self.assertRaises(KeyError, ChipStack.get_chip_value, '##20$')
Exemple #21
0
 def test_get_chip_string(self):
     self.assertEqual('$20', ChipStack.get_chip_string(20))
     self.assertRaises(ValueError, ChipStack.get_chip_string, 11)
Exemple #22
0
 def test_empty_init(self):
     cs = ChipStack(stack=None)
     for key in cs.stack.keys():
         self.assertEqual(cs.stack[key], 0)