简体   繁体   中英

Python 3: UnboundLocalError: local variable 'card' referenced before assignment

The following code gives error

UnboundLocalError: local variable 'card' referenced before assignment

I know it's got to do with the draw_card() function and player_turn() function but I'm exactly sure how to fix it. I've tried doing global card in the player_turn() function but that doesn't work.

import random

def loop():

    player_hand = []
    dealer_hand = []
    deck = []
    rank = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
    suit = ['♣', '♦', '♥', '♠']
    for s in suit:
        for r in rank:
            deck.append(r+s)
    random.shuffle(deck)
    deckpos = 0
    first = deck.pop()
    second = deck.pop()
    third = deck.pop()
    fourth = deck.pop()
    player_hand.append(first)
    player_hand.append(second)
    dealer_hand.append(third)
    dealer_hand.append(fourth)

    def draw_card():
        card = deck[deckpos]
        deckpos += 1
        return card

    def player_turn(first, second):

        player_stand = False
        while player_stand != True:

            print ('You hand is [{}, {}]'.format(first, second))
            print ('The dealer is showing a {}'.format(third))

            first = first[:len(first)-1]
            first = conversion(first)
            second = second[:len(second)-1]
            second = conversion(second)
            value_of_hand = int(first + second)

            if value_of_hand <= 21:
                print ('Your value of your hand is {}'.format(value_of_hand))

            else:
                print ("You busted at {}".format(value_of_hand))
                playerturn_results = [22, 0]
                return playerturn_results

            choice = input ('Do you wish to hit or stand? ')

            if 'hit' in choice.lower():
                print('You draw a {}'.format(card))
                card = card[:len(card)-1]
                card = conversion(card)
                value_of_hand = int(value_of_hand + card)
                print ('Your value of your hand is {}'.format(value_of_hand))


    player_turn(first, second)


loop()

Along with using global card in each function that uses it ( draw_card and player_turn ), you also need to put card = None at the top level (like after import random). Also, this isn't a great way to do it. I don't see why you can't just pass card as a parameter to the functions where required. That applies generally.

As for specific lines that look wrong and nothing to do with global , and the reason you're getting the error: In player_turn , in the if 'hit' in choice.lower(): block, you should get a card before doing things with it:

if 'hit' in choice.lower():
    card = get_card()  # get a card first and then do other things
    print('You draw a {}'.format(card))
    card = card[:len(card)-1]
    ...

But then deck also needs to be declared globally for the line card = deck[deckpos] in draw_card()


Edit: Also, when you're trying to determine the value of a card, you don't need to do first = first[:len(first)-1] . You know that the last character is the suit and everything before that is the rank. So getting the rank is simple and more readable as: first = first[:-1] - which is "slice until last char".

>>> x = '7A'
>>> y = '10B'
>>> x[:-1]
'7'
>>> y[:-1]
'10'

Combined with your conversion line, it would be first = conversion(first[:-1])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM