0

I have tried to create a BLACKJACK game using python (actually I'm learning python). Currently I have not setup bet command (that is written in my Account class). I only takes name from my Account class.

I have a main file : blackjack.py and two classes in files : deckofcards.py, account.py I am only accessing name from account class, so I wont be putting that long mess here.

blackjack.py :

from account import Account

player = Account('kalaLokia')
cards = DeckOfCards()
play = False
playershand = []
dealershand = []
action = ''
blackjack = False


def showCards(items, name):
    '''
    Shows {name}'s cards and hand value
    '''
    print(f"{name}'s hand: ")
    print(f"\t{' - '.join(items)}")
    print(f"Hand value: {cards.handValue(items)}")


def bust(hand):
    '''
    Whether a someone has busted or not
    '''
    if(cards.handValue(hand) > 21):
        return True
    return False


def dealersMove():
    '''
    Dealers move: executes when player calls "stand"
    Dealer perform hit until he gets bust, wins or his hand value becomes >= 17
    When hand value is >17 and players has greater value, dealer loses ;-)
    '''
    global blackjack

    if(cards.handValue(dealershand) == 21):
        print('Dealer got a BLACKJACK')
        print('Dealer WINS')
        return
    elif(blackjack):
        print(f'{player.name} got a BLACKJACK')
        print(f'{player.name} WINS')
        blackjack=False
        return

    while(not bust(dealershand)):

        if(cards.handValue(dealershand) > cards.handValue(playershand)):
            print('Dealer WINS')
            showCards(dealershand, 'Dealer')
            break
        elif(cards.handValue(dealershand) == cards.handValue(playershand)):
            print("It's a TIE!!\n Dealer WINS")
            break
        elif(cards.handValue(dealershand) > 17):
            print(f'Dealer loses\n{player.name} has WON.')
            print(f'{cards.handValue(playershand)} > {cards.handValue(dealershand)}')
            break

        dealershand.append(cards.hit())
    else:
        print(f'Dealer busts! \n{player.name} has WON the game.')


def start():
    '''
    The actiona that can be performed
    '''
    global blackjack

    if(cards.handValue(playershand) == 21): 
        blackjack = True
        dealersMove()
        return
    while(not bust(playershand)):

        action = input(
            f"{player.name}'s turn: Do you want to hit or stand ? ").lower()
        if(action == 'hit'):
            playershand.append(cards.hit())
            showCards(playershand, player.name)
        elif(action == 'stand'):
            dealersMove()
            break
        else:
            print('Please enter a valid action !')
    else:
        print(f'{player.name} has been BUSTED')


if __name__ == "__main__":

    print(f'Hello {player.name}, Welcome to BlackJack Game')
    # Tell game rules here, may be
    response = input('Do you want to start the game (Y/n)? ').lower()
    if(response != 'y'):
        play = False
        print('You have been exited the game')
    else:
        play = True
    # Ask for bet amount later
    while(play):
        cards = DeckOfCards()
        cards.shuffle()
        print('Cards on the table is now shuffled')
        playershand = list(cards.initiate())
        dealershand = list(cards.initiate())
        print(
            f"{player.name}'s hand:\n   {playershand[0]} - {playershand[1]}\nHand value: {cards.handValue(playershand)}\n")
        print(f"Dealer's hand:\n   {dealershand[0]} - ?\n")

        start()

        if(input('Do you want to play again (Y/n)?').lower() != 'y'):
            print('The End')
            play = False

deckofcards.py :

import random

class DeckOfCards():
    '''
    All talks here is about cards
    '''
    cards = {'A':11,'K':10,'Q':10,'J':10,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10}

    def __init__(self):
        '''
        Initialize deck of cards
        '''
        self.deck = list(self.cards.keys())*4

    def shuffle(self):
        '''
        Simply shuffles the deck of cards
        '''
        return random.shuffle(self.deck)

    def handValue(self, hand):
        '''
        Calculates and returns the hand value, expecting a string value to be feeded.
        '''
        result = 0

        for element in hand:
            result = result + self.cards[element]

        while('A' in hand and result > 21):
            if(hand[0]=='A'):
                result = result - 10
            # Somehow this hand.pop is poping out from main value itself. Why ???
            hand.pop(0)

            if(hand == []):
                break  

        return result

    def hit(self):
        '''
        Pop out and returns the last card in the deck
        '''
        return self.deck.pop()

    def initiate(self):
        '''
        Pop out 2 cards from the deck and return as a tuple
        '''
        return (self.deck.pop(), self.deck.pop() )

Issue:
When I have an ACE in my hand and my hand value is greater than 21, the while condition executes in the handValue function (which is in DeckofCards class) as it is. Problem is, after that while condition executes, playershand (declared in main file) I just passed to this handValue function gets empty. That is the hand.pop(0) actually seems popping out value from main object playershand itself (It seems me so).

When I press a hit after that, I get a single new card, all other cards are got popped out. I don't understand why it is so.

On hit(user enter hit) : actually I am passing playershand (cards on the player hand, it's a list) to function showCards (which is also in the main file) where it takes it as argument items and pass it to handValue function in the class DeckOfCards.

So why is it happening? even though I am passing playershand as an argument to other functions, how pop() function affecting playershand which has only access to hand object in the handValue class ?

I have my complete code in github repo to test out, the files in folder blackjack

kalaLokia
  • 131
  • 1
  • 14
  • 1
    Passing a parameter to a function *doesn't make a copy of it* - that would be horribly inefficient. It's the same object inside the function as in the caller of the function. – jasonharper Apr 25 '20 at 15:12
  • So you're saying `hand` object in the function `handValue` is same of `playershand` which I passed to it ? I know the value will be same, but how it is possible that modifying `hand` also reflecting back to `playershand`. I am not returning the modified `hand` value to anywhere. @jasonharper – kalaLokia Apr 25 '20 at 15:23
  • https://stackoverflow.com/a/986145/12637074 : This described me everything I wanted to know – kalaLokia Apr 26 '20 at 07:13

0 Answers0