1

I've tried googling and searching on SO, but I cant figure out why my break on the second to last line is not heading out of the while loop. Better yet, I cant figure out why the loop is not continuing either. My intention is to give the user the possibiltiy to head to the main menu after the last choice (basically the while loop for menuchoice (which is one loop above what I have pasted here).

Any suggestions? Thank you in advance. It feels like I'm missing something essential.

#this is going to show how many exercise weapons you need for next magic level
if menuchoice == "4":
    #these functions returns the amount of magic wands/rods that is needed to be spent for next magic level
    print("Select vocation")
    print("Press P for Royal Paladin")

    #ask user to input vocation:
    while True:
        vocationchoice = input()
        if vocationchoice == "P" or vocationchoice == "p":
            #ask user to input magic level for paladin
            num1 = float (input("Enter your magic level: "))

            #ask for own training dummy
            print("Do you have your own exercise dummy? Type Y for yes and N for no.")
            while True:
                trainingdummy = input()
                if trainingdummy == "y" or trainingdummy == "Y":
                    #list the different exercise weapons
                    print("Select exercise weapon:")
                    print("1. Training rod")

                    #loop, where we ask user to input what exercise weapon they want to calculate
                    while True:
                        while True:
                            weaponchoice = input()
                            if weaponchoice == "q":
                                sys.exit() #quit the program
                            if weaponchoice == "1" or weaponchoice == "2" or weaponchoice == "3" or weaponchoice == "f":
                                break #break out of the input loop

                        #User choice
                        if weaponchoice == "1":
                            print("The amount of training rods needed for next magic level is " + str((nextmaglvlpalwithdummy(num1))) + ".")

                if trainingdummy == "n" or trainingdummy == "N":
                    #list the different exercise weapons
                    print("Select exercise weapon:")
                    print("1. Training rod")

                    #loop where ask user to input what exercise weapon they want to calculate
                    while True:
                        weaponchoice = input()
                        #User choice
                        if weaponchoice == "1":
                            print("The amount of training rods needed for next magic level is " + str((nextmaglvlpal(num1))) + ".")

                        elif weaponchoice == "f":
                            break

                        print("\nGo to main menu? Press F.")
Ajit Panigrahi
  • 752
  • 10
  • 27
austriker
  • 15
  • 3
  • Are you talking about the first break statement or the second one at the end? – Louis Lac Feb 05 '20 at 08:53
  • Maybe, instead of `while True` you could use a boolean `variable` and `var = False` instead of `break` – Ivan Feb 05 '20 at 08:56
  • @LouisLac the last one at the end. It doesnt do anything. And if I remove that break, shouldn't I be able to press "1" again, and get the same result? If it is within that loop? – austriker Feb 05 '20 at 09:12
  • The intended behaviour is that the break statement when "f" is pressed to return to the main menu, e.g. out out of all the previous while loop? For now your code stay in the training dummy" choice loop when "f" is pressed. – Louis Lac Feb 05 '20 at 09:17
  • That is the intended behaviour, yes. But again, if I remove the break statement on the last row, I should be able to press "1" again and it should give me the result. After pressing "1" the first time, it stays there though, like it's not part of a while loop. Its very strange. – austriker Feb 05 '20 at 09:25
  • I just tested your code without the last `elif` and `break` statement and all works fine, the last nested loop is repeated again and I can press "1" again. – Louis Lac Feb 05 '20 at 09:38
  • Thanks Louis. I edited all the rest of the vocations as well, and removed it. It works now for me too. So now the question is - how can i return to the original loop? – austriker Feb 05 '20 at 09:43

3 Answers3

1

This will help you I think. Break only breaks from current loop. If you want to go up on levels you need to break from each loop separately.

A suggestion is to turn a loop into a function and use return which will effectively exit any loop. A little bit of code refactor will be needed though.

If not the case can you maybe provide some more info and possibly the full code (there is a higher loop that we dont see here?)

Svestis
  • 342
  • 4
  • 12
  • Problem is, if i remove the last break statement (elif weaponchoice == f), it doesnt keep going within that loop, and shouldnt it do that? – austriker Feb 05 '20 at 09:11
  • @austiker Just changed the reply a little bit. Hope it is more helpful now – Svestis Feb 05 '20 at 09:39
0

Add a break for weaponchoice == "1" to get out of the loop.

Ajit Panigrahi
  • 752
  • 10
  • 27
0

First, you should print things in the input() command as it will be cleared in intend: input("Text to display").

Second, if you want to exit to the main menu, you need to break every nested loop. Here you only break the most inner loop.

As in Python there is no goto instruction nor named loops, you can use a flag. A flag is set to true when the used presses 'F' and this flag is then used at the beginning of every outer nested loop to break them. It can look like this:

while True: # This is your menu loop
  menuFlag = False # Declare and set the flag to False here

  menu = input("Choose the menu: ")
  # ...

  while True: # Choose character loop
    if menuFlag: break  # Do not forget to break all outer loops   

    character = input("Choose a character: ")
    # ...

    while True: # Any other loop (choose weapon, ...)
        weapon = input("Choose weapon: ")

        # Here you want to return to the menu if f is pressed
        # Set the flag to True in this condition
        if weapon == "f":
            menuFlag = True
            break

In your game this ressembles to:

goToMainMenu = False

while True:
    if goToMainMenu: break
    vocationchoice = input("Select vocation.\nPress P for Royal Paladin: ")

    if vocationchoice == "P" or vocationchoice == "p":
        #ask user to input magic level for paladin
        num1 = float (input("Enter your magic level: "))

        #ask for own training dummy
        while True:
            if goToMainMenu: break

            trainingdummy = input("Do you have your own exercise dummy?\nType Y for yes and N for no: ")
            if trainingdummy == "y" or trainingdummy == "Y":
                #loop, where we ask user to input what exercise weapon they want to calculate
                while True:
                    while True:
                        weaponchoice = input("Select exercise weapon:\n1. Training rod: ")
                        if weaponchoice == "q":
                            sys.exit() #quit the program
                        if weaponchoice == "1" or weaponchoice == "2" or weaponchoice == "3" or weaponchoice == "f":
                            break #break out of the input loop

                    #User choice
                    if weaponchoice == "1":
                        print("The amount of training rods needed for next magic level is " + str((nextmaglvlpalwithdummy(num1))) + ".")

            if trainingdummy == "n" or trainingdummy == "N":
                #list the different exercise weapon

                #loop where ask user to input what exercise weapon they want to calculate
                while True:
                    weaponchoice = input("Select exercise weapon (press F for main menu):\n1. Training rod: ")
                    #User choice
                    if weaponchoice == "1":
                        print("The amount of training rods needed for next magic level is " + str((nextmaglvlpalwithdummy(num1))) + ".")

                    elif weaponchoice == "f" or weaponchoice == "F":
                        goToMainMenu = True
                        break
Louis Lac
  • 5,298
  • 1
  • 21
  • 36
  • Thank you very much! How will the program know what the mainmenu is? I should need to name it that, or? – austriker Feb 05 '20 at 10:18
  • You should declare the flag (that is a boolean value) in scope (the loop) where you want to break into, plus you have to set it to `False`. I add an example in my answer. – Louis Lac Feb 05 '20 at 10:21
  • Note that you can declare any number of flags you need. Be careful, flags are not easy to maintain as you can easily forget to write the break statement and they tend to pollute the code. – Louis Lac Feb 05 '20 at 10:31
  • 1
    I just missed the first example, now I see and understand. A big thank you for helping me Louis Lac! – austriker Feb 05 '20 at 10:43
  • 1
    It worked. I notice, as you say, that this give me another problem, which is that it seems a bit of an effort to maintain, and keep track off. I guess originally, it is better to not get nestled in loops as I do with this code. – austriker Feb 05 '20 at 13:01
  • Sure, you should use functions instead of nesting loops and some sort of state. There are library dedicated to build games in Python that could help you also. – Louis Lac Feb 05 '20 at 13:04