Looping and Finishing? In Python

Asked

Viewed 56 times

0

Hi, guys. I have a problem with my program. I’m not getting it looped until I "shut it down" it. I’ll be leaving his code, making it easier for you to understand. Where the operator selected to play again, it should come to the initial 'menu' (select difficulties and such), '2' should "terminate" the program. Only it doesn’t go, it goes back inside the FOR and stays there, repeating always

a=1
pontos=1000
import random
while a==1:
  print('Bem vindo ao jogo de adivinhar. Em qual dificuldade gostaria de tentar?\n')
  b=int(input('1-Facil?(9 tentativas)\n2-Medio?(6 tentativas)?\n3-Dificil?(3 tentativas)\nVoce comeca com 1000 pontos. Cada vez que errar, perde 50 pontos.\n'))
  while b==1:
    valor=random.randrange(1,10)
    for c in range(9):
      d=int(input('Digite um numero entre 1 e 10\n'))
      if valor==d:
        print('Parabens, acertou!\n')
        break
      else:
        print('Tente novamente\n')
        pontos=pontos-50
    print('Saldo de pontos:\n',pontos)
    a=int(input('Gostaria de jogar novamente?\n1-Sim\n2-Nao\n'))
  while b==2:
    valor=random.randrange(1,50)
    pontos=1000
    for c in range(6):
      d=int(input('Digite um numero entre 1 e 50:\n'))
      if valor==d:
        print('Parabens, acertou!\n')
        break
      else:
        print('Tente novamente\n')
        pontos=pontos-50
    print('Saldo de pontos: ',pontos)
    a=int(input('Gostaria de jogar novamente?\n1-Sim\n2-Nao\n'))
  while b==3:
    valor=random.randrange(1,50)
    pontos=1000
    for c in range(3):
      d=int(input('Digite um numero entre 1 e 100:\n'))
      if valor==d:
        print('Parabens, acertou!\n')
        break
      else:
        print('Tente novamente\n')
        pontos=pontos-50
    print('Salndo de pontos: ',pontos)
    a=int(input('Gostaria de jogar novamente?\n1-Sim\n2-Nao\n'))
print('Obrigado por jogar!')

2 answers

0

Add a break immediately after the user informs if they want to continue playing. This will force the output of the 2nd loop, returning to the validation of the 1st loop.

    a = int(input('Gostaria de jogar novamente?\n1-Sim\n2-Nao\n'))
    break

The problem occurs because the way it is written the validation of the second while will always be true. After the user informs the code 2 (quit) at the end, it continues in the current loop since there was no change in the value of the variable b.

So it would also work if you changed the value of the variable b for any value other than 1,2 or 3 (first question options).

    a = int(input('Gostaria de jogar novamente?\n1-Sim\n2-Nao\n'))
    b = 0

However, I think the code gets easier to read with the break.

0

There are several problems there. One of them, for example, is this while:

b = int(input(...))
while b==1: etc...

If typed 1, he enters the while. But inside the while you do not change the value of b in no time, then he enters loop infinite, see.

In fact you are complicating for nothing, there is no reason to make a while to the difficulty, and also there is no reason to repeat the same code for each difficulty level, and what changes are only the amount of attempts and the range of the numbers. A simpler way would be:

def ler_numero(mensagem, valores_validos):
    while True:
        try:
            valor = int(input(mensagem))
            if valor in valores_validos:
                return valor
            else:
                print(f'Valor deve ser: {", ".join(map(str, valores_validos))}')
        except ValueError:
            print('Você não digitou um número, tente novamente')

import random
pontos = 1000

while True:
    print('Bem vindo ao jogo de adivinhar. Em qual dificuldade gostaria de tentar?\n')
    dificuldade = ler_numero(
        '1-Facil?(9 tentativas)\n2-Medio?(6 tentativas)?\n3-Dificil?(3 tentativas)\nVoce comeca com 1000 pontos. Cada vez que errar, perde 50 pontos.\n',
        (1, 2, 3))
    if dificuldade == 1:
        tentativas = 9
        valor_maximo = 10
    elif dificuldade == 2:
        tentativas = 6
        valor_maximo = 50
    else: # a função ler_numero já me garante que a dificuldade é 1, 2 ou 3
        tentativas = 3
        valor_maximo = 100

    valor = random.randint(1, valor_maximo)
    for i in range(tentativas):
        palpite = ler_numero(f'Digite um número entre 1 e {valor_maximo}: ', range(1, valor_maximo + 1))
        if palpite == valor:
            print('Parabéns, acertou!')
            break
        else:
            pontos -= 50
            if i != tentativas - 1: # se não é a última tentativa
                print('Tente novamente')
    else:
        print(f'Você não acertou, o número era {valor}')
    
    print(f'Você fez {pontos} pontos')
    if 2 == ler_numero('Gostaria de jogar novamente?\n1-Sim\n2-Nao\n', (1, 2)):
        break # sai do while True

print('Obrigado por jogar!')

I created the function ler_numero, validates not only whether the value is valid (if it is between a minimum and maximum value, for example), but also checks whether a number has actually been entered (capturing the ValueError, which occurs if the user enters something other than a number).

Then I create a loop with while True (that repeats itself indefinitely, until finding a break). There’s no point in creating an artificial variable (a) just to control the loop.

When the difficulty is chosen, I arrange the values that will change: the amount of attempts and the maximum value to be chosen by randint (i’ve changed randrange for randint, for randrange(1, 10) choose a number between 1 and 9, while randint(1, 10) choose a number between 1 and 10 - see documentation - and it seems to me that what you need is randint).

Then just make one for to read the guesses. If you get it right, interrupt the loop, otherwise continues until the number of attempts.

At the end I read the option to continue or not.

One detail is that the score is never reset, I don’t know if it was the intention: when the user chooses to play again, the score does not go back to 1000. If the idea was to go back to 1000, put pontuacao = 1000 within the while, just before printing the difficulty choice message.

Another point is that I gave better names for variables (dificuldade is clearer than b, for example, because it makes clear what that value represents). It may seem like a stupid detail, but Better names help when designing.

Browser other questions tagged

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