Пример #1
0
 def test_kellyCriterion(self):
     deck = BlackjackDeck()
     deck.drawCard()
     self.player.updateCount(
         [Card('2', 'C'), Card('3', 'C'),
          Card('5', 'C')], [Card('Q', 'S')])
     self.assertEquals(self.player.count, 2)
     self.assertEquals(self.player.calculateAdvantage(deck), 0.0125)
     self.assertEquals(self.player.kellyCriterion(deck), 12.5)
Пример #2
0
 def test_mitStrategy(self):
     deck = BlackjackDeck()
     deck.drawCard()
     self.player.updateCount(
         [Card('2', 'C'), Card('3', 'C'),
          Card('5', 'C')], [Card('Q', 'S'), Card('4', 'S')])
     self.player.updateCount(
         [Card('2', 'C'), Card('3', 'C'),
          Card('5', 'C')], [Card('Q', 'S'), Card('4', 'S')])
     self.player.updateCount(
         [Card('2', 'C'), Card('3', 'C'),
          Card('5', 'C')], [Card('Q', 'S'), Card('4', 'S')])
     self.assertEquals(self.player.count, 9)
     self.assertEquals(self.player.mitStrategy(deck), 5)
Пример #3
0
class Blackjack:
    def __init__(self, numDecks=8, player=Player(), **kwargs):
        self.numDecks = numDecks
        self.deck = BlackjackDeck(self.numDecks)
        # [player, bet]
        self.player = [player, 0]
        self.dealer = Player()
        self.reshuffle = False
        self.learning = False

        if isinstance(self.player[0], QLearningAgent):
            self.learning = True

        # Flags
        self.noPrint = False

        if "flags" in kwargs:
            if "-np" in kwargs['flags']:
                self.noPrint = True

    # Deals a card to player from the deck
    # If card dealt is cut card, plan to reshuffle at end of round
    def dealCard(self, player):
        card = self.deck.drawCard()
        if card.getValue() == "cut":
            self.reshuffle = True
            card = self.deck.drawCard()
        player.addToHand(card)

    def double(self, player):
        self.dealCard(player[0])
        player[1] = player[1] * 2
        player[0].doubleBet()

    # Deals cards to start a round
    def startRound(self):
        for _ in xrange(2):
            self.dealCard(self.player[0])
            self.dealCard(self.dealer)
        if self.learning:
            # initialize state for Q-Learning
            self.player[0].updateState(
                (self.player[0].getHandValue(),
                 self.dealer.getCardValue(self.getDealerUpcard())))

    # Gets the dealer's face up card (i.e. first card in hand)
    def getDealerUpcard(self):
        return self.dealer.getHand()[0]

    # Runs the game
    def playRound(self):
        self.startRound()

        # Gather bet
        bet = self.player[0].getBet(self.deck)
        if bet == False:
            return (False, self.player[0].winRate)
        self.player[1] = bet

        # Get dealer's face up card
        dealerUpcard = self.getDealerUpcard()
        lastAction = None
        lastState = None

        # Player turn
        while True:
            if not self.noPrint:
                print "\n\nDealer upcard: {0}".format(dealerUpcard)

            # Value of dealer's face-up card for qlearning
            dealerUpValue = self.dealer.getCardValue(dealerUpcard)

            # getAction determines next action according to agent
            action = self.player[0].getAction(dealerUpcard)

            lastState = self.player[0].getHandValue(), dealerUpValue

            if action == "bust":
                break
            if action == "stand":
                lastAction = 2
                break
            elif action == "hit":
                lastAction = 1
                self.dealCard(self.player[0])
                # Update Q-Values
                if self.learning:
                    self.player[0].update(
                        lastState, 1,
                        (self.player[0].getHandValue(), dealerUpValue), None)
            elif action == "double":
                lastAction = 3
                self.double(self.player)
                # Update Q-Values
                if self.learning:
                    self.player[0].update(
                        lastState, 3,
                        (self.player[0].getHandValue(), dealerUpValue), None)
                break

        # Dealer actions
        while True:
            # Don't care about hard vs. soft values
            dealerValue = self.dealer.getHandValue()[0]
            dealerBlackjack = True if dealerValue == const.blackjack else False

            if not self.noPrint:
                print "\n"
                print "Dealer hand: " + " ".join(
                    [str(card) for card in self.dealer.getHand()])
                print "Dealer hand value: {0}".format(dealerValue)
                if dealerValue == const.blackjack:
                    print "Dealer has BLACKJACK"
                elif dealerValue > 21:
                    print "Dealer BUST"
                elif dealerValue >= 17:
                    print "Dealer STANDS on {0}".format(dealerValue)
                else:
                    print "Dealer HITS"

            # Dealer stands on 17 (stand on soft 17)
            if dealerValue == const.blackjack or dealerValue >= 17:
                break

            # Else hit
            self.dealCard(self.dealer)

        # Determine winnings
        playerValue = self.player[0].getHandValue()[0]
        playerBlackjack = True if playerValue == const.blackjack else False

        if not self.noPrint:
            print "\n"

        if playerValue == const.blackjack and dealerValue == const.blackjack:
            payout = self.player[1]
        elif playerValue == const.blackjack:
            payout = 5 * self.player[1] / 2
        elif dealerValue == const.blackjack or playerValue > 21:
            payout = 0
        elif dealerValue > 21 or playerValue > dealerValue:
            payout = 2 * self.player[1]
        elif playerValue == dealerValue:
            payout = self.player[1]
        else:
            payout = 0
        self.player[0].addMoney(payout)

        if not self.noPrint:
            if playerValue == const.blackjack and dealerValue == const.blackjack:
                print "Dealer got BLACKJACK and you got BLACKJACK\nPUSH"
            elif playerValue == const.blackjack:
                print "You got BLACKJACK\nYou win ${0}".format(
                    3 * self.player[1] / 2)
            elif dealerValue == const.blackjack:
                print "Dealer got BLACKJACK\nYou lose ${0}".format(
                    self.player[1])
            elif playerValue > 21:
                print "You BUST\nYou lose ${0}".format(self.player[1])
            elif dealerValue > 21:
                print "Dealer BUSTS\nYou win ${0}".format(self.player[1])
            elif playerValue > dealerValue:
                print "Dealer has value {0} and you have value {1}\nYou win ${2}".format(
                    dealerValue, playerValue, self.player[1])
            elif playerValue == dealerValue:
                print "Dealer has value {0} and you have value {1}\nPUSH".format(
                    dealerValue, playerValue)
            else:
                print "Dealer has value {0} and you have value {1}\nYou lose ${2}".format(
                    dealerValue, playerValue, self.player[1])

        reward = payout - self.player[1]
        result = self.player[0].roundEnd(reward, self.player[0].getHand(),
                                         self.dealer.getHand())
        if self.learning:
            self.player[0].update(
                lastState, lastAction,
                (self.player[0].getHandValue(), dealerUpValue), reward)

        # Clear cards
        self.player[0].discardHand()
        self.dealer.discardHand()

        # Reshuffle if needed:
        if self.reshuffle:
            if not self.noPrint: print "\n\nReshuffling!"
            self.deck.reshuffle()
            self.player[0].reshuffled()
            self.reshuffle = False

        return (True, 0)