My most complex program yet!(in python)(im a noob) Questions regarding it.

Started by
4 comments, last by HeyHoHey 16 years, 9 months ago
okay im learning out of a book, this chapter was on simulation/design. an programming practice problem was to design a game of black jack. here is my attempt so far. one thing i would like to do is to get it so i alternate between the user and dealers cards being dealt. i dont know how to do it so i can do one after the other. im pretty confident my program works in getting the job done even though it probably is not pretty. im sure its messy too. feel free and plz comment on how i can improve my code/design/everything. thanks hey ho hey heres the code sorry if its really messy/confusing


from random import randrange
from random import random


def main():
    printIntro()
    playerScore = 0
    dealerScore = 0
    dealerCard = 1 # for dealer loop
    CardValue = 0  # for figuring out aces/blackjack
    black = ""
    jack = ""
    decision = "H"
    firstTime = 1
    autoWin = 0

    # loop for dealer getting deal cards/ goes until the dealer is done getting cards(score is 17 or more(dealerCard is set to zero))

    while dealerCard != 0:
        # prints dealers score at beginning of loop
        if dealerScore > 0:
            print "The dealer has a score of", dealerScore
            print 
        #deals cards to dealer
        dealerCard = dealDealerHand()

        # Dealer deal info
        # ace decision of 1 or 11 for dealer
        if dealerCard == 1 and ((dealerScore + 11) <= 21):
            dealerCard = 11
        elif dealerCard == 1 and ((dealerScore + 11) > 21):
            dealerCard = 1
        # when dealer will continue or stay or busts
        if dealerScore >= 17 and dealerScore <= 21:
            dealerCard = 0
            print "The dealer has a score of", dealerScore, "he has decided to stay."
        elif dealerScore > 21:
            print "The dealer has busted you win!"
            dealerCard = -1  # if dealer busts this will be used to tell next loop not to start
            break
          
        # dealer Score accumulator adds score + new card dealt
        dealerScore = dealerScore + dealerCard

        # if dealer gets 21 he automatically wins
        if dealerScore == 21:
            print "The dealer got 21, and the dealer wins all ties. Since 21 is the max thats game over."
            autoWin = -1
            break

    

    # user loop
    while decision[0] == "H" or decision[0] == "h":
        # this tells loop to stop if dealer busted
        if dealerCard == -1:
            break
        elif autoWin == -1:
            break


        # print now its ur turn only on first loop
        if firstTime == 1:
            print "Now its your turn..."
            firstTime = 0
        elif firstTime == 0:
            print 
        

       
        
   
        


        #deals cards to user
        Card = dealUserHand()
      

        # If user gets an ace(1 or 11) this allows them to choose what they want the value to be
        if Card == 1 or Card == 11:
            print "You got an ace! It can count for either 1 or 11."
            CardValue = input("What would you like it to count as? 1 or 11?")
            if CardValue == 1:
                Card = 1
            elif CardValue == 11:
                Card = 11
            else:
                print "Wrong input sorry, only 1 or 11 were choices"
                print "Quitting out now."
                break
            
        # defines blackjack for user
        if CardValue == 11:
            black = "black"
            if jack == "jack" and playerScore == 21:
                print "YOU GOT BLACK JACK!!!![an ace and a face card]"
        elif Card == 10:
            jack = "jack"
            if black == "black" and playerScore == 21:
                print "YOU GOT BLACK JACK!!!![an ace and a face card]"
                
        # determines what kind of face card user gets if randrange card is a 10 
        if Card == 10:
            whatFaceCard = random()
            if whatFaceCard < .35:
                print "You got a face card, its a Jack!(worth 10)"
            elif whatFaceCard >= .35 and whatFaceCard < .66:
                print "You got a face card, its a Queen!(worth 10)"
            elif whatFaceCard >= .66:
                print "You got a face card, its a King!(worth 10)"

        # player score accumulator adds score + new card dealt then prints it out
        playerScore = Card + playerScore
        print "You have", playerScore

        # defines bust for player
        if playerScore > 21:
            print "Sorry you busted!"
            break


        # at end of loop this value determines once the while loop starts again whether it will go again(true) or stop(false)
        decision = getDecision()

    # determines who wins the game
    if autoWin != -1 or dealerCard != -1:
        if playerScore > dealerScore and playerScore <= 21:
            print "You won the hand congradulations!!!!"
        elif dealerScore > playerScore and dealerScore <= 21:
            print "The dealer won. :'( Sorry, your welcome to try again!"
        elif dealerScore == playerScore and playerScore <= 21:
            print "AWWW so close. :'( You tied the dealer! But, the dealer wins all ties sorry. :("
    
        









def printIntro():
    print "Welcome, this game allows the user to play black jack."
def getDecision():
    decision = raw_input("Do you want a hit or do you want to stay?")
    return decision

def dealDealerHand():
    dealerScore = 0

    dealerScore = dealOneCard()
    return dealerScore

def dealUserHand():
    playerScore = 0

    playerScore = dealOneCard()
    return playerScore

def dealOneCard():
    dealCard = randrange(1, 11)
    return dealCard





[Edited by - HeyHoHey on July 7, 2007 3:26:38 AM]
Advertisement
Quote:Original post by HeyHoHey
one thing i would like to do is to get it so i alternate between the user and dealers cards being dealt.


But that's not how blackjack works. (A very important lesson here: before you can model something, you have to know how it's supposed to work :) ) The player is supposed to go first (until s/he is satisfied) and then the dealer goes. There's no need to handle 21 as a special case, BTW. Also, you should give both players two cards to start.

Anyway:

- You can import multiple symbols from a module in one line: 'from random import random, randrange'.

- Dealing a card to a dealer and dealing it to the player are fundamentally the same, so there's no reason to make separate functions.

- Use operators like '+=' to save typing. 'x += y' is equivalent to 'x = x + y'.

- Think carefully about your function names. If you need a comment to explain what a variable is for, then the problem is really with the name.

- I can't figure out what you're trying to do with those 'black' and 'jack' variables. The counting logic for blackjack is very simple. Card values actually range 1 to 10, and if any 1s were dealt to a hand, one of them can count as 11. There is never any need to "decide" whether an ace counts as 1 or 11, because this decision is allowed to change later, anyway.

What you do is, model a card total with two variables: a sum of "ordinary" values, and an indication (this can just be boolean, for example) of whether there is an ace in the hand. Here we have an example of something we can model with a class: the "value" is something we *calculate* out of the pair of variables, and we want those two things to be "bound" to each other. A class gives us a logical way to wrap them up, and a class method lets us implement the totalling logic, as well as dealing logic.

class Hand:  def __init__(self):    self.hasAce = False    self.baseTotal = 0    # This is also the proper spot to handle our rule    # "every hand has at least two cards".    self.addCard()    self.addCard()  def addCard(self):    # Ask the deck for a card. By the way, later you'll want a proper model    # for the deck :)    card = randrange(1, 10)    if card == 1: self.hasAce = True    self.baseTotal += card  def total(self):    # Decide whether we can count an ace as 11 without going over, and    # do so if possible.    if self.hasAce and (self.baseTotal < 11):      return self.baseTotal + 10    else:      return self.baseTotal # can't count any aces.# Now we can initialize the player and dealer:player = Hand()dealer = Hand()


- Making a decision about what face card you got doesn't really add information: if you want to model the deck, then model the deck. (Also, a real deck of cards contains tens, which are not face cards; the code currently doesn't allow for that.)



# SPOILERS - a full program (scroll down), though it doesn't print all the# interesting messages of the original - just enough to be able to play.from random import randrange # I'm not using 'random'.class Hand:  def __init__(self):    self.hasAce = False    self.baseTotal = 0    # This is also the proper spot to handle our rule    # "every hand has at least two cards".    self.addCard()    self.addCard()  def addCard(self):    # Ask the deck for a card. By the way, later you'll want a proper model    # for the deck :)    card = randrange(1, 10)    if card == 1: self.hasAce = True    self.baseTotal += card  def total(self):    # Decide whether we can count an ace as 11 without going over, and    # do so if possible.    if self.hasAce and (self.baseTotal < 11):      return self.baseTotal + 10    else:      return self.baseTotal # can't count any aces.def userWantsToHit():  while True:    request = raw_input("(H)it or (S)tay:")    # We'll look at the first letter, for simplicity.    letter = request[0].upper()    if letter == 'H': return True    if letter == 'S': return False    print "Please enter either 'H' or 'S' (no quotes)." # try againdef main():  player = Hand()  dealer = Hand()  while player.total() < 21: # don't allow the user to hit on 21 ;)    print "Your total is", player.total()    if userWantsToHit(): player.addCard()    else: break  # Now that we have the player's final result, we'll save it in a variable  # so we don't have to keep calling the function.  ptotal = player.total()  if ptotal > 21:    print "You busted, you lose."    return # the dealer does not have to play in this case.  while dealer.total() < 17: # the dealer must hit on 16 and under    dealer.addCard()  dtotal = dealer.total()  if dtotal > 21:    print "Dealer busted, you win."  else:    # Noone busted, so we have to compare the hands.    print "Dealer: %s You: %s" % (dtotal, ptotal)    if dtotal > ptotal:      print "Dealer wins."    elif ptotal > dtotal:      print "You win."    else:      print "It's a push" # Tie; bet carries forward to next hand.
thank you very much for taking the time to look at my program. your post was very helpful :P. im gonna work on fixing my program now. heh yea my knowledge of black jack was iffy ty for that info. :) i forgot about 10 cards then also face cards. with the knowledge you have given me for the next thing i make hopefully it will be better. oh and btw the next chapter is the one on classes.(im just starting to read it. so after i finish it then i can understand your program a little better but i get the general idea right now)


thanks

hey ho

p.s. thanks for that fully fuctional program im walking myself through it right now and its a ton simplier then mine and works better. i think i tried to make mine to complex with face cards and then trying to display each card including the first two for both the dealer and the user. thanks a ton for that example program.

oh and also i got one question i was playing with the black jack for a bunch of times and one of the times i hit and i got -2 or something. wondering how that happened cause i just looked at all your code and it looks perfect.(ton better then mine) this game worked flawlessley many times only on the last time did this happen.
>>> main()Your total is 16(H)it or (S)tay:hitYour total is 14(H)it or (S)tay:hitYou busted, you lose.>>> 


[Edited by - HeyHoHey on July 7, 2007 1:30:30 PM]
You had an 11 and a 5 and then you hit and received an 8. Because 11+5+8 is greater than 21, the 11 fell down to a 1 and you then had a total of 14.

That is, at least if the code you were testing is using that strategy.
James
Quote:Original post by JBS103
You had an 11 and a 5 and then you hit and received an 8. Because 11+5+8 is greater than 21, the 11 fell down to a 1 and you then had a total of 14.

That is, at least if the code you were testing is using that strategy.


That would be it, yes. Please re-read what I said about how aces are supposed to work in blackjack. :)
Quote:Original post by Zahlman
Quote:Original post by JBS103
You had an 11 and a 5 and then you hit and received an 8. Because 11+5+8 is greater than 21, the 11 fell down to a 1 and you then had a total of 14.

That is, at least if the code you were testing is using that strategy.


That would be it, yes. Please re-read what I said about how aces are supposed to work in blackjack. :)


doohhh oh yea my mistake. sorry about that lol.


hey ho hey

This topic is closed to new replies.

Advertisement