How to restart the loop for the player to play more than once regardless of whether to hit the answer or not

Asked

Viewed 131 times

-1

import random

print('='*20)
print('JOGO DA FORCA')
print('='*20)
print('Bem vindo ao Jogo da Forca! Vamos começar!')

nome = input("Digite o seu nome: ")
palavra = ('uva','oi')
palavra_forca = random.choice(palavra)

digitadas = []
acertos = []
erros = 0


while True:
    senha = ""
    for letra in palavra_forca:
        senha += letra if letra in acertos else "_ "
    print(senha)
    if senha == palavra_forca:
        print(f"{nome} acertou!")
        break
    tentativa = input("\nDigite uma letra:").lower().strip()
    if tentativa in digitadas:
        print("Você já tentou esta letra!")
        continue
    else:
        digitadas += tentativa
        if tentativa in palavra_forca:
            acertos += tentativa
        else:
            erros += 1
            print("Você errou!")
            print()
    print("X==:==\nX  :   ")
    print("X  O   " if erros >= 1 else "X")
    linha2 = ""
    if erros == 2:
        linha2 = "  |   "
    elif erros == 3:
        linha2 = " \|   "
    elif erros >= 4:
        linha2 = " \|/ "
    print("X%s" % linha2)
    linha3 = ""
    if erros == 5:
        linha3 += " /     "
    elif erros >= 6:
        linha3 += " / \ "
    print("X%s" % linha3)
    print("X\n===========")
    if erros == 6:
        print(f"{nome} foi enforcado!")
        break

2 answers

3

If you want the loop continue, just don’t interrupt it. In your case, you are using break, interrupting the loop, then just don’t use it (or just use it when you really have to quit). It was unclear whether to "continue forever", but a suggestion would be to ask the user if he wants to continue playing. Something like this:

while True:
    # lógica do jogo

    if senha == palavra_forca:
        print(f"{nome} acertou!")
        if input('Jogar novamente? S/N').lower() == 'n':
            break

But that alone is not enough, because when restarting the game you have to set again the variables palavra_forca, digitadas, acertos and erros (since it is a new game starting). I suggest creating a function that returns this information "zeroed", and then you can use it to set the variables in the 2 cases it is needed (when the player hits or when the odds run out). Would look like this:

# ler o nome, etc...

def setup_inicial():
    return (random.choice(palavra), [], [], 0)

palavra_forca, digitadas, acertos, erros = setup_inicial()

while True:
    senha = ""
    for letra in palavra_forca:
        senha += letra if letra in acertos else "_ "
    print(senha)
    if senha == palavra_forca:
        print(f"{nome} acertou!")
        if input('Jogar novamente? S/N: ').lower() == 'n':
            break
        else: # "zera" as variáveis, iniciando um novo jogo as variáveis
            palavra_forca, digitadas, acertos, erros = setup_inicial()
            continue # aqui ele vai para a próxima iteração do loop, ignorando o restante abaixo

    # ler a tentativa, imprimir o homem enforcado, etc...

    if erros == 6:
        print(f"{nome} foi enforcado!")
        if input('Jogar novamente? S/N: ').lower() == 'n':
            break
        else: # "zera" as variáveis, iniciando um novo jogo as variáveis
            palavra_forca, digitadas, acertos, erros = setup_inicial()

When using break, he comes out of while True and continues running the code (if you have something after the while). But if the idea is simply to leave the program, you can use sys.exit. In this case, you could use a function a little more "smart" to check if it was typed "s" or "n" (because the way it is above, anything other than "n" makes the game continue).

And since you’re wearing f-strings (for example, in print(f"{nome} acertou!")), don’t need to use % to print linha2 and linha3, use the same thing in the respective print's.

I also used raw string literals so that the \ is interpreted correctly, since in strings this character is used for escape sequences, such as \n which indicates a line break (but in your case does not seem to give problem because it coincided not to have an escape sequence, anyway, I put below also).

And the variable that holds all possible words could be called palavras (plural). By calling it palavra (in the singular), may give the impression - wrong - that it only has one word. It may seem a bit of a detail, but giving better names helps a lot when programming.

Anyway, I’d be like this:

import random
import sys

print('='*20)
print('JOGO DA FORCA')
print('='*20)
print('Bem vindo ao Jogo da Forca! Vamos começar!')

nome = input("Digite o seu nome: ")
palavras = ('uva','oi')

def setup_inicial():
    return (random.choice(palavras), [], [], 0)

def continua_jogando():
    while True:
        opcao = input('Jogar novamente? s/n ').lower()
        if opcao == 'n': # se digitou "n", sai do jogo (interrompe o programa)
            sys.exit(0)
        if opcao == 's': # se digitou "s", retorna o setup inicial com as variáveis "zeradas"
            return setup_inicial()
        # não digitou "s" nem "n", imprime a mensagem e pede que digite novamente
        print('Digite "s" ou "n"')

palavra_forca, digitadas, acertos, erros = setup_inicial()

while True:
    senha = ""
    for letra in palavra_forca:
        senha += letra if letra in acertos else "_ "
    print(senha)
    if senha == palavra_forca:
        print(f"{nome} acertou!")
        palavra_forca, digitadas, acertos, erros = continua_jogando()
        continue # como vai reiniciar o jogo, use "continue" para ir direto para a próxima iteração do while, ignorando o que está abaixo

    tentativa = input("\nDigite uma letra:").lower().strip()
    if tentativa in digitadas:
        print("Você já tentou esta letra!")
        continue
    else:
        digitadas += tentativa
        if tentativa in palavra_forca:
            acertos += tentativa
        else:
            erros += 1
            print("Você errou!\n")

    print("X==:==\nX  :   ")
    print("X  O   " if erros >= 1 else "X")
    linha2 = ""
    if erros == 2:
        linha2 = "  |   "
    elif erros == 3:
        linha2 = r" \|   "
    elif erros >= 4:
        linha2 = r" \|/ "
    print(f"X{linha2}")
    linha3 = ""
    if erros == 5:
        linha3 += " /     "
    elif erros >= 6:
        linha3 += r" / \ "
    print(f"X{linha3}")
    print("X\n===========")
    if erros == 6:
        print(f"{nome} foi enforcado!")
        palavra_forca, digitadas, acertos, erros = continua_jogando()

To another answer (which has been deleted) is suggesting to use recursion (create a function and call it within itself).

Although "working", it is not the ideal solution. Each recursive call being piled up, and after a certain number of iterations, it may end up popping the stack (see here an example).

Already if you use one loop simple and stop it (be with break or with sys.exit), there is no such risk. The program can iterate as many times as it wants that the stack overflow will not occur.

-1

Put this whole loop inside another while True:

while True:
  palavra = ('uva','oi')
  palavra_forca = random.choice(palavra)

  digitadas = []
  acertos = []
  erros = 0
  while True:
    senha = ''
  • That way it won’t work, in the end he’ll keep repeating that he won or lost

Browser other questions tagged

You are not signed in. Login or sign up in order to post.