Please help me with blackjack program!!

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kfansi
    New Member
    • Feb 2010
    • 3

    #1

    Please help me with blackjack program!!

    Hello everybody,
    I know I'm really new to the site, but I really need your help. I've been developing a blackjack game over the last few days and I'm a bit stuck know.

    If you guys could help me with a few things:
    1. For some reason, the game never allows you to win. I've checked my program multiple times, but I can't figure out why.
    2. Whenever I try to print the sum functions, I always get this odd message. Something like, "Instance of function at x93483".
    3. If you could help me make a running chip count through the program that also would be amazing.

    I've really worked very hard so far and I really just need this last bit of help!!

    Thank you!!

    Code:
    import random
    class Card:
        def __init__(self, suit, rank, value):
            self.rank = rank
            self.suit = suit
            self.value= value
            if self.rank == 1:
                self.rank = "Ace"
                self.value = 11
            elif self.rank == 11:
                self.rank = "Jack"
                self.value = 10
            elif self.rank == 12:
                self.rank = "Queen"
                self.value = 10
            elif self.rank == 13:
                self.rank = "King"
                self.value = 10
            elif 2 <= self.rank <= 10:
                self.value = self.rank
                self.rank = str(self.rank)
            if self.suit == 1:
                self.suit = "Clubs"
            if self.suit == 2:
                self.suit = "Spades"
            if self.suit == 3:
                self.suit = "Diamonds"
            if self.suit == 4:
                self.suit = "Hearts"
            self.cardname = self.rank + " of " + self.suit
    
    deck = []
    for suit in range(1,5):
        for rank in range(1,14):
            for value in range(2,12):
    
                deck.append(Card(suit,rank,value))
    
    class Player:
        def total(self):
            total = 100
            print "You have 100 chips"
            bet=raw_input("How many chips would you like to bet?")
            total= int(total)-int(bet)
            return total
            
        def bet(self):
            print "You have ", total, "chips. How many would you like to bet?"
            bet = raw_input()
            return bet
        
        def player_turn(self):
            hand = []
            for cards in range(0,2):
                a = random.choice(deck)
                hand.append(a)
                deck.remove(a)
    
            print "This is your hand:"
            for card in hand:
                print card.cardname
    
            print "Would you like to hit or stay?"
            response= raw_input("Type either 'hit' or 'stay'")
            
            while response =="hit":
                card=random.choice(deck)
                hand.append(card)
                deck.remove(card)
                print "Your next card is", card.cardname
                psum=0
                for i in hand:
                    psum=int(i.value) + psum
                if psum > 21:
                    break
                print "Would you like to hit or stay?"
                response = raw_input("Type either 'hit' or stay'")
                
                return psum
        
        def sum(self):
            sum=0
            for i in hand:
                sum= int(i.value)+sum
            return sum
        
        
            
    
    
    class Dealer:
    
        def computer_turn(self):
            dealerhand = []
            for cards in range(0,2):
                a = random.choice(deck)
                dealerhand.append(a)
                deck.remove(a)
            dsum = 0
            for i in dealerhand:
                dsum = int(i.value)+dsum
            while dsum < 17:
                card = random.choice(deck)
                dealerhand.append(card)
                deck.remove(card)
                dsum = int(card.value)+dsum
    
            return dsum
        
        def sum(self):
            sum=0
            for i in dealerhand:
                sum= int(i.value)+sum
            return sum
    
        
            
    print "Would you like to play?"
    answer = raw_input("'Yes' or 'No'")
    while answer == "Yes":
        p = Player()
        d = Dealer()
        p.total()
        p.player_turn()
        d.computer_turn()
        
      
        if p.sum > d.sum and p.sum <= 21:
            print "You won! Here is the dealer's score."
            print d.sum
        else:
            print "You lost. Here is the computer's score.", d.sum
        
        print "Would you like to play again?"
        answer = raw_input("'Yes' or 'No'")
  • bvdet
    Recognized Expert Specialist
    • Oct 2006
    • 2851

    #2
    One thing I noticed - In Player.player_t urn() the indentation is incorrect at return psum.

    Code:
                 if psum > 21:
                     break
    If True, the while loop will end and None will be returned by the method.

    You have a method named sum and you have an attribute named sum. They should be different. I would advise you to stay away from the names of built-in functions like sum. If you want to print the score, define it as an instance attribute something like this:
    Code:
        def sum_score(self):
            self.score = sum([int(i.value) for i in hand])
            # this next line is not necessary since you have defined an instance attribute
            return self.score
    
    p = Player()
    p.player_turn()
    p.sum_score()
    print p.score
    Make use of print statements embedded at strategic locations in your code for debugging. A lot of times you can immediately see a problem that was overlooked.

    Comment

    • kfansi
      New Member
      • Feb 2010
      • 3

      #3
      Ok I am ALMOST DONE with the blackjack program, but there are these two bugs that I dont understand at all!

      BUG #1:
      For some reason, the program will only let you hit twice. I think I set up the while statement right, and I've checked it and I think it makes sense, so what is the problem?

      Bug#2:
      Even if you bust, if the computer busts as well, it will always say you won. In real blackjack it shouldn't be like that. How can I fix that?


      Code:
      #We use this module to pick a random card from the deck.
      import random
      #We use this module to close the program once the player goes bankrupt.
      import sys
       
      #Makes a card and assigns suit. rank, and value.
      class Card:
          def __init__(self, suit, rank, value):
              self.rank = rank
              self.suit = suit
              self.value= value
              if self.rank == 1:
                  self.rank = "Ace"
                  self.value = 11
              elif self.rank == 11:
                  self.rank = "Jack"
                  self.value = 10
              elif self.rank == 12:
                  self.rank = "Queen"
                  self.value = 10
              elif self.rank == 13:
                  self.rank = "King"
                  self.value = 10
              elif 2 <= self.rank <= 10:
                  self.value = self.rank
                  self.rank = str(self.rank)
              if self.suit == 1:
                  self.suit = "Clubs"
              if self.suit == 2:
                  self.suit = "Spades"
              if self.suit == 3:
                  self.suit = "Diamonds"
              if self.suit == 4:
                  self.suit = "Hearts"
              self.cardname = self.rank + " of " + self.suit
      #Makes a deck of cards
      deck = []
      for suit in range(1,5):
          for rank in range(1,14):
              for value in range(2,12):
                  deck.append(Card(suit,rank,value))
      #Creates a Player
      class Player:
       
      #Makes a function so the player can play the game.  
          def player_turn(self):
      #Gives player two cards from the deck.
              self.hand = []
              for cards in range(0,2):
                  a = random.choice(deck)
                  self.hand.append(a)
                  deck.remove(a)
      #Prints the cards in hand.
              print "Here's your hand bud:"
              for card in self.hand:
                  print card.cardname
       
              print "Would you like to hit or stay?"
              response= raw_input("Type either 'hit' or 'stay'")
              while response.lower()!= "hit" and response.lower()!="stay":
                  response=raw_input("Type either 'hit' or 'stay'")
      #Gives the player another card if he/she decides to hit.      
              while response =="hit" or response == "Hit":
                  card=random.choice(deck)
                  self.hand.append(card)
                  deck.remove(card)
                  print "Here's your next card:", card.cardname
                  psum=0
       
      #Adds up the value of each card in the player's hand.
                  for i in self.hand:
                      psum=int(i.value) + psum
      #Makes the Ace have a value of 1, if the sum of the player's cards are greater than 21.
                  for i in self.hand:
                      if i.rank == 1 and p.Sum() > 21:
                          i.value = 1
       
                  if psum > 21:
                      break
                  print "Would you like to hit or stay?"
                  response = raw_input("Type either 'hit' or 'stay'")
                  while response.lower()!="hit" and response.lower()!="stay":
                      response = raw_input("Type either 'hit' or 'stay'")
                  return psum
       
       
      #Adds the values of each card in the player's hand.  
          def Sum(self):
              self.sum=0
              for i in self.hand:
                  self.sum= int(i.value)+self.sum
              return self.sum
       
       
       
       
      #Makes a dealer class.
      class Dealer:
      #(Same as the Player)
          def computer_turn(self):
              self.dealerhand = []
              for cards in range(0,2):
                  a = random.choice(deck)
                  self.dealerhand.append(a)
                  deck.remove(a)
              dsum = 0
              for i in self.dealerhand:
                  dsum = int(i.value)+dsum
      #Tells the dealer to hit if the dealer's score is less than 17.
              while dsum < 17:
                  card = random.choice(deck)
                  self.dealerhand.append(card)
                  deck.remove(card)
                  dsum = int(card.value)+dsum
       
              return dsum
       
          def Sum(self):
              self.sum=0
              for i in self.dealerhand:
                  self.sum= int(i.value)+self.sum
              return self.sum
       
       
       
       
      #Actual game      
      print "Would you like to play Blackjack, the best game in the whole wide world!"
      answer = raw_input("'Yes' or 'No'")
       
      #Makes sure the player types in either yes or no.(It can be typed in either capital or lowercase letters.)
      while answer.lower()!="yes" and answer.lower()!="no":
          answer = raw_input("'Yes' or 'No'")
      #Quits out of the game if the player doesn't want to play.
      if answer == 'No' or answer == 'no':
          sys.exit()
      #Gives the player a starting amount of 100 chips to bet with.
      total=100
      while answer == "Yes" or answer == "yes":
      #Creates a player and dealer object.
          p = Player()
          d = Dealer()
          print "You have", total, "chips"
      #Allows the player to place a bet.
          betting=raw_input("How many chips would you like to bet?")
      #Runs through both functions
          p.player_turn()
          d.computer_turn()
       
      #The conditions under which the player can win or lose.   
          if p.Sum() > d.Sum() and p.Sum() <= 21:
              print "Awww shucks! You beat me. This was my score: "
              print d.Sum()
      #Increases chip count by amount placed in bet.
              total=int(total)+int(betting)
              print "You now have", total, "chips"
       
          elif p.Sum()>21:
              print "You busted! Hahaha!"
              print d.Sum()
      #Decreases chip count by amount placed in bet.
              total=int(total)-int(betting)
              print "You now have", total, "chips"
       
          elif d.Sum()>21:
              print "Shoot! Shoot! Shoot! I busted! Damn it, you won."
              print "This was my score: "
              print d.Sum()
              total=int(total)+int(betting)
              print "You now have", total, "chips"
       
          elif p.Sum() == d.Sum():
              print "A draw."
       
          else:
              print "Ahahaha! Feel the wrath. I just beat you, you lil punk. Your score was", p.Sum(), "My score was:"
              print d.Sum()
              total=int(total)-int(betting)
              print "You now have", total, "chips"
       
      #Tells the player he/she is bankrupt and ends the game.      
          if total==0:
              print "YOU ARE BROKE! LOLOLOLOL!!!"
              sys.exit()
      #Restarts the  game      
          print "Let's play again, so I can win all of your chips!...Would you like to play again?"
          answer = raw_input("'Yes' or 'No'")
          while answer.lower()!="yes" and answer.lower()!="no":
              answer = raw_input("'Yes' or 'No'")
       
          if answer == 'No' or answer == 'no':
              sys.exit()

      Comment

      • bvdet
        Recognized Expert Specialist
        • Oct 2006
        • 2851

        #4
        kfansi,

        I played around with your blackjack game for several minutes, but I could not see anything wrong without adding some additional print statements. I will try to play with it some more later when I have time. It looks good. You must have spent considerable time on it. One suggestion - instead of encapsulating card "hits" in a while loop, encapsulate the play of the game in a "while True" loop and take action to the responses in an if/elif block.

        In the mean time, I have been playing around with a blackjack game of my own. I used an if/elif block to encapsulate card play.
        Code:
        import random
        
        class Card(object):
        
            suitList = ["Hearts", "Diamonds", "Clubs", "Spades"]
            rankList = ["Invalid", "Ace", "2", "3", "4", "5", "6",
                        "7", "8", "9", "10", "Jack", "Queen", "King"]
            scoreList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
           
            def __init__ (self, suit=0, rank=1):
                if suit < 0 or suit > 3:
                    raise AttributeError, "Suit out of range"
                if rank < 1 or rank > 13:
                    raise AttributeError, "Rank out of range"
                self.suit = suit
                self.rank = rank
                self.score = self.scoreList[self.rank]
                self.cname = self.rankList[self.rank]
                self.sname = self.suitList[self.suit]
        
            def __str__(self):
                return self.rankList[self.rank] + " of " + self.suitList[self.suit]
        
            def __repr__(self):
                return self.rankList[self.rank] + " of " + self.suitList[self.suit]
            
            def __cmp__(self, other):
                i = cmp(self.rank, other.rank)
                if i == 0:
                    return cmp(self.suit, other.suit)
                return i
        
        class Deck(object):
            def __init__(self):
                self.cards = []
                for suit in range(5):
                    for rank in range(1,14):
                        self.cards.append(Card(suit, rank))
        
            def __getitem__(self, i):
                return self.cards[i]
        
            def __iter__(self):
                for card in self.cards:
                    yield card
        
            def __len__(self):
                return len(self.cards)
        
            def __str__(self):
                return '\n'.join([str(c) for c in self])
        
            def __repr__(self):
                return str(self.cards)
        
        class BJ(object):
            
            dealer_hit_threshold = 16
        
            def __init__(self):
                '''
                Designed for 2 players. Player 2 is the dealer. Dealer wins a tie.
                There is a tie if both Player and Dealer are dealt a 'natural' or
                blackjack.
                
                Results are appended to self.results:
                [[winner, playerhand, dealerhand], [winner, playerhand, dealerhand]]
                Results are formatted for output.
                '''
                self.results = []
                self.deck = Deck()
        
            def deal_hand(self, n, deck):
                '''
                Randomly deal and remove n cards from a Deck object.
                '''
                hand = []
                if len(deck) >= n:
                    for i in range(n):
                        hand.append(deck.cards.pop(random.choice(range(len(deck)))))
                else:
                    print "There are not enough cards in the deck to deal %d cards." % n
                return hand
        
            def hit_hand(self, hand, deck):
                '''
                Append a card to hand from deck, removing the card from deck.
                '''
                if len(deck):
                    hand.append(deck.cards.pop(random.choice(range(len(deck)))))
                    return True
                else: return False
        
            def score_hand_BJ(self, hand):
                '''
                Tabulate the Blackjack score for hand.
                Adjust score automatically for an Ace.
                '''
                score = sum([card.score for card in hand])
                if 'Ace' in [card.cname for card in hand]:
                    if score <= 11:
                        score += 10
                return score
                
            def play(self):
                '''
                Play the game.
                '''
                playing = False
                while True:
                    option = raw_input("(D)eal, (H)it Me, (S)tand, (Q)uit")
                    if option.upper() == "D":
                        if playing:
                            print "You are already playing a hand!"
                        else:
                            if len(self.deck) < 4:
                                print
                                print "Appending new deck."
                                self.deck.cards.extend(Deck())
                            playing = True
                            hand1 = self.deal_hand(2, self.deck)
                            hand2 = self.deal_hand(2, self.deck)
                            print "Player 1 Hand: %s\nPlayer 2 Hand: %s" % \
                                  (','.join([str(c) for c in hand1]),
                                   ','.join(["**face down**",]+[str(c) for c in hand2[1:]]))
                            print "Player 1 Score: %s\nPlayer 2 Score: %s" % \
                                  (self.score_hand_BJ(hand1), '****')
                            # check for blackjack
                            if self.score_hand_BJ(hand1) == 21 and \
                               self.score_hand_BJ(hand2) == 21:
                                print "Player and Dealer were both dealt 'Blackjack' (tie)."
                                playing = False
                            elif self.score_hand_BJ(hand1) == 21:
                                print "Player was dealt 'Blackjack'. Player wins."
                                self.results.append(["Player", hand1, hand2])
                                playing = False
                                
                    elif option.upper() == "H":
                        if playing:
                            if not self.deck:
                                print "New deck."
                                self.deck = Deck()
                            self.hit_hand(hand1, self.deck)
                            print "Player took a HIT. Current HAND: %s Score: %s" % \
                                  (hand1, self.score_hand_BJ(hand1))
                            if self.score_hand_BJ(hand1) > 21:
                                print "Player BUSTS. Dealer wins."
                                self.results.append(["Dealer", hand1, hand2])
                                playing = False
                                print
                        else:
                            print "You must DEAL before taking a HIT"
        
                    elif option.upper() == "S":
                        if playing:
                            print
                            print "Dealer HAND: %s SCORE: %s" % (hand2, self.score_hand_BJ(hand2))
                            while self.score_hand_BJ(hand2) <= BJ.dealer_hit_threshold and \
                                  self.score_hand_BJ(hand2) < self.score_hand_BJ(hand1):
                                if not self.deck:
                                    print "New deck."
                                    self.deck = Deck()
                                else:
                                    self.hit_hand(hand2, self.deck)
                                    print "Dealer took a HIT. Current HAND: %s Score: %s" % \
                                          (hand2, self.score_hand_BJ(hand2))
                                    if self.score_hand_BJ(hand2) > 21:
                                        print "Dealer BUSTS. Player wins."
                                        self.results.append(["Player", hand1, hand2])
                                        playing = False
                                        print
                            if playing:
                                if self.score_hand_BJ(hand1) > self.score_hand_BJ(hand2):
                                    print "PLAYER wins this hand.",
                                    print "Score: %s to %s" % (self.score_hand_BJ(hand1),
                                                               self.score_hand_BJ(hand2))
                                    self.results.append(["Player", hand1, hand2])
                                else:
                                    print "DEALER wins this hand.",
                                    print "Score: %s to %s" % (self.score_hand_BJ(hand1),
                                                               self.score_hand_BJ(hand2))
                                    self.results.append(["Dealer", hand1, hand2])
                        else:
                            print "You must DEAL before selecting option to STAND."
                        playing = False
                        print
        
                    elif option.upper() == "Q":
                        self.play_over()
                        return
        
            def play_over(self):
                '''
                Summarize the game results and display.
                '''
                dd = dict.fromkeys(["Player", "Dealer"], 0)
                for hand in self.results:
                    dd[hand[0]] += 1
                playerwins = dd["Player"]
                dealerwins = dd["Dealer"]
                if playerwins > dealerwins:
                    resultList = ["", "Player won %d hand%s to %d." % \
                                  (playerwins, ["", "s"][playerwins>1 or 0], dealerwins)]
                elif playerwins == dealerwins:
                    resultList = ["There was a tie %d hand%s to %d." % \
                                  (playerwins, ["", "s"][playerwins>1 or 0], dealerwins)]
                else:
                    resultList = ["Dealer won %d hand%s to %d." % \
                                  (dealerwins, ["", "s"][dealerwins>1 or 0], playerwins)]
                resultList.append("Hands Played:")
                if self.results:
                    for i, hand in enumerate(self.results):
                        resultList.append("Hand %d:\n  Player %d: %s\n  Dealer %d: %s\n" % \
                                          (i+1, self.score_hand_BJ(hand[1]),
                                           ", ".join([str(c) for c in hand[1]]),
                                           self.score_hand_BJ(hand[2]),
                                           ", ".join([str(c) for c in hand[2]])))
                else:
                    resultList.append("No hands were played")
                print '\n'.join(resultList)
        
        if __name__ == "__main__":
            g = BJ()
            g.play()

        Comment

        • Glenton
          Recognized Expert Contributor
          • Nov 2008
          • 391

          #5
          So totally random point but here is how to get the suit symbols in unicode!

          ♠ ♡ ♢ ♣ just seems classy somehow...

          (unless you can't read it of course...)

          Comment

          • kfansi
            New Member
            • Feb 2010
            • 3

            #6
            Your program looks really good bvdet. Interesting way to go about it. I realized what the last real bug in the program is. The ace never equals one. I have an if statement inside a for statement which I thought fixed the problem, but it didn't. If you have a line of code that would fix it that'd be great.

            Comment

            • bvdet
              Recognized Expert Specialist
              • Oct 2006
              • 2851

              #7
              My code considers the value of an Ace to be 1. When I tabulate the score of a hand, the code automatically adds 10 to the score if the current score is 11 or less.

              Code:
                  def score_hand_BJ(self, hand):
                      '''
                      Tabulate the Blackjack score for hand.
                      Adjust score automatically for an Ace.
                      '''
                      score = sum([card.score for card in hand])
                      if 'Ace' in [card.cname for card in hand]:
                          if score <= 11:
                              score += 10
                      return score

              Comment

              Working...