Example #1
0
def test_cardDeal():
	"""
	Testing that our number of cards goes down by one when dealing a card
	"""
	
	s = Shoe(6)
	numCards = len(s.getCards())
	s.dealCard()
	numCardsAfter = len(s.getCards())
	assert numCardsAfter == numCards - 1
Example #2
0
class Dealer(Player):
    """
	Class acts to abstract the things that a dealer would do
	We're extending Player as Dealers are a subset of players
	"""
    def blackJackPaysToInt(self, x):
        """
		Input:
			x = Ascii representation of what blackjack pays (such as "3:2" or "6:5")
		Action:
			Convert string into integer. Example: "3:2" would convert to 1.5
		Return:
			Integer for use in calculating blackjack payout
		"""

        # Split the numbers apart
        num, den = map(int, "3:2".split(":"))

        # Return the result
        return num / den

    def __init__(self, houseRules, ui, dealCardDelay=1):
        """
		Input:
			houseRules = object of rules as returned by "selectHouseRules"
			UI = Active UI instantiation
			(optional) dealCardDelay = number of seconds to sleep between dealer dealing a card
		"""

        self.numDecksPerShoe = int(houseRules["number_of_decks"], 10)

        self.hitSoft17 = asciiToBool(houseRules["hit_soft_17"])

        self.doubleAfterSplit = asciiToBool(houseRules["double_after_split"])

        # TODO: Not sure how to deal with this one. Probably need an enum.
        self.doubleOn = houseRules["double_on"]

        self.totalHandsAllowed = int(houseRules["total_hands"], 10)

        self.resplitAces = asciiToBool(houseRules["resplit_ace"])

        self.blackJackPays = self.blackJackPaysToInt(
            houseRules["blackjack_pays"])

        self.penetration = float(houseRules["penetration"])

        # Init a new Shoe while we're at it
        self.shoe = Shoe(self.numDecksPerShoe)
        self.shoe.shuffle()

        # Give ourself a hands list
        self.hands = []

        # Have we played our hand yet?
        self.dealerTurn = False

        # Set the UI
        self.ui = ui

        # Set our between card sleep timer
        self.dealCardDelay = dealCardDelay

    def allowedHandActions(self, hand, player):
        """
		Input:
			hand == Hand class instance
			player == Player class instance
		Action:
			Determines valid actions that the player can take with the given hand
		Returns:
			Set of allowed actions. Possible actions include "hit","stand","double","split","surrender"
		"""

        # TODO: Double after split

        # TODO: doubleOn

        # TODO: totalHandsAllowed

        # TODO: resplitAces

        actions = {"hit", "stand"}

        # Grab the cards
        cards = hand.getCards()

        # If this is our first two, we have more options
        if len(cards) == 2:
            # We can double any two first cards
            actions = actions.union({"double"})

            # We can split any first two cards that are the same
            if cards[0].getName() == cards[1].getName():
                actions = actions.union({"split"})

        return actions

    def dealCardToHand(self, hand, numCards=1):
        """
		Input:
			hand = Hand object that we should deal to
			(optional) numCards = integer number of cards to deal. 2 would be used to deal a new hand out.
		Action:
			Pops a card from the top of shoe stack and adds it to the hand object
		Return:
			Nothing. The object is mutable and changed in place to save memory and increase speed.
		"""

        # Bastardizing this a little to quickly deal any number of cards out
        for x in range(numCards):
            hand.addCard(self.shoe.dealCard())

    def dealHandsToTable(self, table):
        """
		Input:
			table == Table object
		Action:
			Deals a full hand to each player at the table (one at a time as you would in a Casino
		Returns:
			(insurance, dealerBlackJack)
			insurance == Do we need to ask players for insurance (meaning, Dealer is showing an Ace)
			dealerBlackJack == dealer has BlackJack
		"""

        # Need to do this twice because everyone gets 2 cards
        for x in range(2):
            # Loop through all the players
            for player in table.getPlayers():
                self.dealCardToHand(player.getHand())

            # Don't forget our own hand!
            self.dealCardToHand(self.getHand())

        # Check for blackjacks and insurance stuff here
        if self.getHand().getCards()[0].getName() == "A":
            insurance = True
        else:
            insurance = False

        # Check for dealer blackjack

        return insurance, self.getHand().isBlackJack()

    def facilitatePlayerHand(self, player, hand):
        """
		Input:
			player == Player object
			hand == Hand object
		Action:
			Performs calls and logic necessary to carry out all player's actions.
			Actual logic will be made either by the human player or simulation script.
			Any player busts will be taken care of after all hands are played
		Returns:
			Nothing
		"""

        # Loop so long as we haven't busted
        while not hand.isBusted():
            # Get valid actions for this hand
            validActions = self.allowedHandActions(hand, player)

            # Get action from the player.
            action = player.selectHandAction(player.getHands().index(hand),
                                             validActions)

            # We're hitting. Hit and let the loop take care of it
            if action == "hit":
                self.dealCardToHand(hand)

                self.ui.drawTable()

            # We're standing. Just return
            elif action == "stand":
                return

            # Put more money down. Assuming checks have been done before this call
            elif action == "double":
                # Determine how much was already bet
                bet = player.getBets()[player.getHands().index(hand)]

                # If doubling the bet would be more money than they have, throw exception
                if bet > player.getMoney():
                    raise Exception("You're trying to bet more than you have.")

                # If we get here, they have enough to cover the bet
                # Move that money to their bet
                player.addMoney(bet * -1)
                player.getBets()[player.getHands().index(hand)] += bet

                # Give them one more card only
                self.dealCardToHand(hand)
                return
            else:
                raise Exception(
                    "I haven't implemented {0} yet.".format(action))

    def playDealersHand(self, table):
        """
		Input:
			table = Table object that the dealer is at
		Action:
			Plays out the dealer's turn
		Returns:
			Nothing
		"""

        # It's our turn now
        self.dealerTurn = True

        # Show our cards
        self.ui.drawTable()

        # See if we actually need to play
        if table.getNumActiveHands() == 0:
            # No reason to play further
            return

        # Time to play our hand
        hand = self.getHand()

        # Continue doing things so long as we havne't busted
        while not hand.isBusted():
            # Show our cards
            self.ui.drawTable()

            # Pause between cards
            sleep(self.dealCardDelay)

            # Remember, handValue initially is a list here
            handValue = hand.getValue()

            # Convienience Checks
            isHard = len(handValue) == 1
            isSoft = not isHard

            # Solidify handValue to a single value
            handValue = handValue[-1]

            ###############
            # Hard Values #
            ###############
            if isHard:

                # Stand on 17 and above
                if handValue >= 17:
                    return

                # Time to take another card
                self.dealCardToHand(hand)
                continue

            ###############
            # Soft Values #
            ###############
            else:
                # Stand on 18+ for sure
                # Also stand on 17 if it's in our rules
                if handValue >= 18 or (handValue == 17 and not self.hitSoft17):
                    return

                # Otherwise hit
                self.dealCardToHand(hand)
                continue

    def payoutTable(self, table):
        """
		Input:
			table == Table object
		Action:
			Check dealer's score vs players score and pay or take money
		Returns:
			Nothing
		"""

        # Get my own value
        dealerHand = self.getHand()
        dealerValue = dealerHand.getValue()
        dealerBusted = dealerHand.isBusted()
        if not dealerBusted:
            # Pop the highest value we have
            dealerValue = dealerValue[-1]
        else:
            # Changing value to 0 to make things simpler
            dealerValue = 0

        # Loop through all players
        for player in table.getPlayers():
            playerBets = player.getBets()

            # All hands for the given player
            for hand in player.getHands():
                # If the player busted, there's actually nothing to do
                # This is because the bet value is already removed when betting
                # Table clean-up will take care of the rest
                if hand.isBusted():
                    continue

                playerValue = hand.getValue()[-1]
                # Get associated bet for hand
                playerBet = playerBets[player.getHands().index(hand)]

                # If player did better than dealer
                if playerValue > dealerValue:
                    player.addMoney(playerBet * 2)
                    continue

                # If player did the same as dealer
                elif playerValue == dealerValue:
                    player.addMoney(playerBet)