1
\$\begingroup\$

Like the title says, I made a very simple game of Blackjack using Python version 2.6.9. I am relatively new to python and programming so I would really appreciate some constructive criticism to help me improve.

from random import shuffle #this imports shuffle which shuffles the deck
deck = list('234567890JQKA'*4)
for shu in range(0,3):
 shuffle(deck)
value = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8,
 '9':9, '0':10, 'J':10, 'Q':10, 'K':10, 'A':1} # Creates the shuffled deck
player = [deck.pop() for _ in range(2)]
AI = [deck.pop() for _ in range(2)] # Deals the cards to the players
stay = False
def player_game():
 global stay
 print "Your hand: %s" % player
 hit = raw_input("Hit or Stay? ")
 if hit == "Hit":
 player.append(deck.pop())
 elif hit == "Stay":
 stay = True
 return stay
 else:
 print "I'm sorry. you need to input 'Hit or Stay'."
while 1:
 player_game()
 total = sum(map(value.get, player, AI))
 if total > 21:
 print "Hand: %s" % player
 print "You busted with a score of: %s" % total
 break
 elif total == 21:
 print player
 print "You win!"
 break
 if stay == True:
 print "You stayed."
 print "Final score: %s" % total
 break
200_success
146k22 gold badges190 silver badges479 bronze badges
asked Jul 28, 2017 at 18:21
\$\endgroup\$
1
  • \$\begingroup\$ Why do you use such an old Python version? I think we're at a point where no beginner should start with something else than the most recent version (3.6) or if you really want to learn Python 2 then use at least Python 2.7.13. \$\endgroup\$ Commented Jul 30, 2017 at 14:17

3 Answers 3

1
\$\begingroup\$

It is common practice to shorten statements like

if stay == True:

down to

if stay:

This'll make your code easier to read (more English-like).

answered Jul 28, 2017 at 18:58
\$\endgroup\$
1
\$\begingroup\$
from random import shuffle #this imports shuffle which shuffles the deck

The comment isn't really necessary. I wouldn't worry too often about explain imports upfront. I would explain the functions when you use them. In this case, however:

shuffle(deck)

Is fairly self explanitory.

for shu in range(0,3):

As you never use shu, by convention you would use _ instead. More importantly, I'm not exactly sure what you hope to get out of shuffling the deck three times. I think once is probably enough.

Using global is usually bad practice. You can use the return value of play_game to get around this. (I'll leave that as an exercise.)

I would change while 1: to while True:. Although they do the same thing True is considered better style in at least Python.

answered Jul 28, 2017 at 22:16
\$\endgroup\$
1
  • \$\begingroup\$ Would you mind explaining more of how I can use the return value of 'player_game'? I have tried playing around with it and can't seem to fix the problem without using 'global'. \$\endgroup\$ Commented Jul 29, 2017 at 15:59
0
\$\begingroup\$

The program looks pretty good, but the main thing that should be changed is the global variable stay. Global variables should mostly be avoided, since they make code harder to understand and maintain. I'd only get the input in the player_game function and return True or False if the user wants to stay or hit, and then assign this returned value to the stay variable.


Then there's a big problem with your total = sum(map(value.get, player, ai)) line. You're passing the ai cards as default values to value.get. That means if the player has a invalid card that doesn't exist in the value dict, it adds the ai card instead. I think it's not possible to have invalid cards, so you can just change the line to total = sum(VALUE[card] for card in player) (that's a generator expression that we pass to sum. It's similar to a list comprehension, but is evaluated lazily).


Regarding string formatting, in your simple cases you don't need it: print("Your hand:", player), but I also recommend to take a look at the new style string formatting "Your hand: {}".format(player) and if you switch to Python 3.6 the new f-strings f"Your hand: {player}".

I've made some changes to the program and added comments.

# This allows you to use Python 3's print function in
# Python 2, so that the program is more compatible.
from __future__ import print_function
from random import shuffle
# Maps the card strings to integer values. This dict should stay
# constant (won't get changed), therefore we use a uppercase name.
# That just tells other programmers that they shouldn't modify this dict.
VALUE = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8,
 '9':9, '0':10, 'J':10, 'Q':10, 'K':10, 'A':1}
def player_input():
 """Return True for stay and False for hit."""
 # A while loop is needed here, if the user inputs something invalid.
 while True:
 # Convert input to lower case to be more user friendly.
 hit = raw_input("(H)it or (s)tay? ").lower()
 # We can also allow `h` or `s` as input.
 if hit in ("hit", "h"):
 return False # Assign this to the `stay` variable in `main`.
 elif hit in ("stay", "s"):
 return True # Assign this to the `stay` variable in `main`.
 else:
 print("I'm sorry. you need to input '(h)it or (s)tay'.")
# Put everything into a main function except the global constants.
def main():
 deck = list('234567890JQKA'*4)
 # If the variable isn't needed we usually use `_` as
 # a throwaway variable. `range(3)` is the same as `range(0, 3)`.
 # for _ in range(3): # Shuffling 3 times is pointless.
 shuffle(deck)
 # Deals the cards to the players.
 player = [deck.pop() for _ in range(2)]
 # Uppercase names are for constants.
 ai = [deck.pop() for _ in range(2)]
 while True: # `while 1:` is outdated.
 print("Your hand:", player)
 stay = player_input()
 if not stay:
 player.append(deck.pop())
 total = sum(VALUE[card] for card in player)
 if total > 21:
 print("Hand:", player)
 print("You busted with a score of:", total)
 break
 elif total == 21:
 print("Hand:", player)
 print("You win!")
 break
 elif stay: # == True: isn't needed.
 print("You stayed.")
 print("Final score:", total)
 break
# This makes sure that the program doesn't run
# if it gets imported.
if __name__ == '__main__':
 main()
answered Jul 30, 2017 at 15:52
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.