By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,907 Members | 2,031 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,907 IT Pros & Developers. It's quick & easy.

blackjack

P: 64
hi, i am making black jack code, but i am stuck, i have made start, but for reason gettin errors, which i dont seem be able to fix, below is my code wht i started.

Expand|Select|Wrap|Line Numbers
  1. import random 
  2.  
  3. deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10,11]*4
  4. player=[]
  5. computer=[]
  6. #r = random.randint
  7.  
  8. computer.append(random.randint(deck))
  9. player.append(random.randint(deck))
  10. computer.append(random.randint(deck))
  11. print " The computer hand %d " % computer 
  12. player.append(random.randint(deck))
  13. print " The player hand %d" % player
  14.  
the error which i am getting is:

Traceback (most recent call last):
File "C:\Users\imran\Desktop\jack.py", line 31, in ?
computer.append(random.randint(deck))
TypeError: randint() takes exactly 3 arguments (2 given)
Jan 15 '09 #1
Share this Question
Share on Google+
21 Replies


boxfish
Expert 100+
P: 469
random.randint takes two numbers as arguments and returns a random number that's between them. I think what you're looking for is random.choice, which selects a random item from a list:
Expand|Select|Wrap|Line Numbers
  1. computer.append(random.choice(deck))
Another possibility is to actually shuffle the deck with random.shuffle before dealing cards:
Expand|Select|Wrap|Line Numbers
  1. random.shuffle(deck)
  2. computer.append(deck[0])
  3. player.append(deck[1])
  4. computer.append(deck[2])
Hope this helps.
Jan 16 '09 #2

P: 64
ok thanks no i dont have no erros,, but how would i display the players hand, computers hand.

below is how the code looks now, but, would have to keep the code commeted out, as that think would display the, hands.

thanks for help

Expand|Select|Wrap|Line Numbers
  1. import random 
  2.  
  3. deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10,11]*4
  4. player=[]
  5. computer=[]
  6. random.shuffle(deck) 
  7. computer.append(deck[0]) 
  8. player.append(deck[1])
  9. computer.append(deck[2])
  10.  
  11. ##computer.append(random.choice(deck)) 
  12. ##player.append(random.choice(deck))
  13. ##
  14. ##computer.append(random.choice(deck))
  15. ##print " The computer hand %d " % computer 
  16. ##
  17. ##player.append(random.choice(deck))
  18. ##print " The player hand %d" % player
Jan 16 '09 #3

P: 64
thanks for ur help before "boxfish" , i was able, proceed and pretty much complete my blackjack code. however, i have come across a minor problem, my hit function does not seem to work. do you know how i can fix this. also, does anyone know how i can fit a re-run code into my program too?

Expand|Select|Wrap|Line Numbers
  1. import random 
  2.  
  3. deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]
  4. player=[]
  5. computer=[]
  6. random.shuffle(deck)
  7. player.append(deck[0]) 
  8. player.append(deck[1])
  9. computer.append(deck[2])
  10. computer.append(deck[3])
  11. playerstotal = player [0]
  12. playerstotal2 = player [1]
  13. ptotal = playerstotal + playerstotal2
  14. comptotal = computer [0]
  15. comptotal2 = computer [1]
  16. ctotal = comptotal + comptotal2
  17. print "players hand", player
  18. print ptotal
  19. print "computers hand", computer
  20. print ctotal
  21.  
  22. def game():
  23.     options = raw_input ("do you wana [h]it / [s]tand / [q]uit: ")
  24.     while options == 'h':
  25.         player.append
  26.         print ptotal
  27.         break
  28.     while options == 's':
  29.         print "players hand", player
  30.         print ptotal
  31.         break
  32.  
  33.     if ctotal < 16:
  34.         computer.append
  35.  
  36.     if ptotal > 21:
  37.         print "player busted. computer wins"
  38.     if ctotal > 21:
  39.         print "computer busted. player wins"
  40.     if ctotal == ptotal:
  41.         print "draw. computer wins"
  42.     if ptotal == 21:
  43.         print "player gets a BlackJack. player wins"
  44.     if ctotal == 21:
  45.         print "computer gets a BlackJack. computer wins"
  46.     if ptotal > ctotal:
  47.         if ptotal < 21:
  48.             print "player wins"
  49.     if ctotal > ptotal:
  50.         if ctotal < 21:
  51.             print "computer wins"
  52.  
  53.     while options == 'q':
  54.         print "hope you enjoyed the game, bye!!"
  55.         break 
  56.  
  57. game()
  58.  
  59.  
thanks, appreciate the help.
Jan 16 '09 #4

boxfish
Expert 100+
P: 469
The line in your hit function,
player.append
does nothing. You need to specify something to append, which means you need a way of keeping track of which card must be dealt next. One way to do this is to delete cards from the deck as you deal them, like this,
Expand|Select|Wrap|Line Numbers
  1. player.append(deck[0])
  2. del deck[0] 
  3. player.append(deck[0]) # When you delete the first card, deck[1] becomes deck[0]
  4. del deck[0]
  5. computer.append(deck[0])
  6. del deck[0]
  7. computer.append(deck[0])
  8. del deck[0]
so that the next card to be dealt is always deck[0].
Another possibility is to store the index of the next card to be dealt in a variable:
Expand|Select|Wrap|Line Numbers
  1. nextCard = 0
  2. player.append(deck[nextCard])
  3. nextCard += 1
  4.  player.append(deck[nextCard]) # nextCard is now 1.
  5. nextCard += 1
  6.  computer.append(deck[nextCard])
  7.  nextCard += 1
  8.  computer.append(deck[nextCard])
  9.  nextCard += 1
I think you need to calculate ptotal every time the player gets a new card and calculate ctotal every time the computer gets a new card. Calculating them just once at the beginning of the game won't work.

I hope this is helpful, although your program will still need more work after you fix these problems.
Jan 16 '09 #5

P: 64
i have tried the second option, but does not seem to work.


Expand|Select|Wrap|Line Numbers
  1. import random 
  2.  
  3. deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]
  4. player=[]
  5. computer=[]
  6. random.shuffle(deck)  #this will shuffle the cards in the deck
  7. nextCard = 0
  8. player.append(deck[nextCard]) 
  9. nextCard += 1 
  10. player.append(deck[nextCard]) # nextCard is now 1. 
  11. nextCard += 1 
  12. computer.append(deck[nextCard]) 
  13. nextCard += 1 
  14. computer.append(deck[nextCard]) 
  15. nextCard += 1 
  16. playerstotal = player [0]
  17. playerstotal2 = player [1]
  18. ptotal = playerstotal + playerstotal2   #this (ptotal) is the players overall total
  19. comptotal = computer [0]
  20. comptotal2 = computer [1]
  21. ctotal = comptotal + comptotal2         #this (ctotal) is the computers overall total
  22. print "players hand", player, "\tplayers total value", ptotal   #this will display the players hand
  23.  
  24. #hit or stand,are players options.
  25. def game():
  26.     options = raw_input ("do you wana [h]it / [s]tand / [q]uit: ")
  27.     while options == 'h':       
  28.         player.append(deck[nextCard]) 
  29.         nextCard += 1 
  30.         print ptotal
  31.         break
  32.     while options == 's':
  33.         print "players hand", player
  34.         print ptotal
  35.         break
  36.  
  37.     if ctotal < 16:
  38.         computer.append(deck[nextCard])
  39.         nextCard += 1
  40.     if ptotal > 21:
  41.         print "player busted. computer wins"
  42.     if ctotal > 21:
  43.         print "computer busted. player wins"
  44.     if ctotal == ptotal:
  45.         print "draw. computer wins"
  46.     if ptotal == 21:
  47.         print "player gets a BlackJack. player wins"
  48.     if ctotal == 21:
  49.         print "computer gets a BlackJack. computer wins"
  50.     if ptotal > ctotal:
  51.         if ptotal < 21:
  52.             print "player wins"
  53.     if ctotal > ptotal:
  54.         if ctotal < 21:
  55.             print "computer wins"
  56.  
  57.     while options == 'q':
  58.         print "hope you enjoyed the game, bye!!"
  59.         break 
  60.  
  61. game()
Jan 16 '09 #6

bvdet
Expert Mod 2.5K+
P: 2,851
You can deal cards from a deck with one statement using random.choice() and list method pop().
Example:
Expand|Select|Wrap|Line Numbers
  1. >>> hand = []
  2. >>> deck = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
  3. >>> import random
  4. >>> hand.append(deck.pop(random.choice(range(len(deck)))))
  5. >>> hand
  6. [10]
  7. >>> deck
  8. ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10]
Notice one of the 10's has been removed from the deck.

You can score aces as 1 or 11 using a function like this:
Expand|Select|Wrap|Line Numbers
  1. def hand_score(hand):
  2.     score = sum([card for card in hand if isinstance(card, int)])
  3.     aces = [card for card in hand if isinstance(card, str)]
  4.     score += len(aces)
  5.     for ace in aces:
  6.         if score < 12:
  7.             score += 10
  8.     return score
The function sums all the numbers and assigns the value to variable score. Then a 1 is added to score for each ace. A for loop adds 10 to score for each ace if the current value of score is less than 12. Example:
Expand|Select|Wrap|Line Numbers
  1. >>> hand_score([6,7,'A'])
  2. 14
  3. >>> hand_score(['A', 'A', 'A', 3, 4])
  4. 20
  5. >>> hand_score([10, 'A'])
  6. 21
  7. >>> hand_score([10, 'A', 'A'])
  8. 12
  9. >>> 
HTH
Jan 16 '09 #7

P: 64
thanks for your post, which may be helpful for other parts of my code, however my main problem is getting the "hit" function to work, as it is not working at the moment. have a look previous posts in this thread, and then could you be able to help me fix the "hit"?

thanks once again.
Jan 16 '09 #8

bvdet
Expert Mod 2.5K+
P: 2,851
What error message did you receive? When I run your code, I get this error:
UnboundLocalError: local variable 'nextCard' referenced before assignment

This should solve that problem:
Expand|Select|Wrap|Line Numbers
  1. def game():
  2.     global nextCard # I added this statement
  3.     while True:
  4.         options = raw_input ("do you wana [h]it / [s]tand / [q]uit: ")
Instead of using while statements, I suggest using an if/elif/else block for the user options.
Expand|Select|Wrap|Line Numbers
  1.         if options == 'h':       
  2.             player.append(deck[nextCard]) 
  3.             nextCard += 1 
  4.             print ptotal
  5.  
  6.         elif options == 's':
  7.             print "players hand", player
  8.             print ptotal
  9.  
  10.         elif options == 'q':
  11.             print "hope you enjoyed the game, bye!!"
  12.             return
Jan 16 '09 #9

P: 64
I added in what you told me to bvdet, and i get no errors, but when i 'hit', another card is not dealt and it still comes up with the previous total.

here is my code now:

Expand|Select|Wrap|Line Numbers
  1. import random 
  2.  
  3. deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]
  4. player=[]
  5. computer=[]
  6. random.shuffle(deck)  #this will shuffle the cards in the deck
  7. nextCard = 0
  8. player.append(deck[nextCard]) 
  9. nextCard += 1 
  10. player.append(deck[nextCard]) # nextCard is now 1. 
  11. nextCard += 1 
  12. computer.append(deck[nextCard]) 
  13. nextCard += 1 
  14. computer.append(deck[nextCard]) 
  15. nextCard += 1 
  16. playerstotal = player [0]
  17. playerstotal2 = player [1]
  18. ptotal = playerstotal + playerstotal2   #this (ptotal) is the players overall total
  19. comptotal = computer [0]
  20. comptotal2 = computer [1]
  21. ctotal = comptotal + comptotal2         #this (ctotal) is the computers overall total
  22. print "players hand", player, "\tplayers total value", ptotal   #this will display the players hand
  23.  
  24. #hit or stand,are players options.
  25. def game():
  26.     global nextCard
  27.     while (True):
  28.         options = raw_input ("do you wana [h]it / [s]tand / [q]uit: ")
  29.         if options == 'h':
  30.             player.append(deck[nextCard]) 
  31.             nextCard += 1 
  32.             print ptotal
  33.             #break
  34.         elif options == 's':
  35.             print "players hand", player
  36.             print ptotal
  37.             #break
  38.         elif options == 'q':
  39.             print "hope you enjoyed the game, bye!!"
  40.             return
  41.             #break 
  42.  
  43.         if ctotal < 16:
  44.             computer.append(deck[nextCard])
  45.             nextCard += 1
  46.         if ptotal > 21:
  47.             print "player busted. computer wins"
  48.         if ctotal > 21:
  49.             print "computer busted. player wins"
  50.         if ctotal == ptotal:
  51.             print "draw. computer wins"
  52.         if ptotal == 21:
  53.             print "player gets a BlackJack. player wins"
  54.         if ctotal == 21:
  55.             print "computer gets a BlackJack. computer wins"
  56.         if ptotal > ctotal:
  57.             if ptotal < 21:
  58.                 print "player wins"
  59.         if ctotal > ptotal:
  60.             if ctotal < 21:
  61.                 print "computer wins"
  62.  
  63. game()
here is what happens when i run the game:

Expand|Select|Wrap|Line Numbers
  1. Y [yes] to view the rules , N [no]to start the game:n
  2. start game
  3. players hand [8, 4]  players total value 12
  4. do you wana [h]it / [s]tand / [q]uit: h
  5. 12
  6. computer wins
  7. do you wana [h]it / [s]tand / [q]uit: 
Jan 17 '09 #10

bvdet
Expert Mod 2.5K+
P: 2,851
A "card" is appended to list object player, but you are not updating the player's score. If the initial two cards are [6,7], the score would be sum([6,7]) = 13. If the player's hand is hit with a 3, the score would be sum([6,7,3]) = 16.
Jan 17 '09 #11

P: 64
ok so it is not updating because the total itself is not updating. do you know how i can change it so the total updates?

thanks.
Jan 17 '09 #12

bvdet
Expert Mod 2.5K+
P: 2,851
@imran akhtar
The interpreter will do whatever you tell it to do. I suggested earlier a function to calculate the total each time. You do not need variable nextCard. Use list method pop() to return a card and remove from deck. I moved the location where the computer's hand is updated. If computer busts, player wins and there is no need to hit player. I added string method lower() to options to allow an uppercase entry. The code is by no means finished, but you should be able to take it from here.
Expand|Select|Wrap|Line Numbers
  1. import random
  2.  
  3. def calc_score(hand):
  4.     score = sum([card for card in hand if isinstance(card, int)])
  5.     aces = [card for card in hand if isinstance(card, str)]
  6.     score += len(aces)
  7.     for ace in aces:
  8.         if score < 12:
  9.             score += 10
  10.     return score
  11.  
  12. #hit or stand,are players options.
  13. def game():
  14.  
  15.     deck = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
  16.     player=[]
  17.     computer=[]
  18.     random.shuffle(deck)  #this will shuffle the cards in the deck
  19.  
  20.     # deck.pop() will return a card and remove from deck
  21.     player.append(deck.pop()) 
  22.     computer.append(deck.pop())
  23.     player.append(deck.pop())
  24.     computer.append(deck.pop())
  25.  
  26.     player_score = calc_score(player)
  27.     computer_score = calc_score(computer)
  28.  
  29.     #this will display the players hand
  30.     print "players hand", player, "\tplayers total value", player_score
  31.  
  32.     # update computer hand until the score is >= 16 or busted
  33.     while computer_score < 16:
  34.         computer.append(deck.pop())
  35.         computer_score = calc_score(computer)
  36.  
  37.     if computer_score > 21:
  38.         # CHECK IF COMPUTER IS BUSTED HERE
  39.         print "COMPUTER IS BUSTED!"
  40.         return
  41.  
  42.     while True:
  43.         options = raw_input ("do you want to [h]it / [s]tand / [q]uit: ")
  44.  
  45.         if options.lower() == 'h':       
  46.             player.append(deck.pop())
  47.             print player
  48.             player_score = calc_score(player)
  49.             print player_score
  50.             # CHECK IF PLAYER IS BUSTED HERE
  51.             if player_score > 21:
  52.                 print "PLAYER IS BUSTED!"
  53.                 return
  54.  
  55.         elif options.lower() == 's':
  56.             print "players hand", player
  57.             print player_score
  58.             # COMPARE SCORES HERE TO DETERMINE THE WINNER
  59.  
  60.         elif options.lower() == 'q':
  61.             print "hope you enjoyed the game, bye!!"
  62.             return
  63. game()
Jan 17 '09 #13

P: 64
hey. i dont think you seem to understand. i've done my own code and would rather stick to how it is, i appreciate u writing ur own version of the code but i would rather stick with mine, and jus fix the 'hit' function. you say i can fix it by creating a function to calculate the total, how would i do that?

thanks.
Jan 17 '09 #14

bvdet
Expert Mod 2.5K+
P: 2,851
Hey back. You don't understand that I have modified your code, not written my own. The improvements I proposed to you eliminated the awkward way you were calculating the initial score, updated the score after each hit, removed cards from the deck each time a card was dealt and eliminated the variable nextCard, eliminated the string of if statements that executed each iteration, and showed you how to count aces as 1 or 11.

If all you want to fix in your previous code is updating the score:
Expand|Select|Wrap|Line Numbers
  1.         if options == 'h':
  2.              player.append(deck[nextCard])
  3.              ptotal = sum(player) # <---PLAYER SCORE UPDATED HERE
  4.              nextCard += 1 
  5.              print ptotal
Good luck and HTH.
Jan 17 '09 #15

P: 64
thnaks for ur help with updating the score, it now works, but i have two main problem, firstly how would i now get the ace to be 1 and 11, and a way of displaying the total hands played at the end of the game.

thanks for the help


below is my code,

Expand|Select|Wrap|Line Numbers
  1. import random 
  2.  
  3. deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]
  4. player=[]
  5. computer=[]
  6. random.shuffle(deck)  #this will shuffle the cards in the deck
  7. nextCard = 0
  8. player.append(deck[nextCard]) 
  9. nextCard += 1 
  10. player.append(deck[nextCard]) # nextCard is now 1. 
  11. nextCard += 1 
  12. computer.append(deck[nextCard]) 
  13. nextCard += 1 
  14. computer.append(deck[nextCard]) 
  15. nextCard += 1 
  16. ptotal = sum(player)
  17. ctotal = sum(computer)
  18. print "players hand", player, "\tplayers total value", ptotal   #this will display the players hand
  19. #hit or stand,are players options.
  20. def game():
  21.     global nextCard
  22.     while (True):
  23.         options = raw_input ("do you wana [h]it / [s]tand / [q]uit: ")
  24.         if options == 'h': 
  25.              player.append(deck[nextCard]) 
  26.              ptotal = sum(player)  
  27.              nextCard += 1  
  28.              print "players hand", player, "\tplayers total value", ptotal
  29.  
  30.         elif options == 's':
  31.             ptotal = sum(player)
  32.             print "players hand", player, "\tplayers total value", ptotal
  33.             break
  34.         elif options == 'q':
  35.             playAgain = raw_input ("do u wana play again, [y] / [n]")
  36.             if playAgain == "y":
  37.                 game()
  38.             elif playAgain == "n":
  39.                 print "see ya later, bye!"
  40.                 return
  41.                 break 
  42.  
  43.     while (True):
  44.         if ctotal < 16:
  45.             computer.append(deck[nextCard])
  46.             nextCard += 1
  47.         if ptotal > 21:
  48.             print "computer hand", computer, "\tcomputers total value", ctotal
  49.             print "player busted. computer wins"
  50.             break
  51.         if ctotal > 21:
  52.             print "computer hand", computer, "\tcomputers total value", ctotal
  53.             print "computer busted. player wins"
  54.             break
  55.         if ctotal == ptotal:
  56.             print "computer hand", computer, "\tcomputers total value", ctotal
  57.             print "draw. computer wins"
  58.             break
  59.         if ptotal == 21:
  60.             print "computer hand", computer, "\tcomputers total value", ctotal
  61.             print "player gets a BlackJack. player wins"
  62.             break
  63.         if ctotal == 21:
  64.             print "computer hand", computer, "\tcomputers total value", ctotal
  65.             print "computer gets a BlackJack. computer wins"
  66.             break
  67.         if ptotal > ctotal:
  68.             if ptotal < 21:
  69.                 print "computer hand", computer, "\tcomputers total value", ctotal
  70.                 print "player wins"
  71.                 break
  72.         if ctotal > ptotal:
  73.             if ctotal < 21:
  74.                 print "computer hand", computer, "\tcomputers total value", ctotal
  75.                 print "computer wins"
  76.                 break
  77.  
  78. game()
  79.  
  80.  
  81.  
  82.  
Jan 17 '09 #16

bvdet
Expert Mod 2.5K+
P: 2,851
I showed you how to count an ace as 1 or 11 already by defining a deck of cards with an "A" instead of a 1 and 11, and defining a function to determine the score of a hand. Here is another way, using a 1 instead of an "A".
Expand|Select|Wrap|Line Numbers
  1. >>> def sum_score(hand):
  2. ...     score = sum(hand)
  3. ...     for card in hand:
  4. ...         if card == 1 and score < 12:
  5. ...             score += 10
  6. ...     return score
  7. ... 
  8. >>> deck = [1,2,3,4,5,6,7,8,9,10,10,10,10]*4
  9. >>> import random
  10. >>> random.shuffle(deck)
  11. >>> hand1 = [deck.pop() for i in range(3)] # a hand with 3 cards
  12. >>> hand2 = [deck.pop() for i in range(3)] # another hand with 3 cards
  13. >>> hand1
  14. [5, 10, 10]
  15. >>> sum_score(hand1)
  16. 25
  17. >>> hand2
  18. [1, 4, 5]
  19. >>> sum_score(hand2)
  20. 20
  21. >>> 
hand2 contains a 1 which represents an ace. Function sum_score() adds 10 to the score because the initial sum is less than 12.

-BV
Jan 17 '09 #17

P: 64
yeh thanks, after few changes it is now wroking, is there a way of how i would display total hands played, at the end of game, for both computer and player
Jan 17 '09 #18

bvdet
Expert Mod 2.5K+
P: 2,851
Your code is designed for one hand. You will need a way to deal additional hands, therefore another option is required. Create an empty list at the beginning of the script, and append each hand's results to it.

-BV
Jan 17 '09 #19

P: 64
ok, a bit confused, dont understand how i would start it, thanks
Jan 17 '09 #20

P: 64
so is it possiable of you can explain bit more, how i would display the hands.

thanks
Jan 18 '09 #21

bvdet
Expert Mod 2.5K+
P: 2,851
Create an empty list names results, and append the result of each hand to the list after the winner of the hand is determined. When the user decides to quit playing, ite3rate on the list to display the all results.
Expand|Select|Wrap|Line Numbers
  1. results = []
  2. results.append(['player',[1,5,5],[6,9,4]])
  3. results.append(['computer',[6,5,6],[9,10]])
  4. for result in results:
  5.     print "Winner: %s" % result[0]
  6.     print "    Player hand: %s" % (', '.join([str(i) for i in result[1]]))
  7.     print "    Computer hand: %s" % (', '.join([str(i) for i in result[2]]))
Jan 18 '09 #22

Post your reply

Sign in to post your reply or Sign up for a free account.