Why doesn't this program work?

Hello,
I have to code the game ‘black jack’. I have to code the game ‘black jack’. When I ask the player to replay the question comes up again as if I was in an infinite loop, even though I don’t use a while.

import random

#1
def deck():
    color=["spades", "diamonds", "hearts", "clubs"]                                                 #creation of a list of the 4 symbols 
    deck=[]                                                                                         #creation of an empty list
    for s in color :
        cards=["2", "3", "4", "5", "6", "7", "8", "9", "10", "jack", "queen", "king", "ace"]        #creation of a list of the value
        for n in cards :
            c = n + " of " + s                                                                      #c is the cards with a value and a symbole   
            deck.append(c)                                                                          #add c to the empty list = deck of cards
    return deck

#2
def valueCard(card) :
    nb= card[0]                                                  #take only the first character of the string
    if nb>='2' and nb<='9' :
        value = int(card[0])
    elif nb=='1' or nb=='j' or nb=='q' or nb=='k' :
        value = 10
    else :
        value = int(input("which value chosen ? ( 1 or 11 )"))   #ask the user to chose the value wanted
    return value

#3
def initstack(n) :          # n is the number of player chose by the user
    p = []                  #creation of an empty list
    for i in range(0, n+1): # add n-deck of card to the empty list
        y = deck()          # y is a deck of card
        p.extend(y)         # add y to p 
        random.shuffle(y)
    return p                # p is list of the n-deck shuffled


#4
def drawCard(p,x=1):        # x is the number of cards
    dc = []                 #creation of a empty list
    for i in range (0, x) : 
        card = p[0]         #card is the first element of the srting
        dc.append(card)     #add to the list dc
        p.remove(card)      #remove card from the list of n-deck
    return dc               #dc is the list of thge x-cards choosen


#1
def initPlayers(n):
    joueurs = []
    for i in range (0, n ) :
        name = input("name of the player ?")
        joueurs.insert(i, name)
    return joueurs

#2
def initScores(joueurs, v=0):
    score = {}
    for i in joueurs :
        score[i] = v
    return score

#3
def firstTurn(players):
    scores =initScores(players, 0)
    p = initstack(len(players))
    for i in range(0, len(players)) :
        cards = drawCard(p, 2)
        print(cards)
        score = 0
        name = players[i]
        for j in range(0, 2) :
            v = valueCard(cards[j])
            score = score + v
        scores[name] = score
    return scores

#4
def winner(scores) :
    wins = 0
    for key in scores:
        if scores[key] > wins and wins<= 21 :
            wins = scores[key]
            name = key
    return name, wins



def Continue() :
    c = input(" do you want to continue ? yes/no ")
    while c !='yes' or c !='no' :
        c = input(" do you want to continue ? yes/no ")
    if c =='yes' :
        return True
    elif c =='no' :
        return False

def playerTurn(turn, namep, scores, p, x) :
    print('BLACK JACK')
    print('turn number:', turn)
    print('the player is:', namep)
    print('current total of point:', scores[namep])
    savescore={}
    if Continue()==True :
        newcard= drawCard(p, x)
        v = valueCard(newcard)
        print('the value of the card is:',v)
        scores[namep]= scores[namep] + v
        if scores[namep] == 21 :
            print('YOU ARE THE WINNER !!!!')
        elif scores[namep] > 21 :
            print('YOU LOOSE',)
            savescore[namep]= scores[namep]
            del scores[namep]
    elif Continue()==False :
        savescore[namep]= scores[namep]
        del scores[namep]
        print('END OF YOUR GAME')
        
    
    return scores[namep]
            
    
  

def gameTurn(joueurs, scores, p, x) :            
    scores2=dict(scores)                                                    #copy of the dictionary scores                                                    
    turn = 1
    for i in joueurs :                                                      #chose the player
        if i in scores :                                                    #verify if the player is still in play 
            scores2 = scores2[i]+(playerTurn(turn, i, scores, p, x))        #upload the score of the player in the dictionary scores2
            if scores2[i]==21:                                              # if th score of the player is 21, the game stop
                return scores2
        elif not i in scores :                                              
            del scores2[i]                                                  #if the player is not in the dictionary scores it will be removed of the dictionary scores2, this signify the player decide to don't continuate or the player loose
        turn=turn+1
    return scores2                                                          #return the new dictionary with the new values of the players still in play



def gameOver(scores2):
    flag = False
    if (21 in scores2.value()) or (not scores2) :       #if 21 is a value in scores2 or if scores2 is empty
        flag = True                                     # the game is finished
    return flag


def findkey(scores2):
    for i in scores2:
        if scores2[i]==21:
            winner=i
    return winner

def completeGame(joueurs, scores, p, x):
    nwin=initScores(joueurs, v=0)
    gameround=gameTurn(joueurs, scores, p, x)
    gO= gameOver(gameround)
    while gO==True :
        winner=findkey(gameround)
        nwin[winner]=nwin[winner]+1
    return nwin

main program .......................................................................... 
        

n = int(input('nb of players ?'))
p = initstack(n)
playagain ='yes'
nbgame=0
while playagain == 'yes' :
    x = int(input('nb of cards ?'))
    dc = drawCard(p, x)
    joueurs = initPlayers(n)
    score = initScores( joueurs, 0)
    scores = firstTurn (joueurs)        
    BJgame= completeGame(joueurs, scores, p, x)
    print(BJgame)
    nbgame=nbgame+1
    playagain=imput('Do you want to play an other time? (yes/no)')
overallwinner = winner(BJgame)
print('you played:', nbgame, 'the overall winner is:', overallwinner)

Hi Sophia and welcome to the Python forums! Please properly format your code so that we can read it properly. You can do that by putting your code between 3 backticks (```) like this:

```python
#1
def deck():
    ...
```

And it will show up like this:

# 1
def deck()
    ...

Since formatting is important to Python we can’t help you if we can’t read your code properly. Please edit your post so that your code displays properly.

But… you do use a while. Look:

playagain ='yes'
nbgame=0
while playagain == 'yes' :
    x = int(input('nb of cards ?'))
    dc = drawCard(p, x)
    joueurs = initPlayers(n)
    score = initScores( joueurs, 0)
    scores = firstTurn (joueurs)
    BJgame= completeGame(joueurs, scores, p, x)
    print(BJgame)
    nbgame=nbgame+1
    playagain=imput('Do you want to play an other time? (yes/no)')

That will loop until the player answers “yes”.

But I suspect your real problem is gameOver(), which is also used in a
loop. Your gameOver() function is like this:

def gameOver(scores2):
    flag = False
    if (21 in scores2.value()) or (not scores2) :       #if 21 is a value in scores2 or if scores2 is empty
        flag = True                                     # the game is finished
    return flag

That itself looks ok. But when you use it:

def completeGame(joueurs, scores, p, x):
    nwin=initScores(joueurs, v=0)
    gameround=gameTurn(joueurs, scores, p, x)
    gO= gameOver(gameround)
    while gO==True :
        winner=findkey(gameround)
        nwin[winner]=nwin[winner]+1
    return nwin

Here you call gameOver(gameround) once, before the while loop. SO the
value of go never changes and is always True because you never call
gameOver again.

Try this changed loop:

gO= gameOver(gameround)
while gO==True :
    winner=findkey(gameround)
    nwin[winner]=nwin[winner]+1
    gO= gameOver(gameround)

I would also put a print() call somewhere to watch the value of “go”,
just:

print("g0 =", g0)

at the top of the loop. That would at least tell you the variable state.
And putting a print() in gameOver() itself will show you it being
called, and just before the return would show you what it is returning.

Also, your test seems upside down. You want the loop to run while the
game is not over. Since you don’t use g0 elsewhere, you can omit
it. And you do not need to test against “True” explicitly. That would
make you loop look like this:

while not gameOver(gameround):
    winner=findkey(gameround)
    nwin[winner]=nwin[winner]+1

See we omitting the “g0=” at the bottom? Because now the loop condition
itself now calls gameOver().

If your inifinite loop is elsewhere this may not fix all your problems,
but this at least is required.

And remember to print() stuff. It will show you what things are called
and what various variable are. print() the things you think might be
wrong, to see if they are wrong.

Cheers,
Cameron Simpson cs@cskk.id.au

Hi Sophia, welcome! Seems like @cameron spotted the issue, and I echo @J-M0 's comments about formatting—at least on the web, its almost impossible to follow your code without code block formatting (you can use the preview pane to the right of your message to make sure it shows up correctly). If you’d like further feedback on your implementation, I’d be happy to do so provided it is formatted legibly.

I just wanted to add, however, we recently helped another using solve a very similar problem to yours (getting stuck in a while loop in a blackjack game when trying to exit; must be a common beginner exercise), so you might be interested in checking out the approach in that thread and my suggestions on it and compare it to yours, as its often very worthwhile to do. Cheers!

Luckily for me I’m on email, and see the text/plain version by default
(email comes in text/plain and text/html for this forum). So the
physical formatting is preserved for me!

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like

Ah, I was wondering about that one—I almost explicitly mentioned something to that effect in the above, but didn’t want to presume and just left it at “at least on the web”. One benefit of email then, I guess!

Just one of many! :slight_smile: - Cameron

ok, i will do it. Thank you~