Felix
Felix

Reputation: 29

How to use a loop into another loop in Java

I am trying to make a small game:

I created a loop for my first question (choosing a hero) so that if the user enters something else aside from 1 or 2, the program will repeat the question ("Choose your hero: ...). I need the same done for my second and third question (especially since there are some restrictions, e. g. if the user chose Warrior, he can't choose Teleportation as his travel option).

public static void main(String[] args) {
    int hero, travel, weapon;
    Scanner scan = new Scanner(System.in);

    loop:
        while (true) {
            System.out.println("Choose your hero: 1 for Warrior, 2 for Mage");
            hero = scan.nextInt();
            switch (hero) {
            case 1:
                System.out.println("Choose your travel option: 1 for Horse; 2 for Teleportation");
                travel = scan.nextInt(); 
                break loop;
            case 2:
                System.out.println("Choose your travel option: 1 for Horse; 2 for Teleportation");
                travel = scan.nextInt(); 
                break loop;
            default:
                break;
            }
        }                       
}

I don't know how to use a loop inside another loop properly. I've tried several options but it always returns an error.

Upvotes: 0

Views: 199

Answers (3)

Stephan Hogenboom
Stephan Hogenboom

Reputation: 1573

Like the comments suggest i would not go with loops inside loops. Instead you should assign the variables one at the time. I have written a helper method selectVariable(String description, String varOne, String varTwo) that you can use to assign variables and give you a start for your story game. You could expand it if you want to give the user more choices. Also don't give the use the illusion a choice can be made, if there is no choice in that situation.

Here is the code that should do what you want:

import java.util.Scanner;

public class Story {

  static Scanner scan = new Scanner(System.in);

  public static void main(String[] args) {
    int hero = chooseHero();
    int travel = chooseTravel(hero);
    int weapon = chooseWeapon(hero);

    //For printing purposes give your choice their respective string name again. 
    String heroDesc = hero == 1 ? "Warrior" : "Mage";
    String travelDesc = travel == 1 ? "Horse" : "Teleportation";
    String weaponDesc = weapon == 1 ? "Sword" : "Staff";

    System.out.printf("you are a %s, traveling by %s, wielding a %s" + System.lineSeparator(), heroDesc, travelDesc, weaponDesc);
  }

  private static int chooseHero() {
    return selectVariable("choose your hero class", "warrior", "mage");
  }

  private static int chooseTravel(int hero) {
    if (hero == 1) { // if the user has no choice don't give the illusion a choice can be made
      System.out.println("you are a Warrior you will travel by horse");
      return 1;
    } else {
      return selectVariable("choose your way of travel", "by horse", "teleportation");
    }
  }

  private static int chooseWeapon(int hero) {
    if (hero == 2) {
      System.out.println("you are a mage you will wield a staff");
      return 2;
    } else {
      return selectVariable("choose your weapon", "sword", "staff");
    }
  }

  //you can reuse this method to also assign other traits to your story
  private static int selectVariable(String description, String varOne, String varTwo) {
    int var;
    do {
      System.out.printf("%s: 1 %s, 2 for %s" + System.lineSeparator(), description, varOne, varTwo);
      var = scan.nextInt();
      switch (var) {
        case 1:
          System.out.printf("you have chosen %s" + System.lineSeparator(), varOne);
          return var;
        case 2:
          System.out.printf("you have chosen %s" + System.lineSeparator(), varTwo);
          return var;
        default:
          System.out.println(var + " is an invalid choice");
      }
    }
    while (true);
  }
}

Upvotes: 1

Bentaye
Bentaye

Reputation: 9756

It is always a good idea to split things up, instead of making nested loops. Here is a simple way to split the program in 3 methods, each one dealing with a choice.

Hero choice: Offer both choices and loop until given a valid answer. Then return the answer

private static int queryHero() {
    Scanner scan = new Scanner(System.in);
    int hero;
    while (true) {
        System.out.println("Choose your hero: 1 for Warrior, 2 for Mage");
        hero = scan.nextInt();
        if(hero == 1 || hero == 2) {
            break;
        } else {
            System.out.println(hero + " is not a valid choice");
        }
    }
    return hero;
}

Travel option choice: Offer choices depending on the chosen hero and loop until given a valid answer. Then return the answer

private static int queryTravelOptionForHero(int hero) {
    Scanner scan = new Scanner(System.in);
    int travelOption;
    while (true) {
        if (hero == 1) {
            System.out.println("Choose your travel option: 1 for Horse");
            travelOption = scan.nextInt();
            if (travelOption == 1) {
                break;
            } else {
                System.out.println(travelOption + " is not a valid choice");
            }
        } else if (hero == 2) {
            System.out.println("Choose your travel option: 1 for Horse; 2 for Teleportation");
            travelOption = scan.nextInt();
            if (travelOption == 1 || travelOption == 2) {
                break;
            } else {
                System.out.println(travelOption + " is not a valid choice");
            }
        }
    }
    return travelOption;
}

Weapon choice: Offer choices depending on the chosen hero and loop until given a valid answer. Then return the answer

private static int queryWeaponForHero(int hero) {
    Scanner scan = new Scanner(System.in);
    int weapon;
    while (true) {
        if(hero == 1) {
            System.out.println("Choose your weapon: 1 for Sword; 2 for Staff");
            weapon = scan.nextInt();
            if (weapon == 1 || weapon == 2) {
                break;
            } else {
                System.out.println(weapon + " is not a valid choice");
            }
        } else if(hero == 2) {
            System.out.println("Choose your weapon: 2 for Staff");
            weapon = scan.nextInt();
            if(weapon == 2) {
                break;
            }else {
                System.out.println(weapon + " is not a valid choice");
            }
        }

    }
    return weapon;
}

Then in your main:

int hero = queryHero();
int travelOption = queryTravelOptionForHero(hero);
int weapon = queryWeaponForHero(hero);

System.out.println("hero: " + hero);
System.out.println("travelOption: " + travelOption);
System.out.println("weapon: " + weapon);

Note: I am not sure if you know about them, but there are ways to make this code nicer using enums and Lists

Upvotes: 1

Alon Adler
Alon Adler

Reputation: 4024

Your flow can be written as a simple procedural code. As so, I would write it in the most simple form I can - at least as a start.

There is no real justification for using switch labels and loops inside loops

Just write 3 simple loops, one after another - It will be simple to read, understand and debug.

I dont want to write the code for you, it is not the purpose of this site, but here's a Pseudo code:

Loop 1 (selecting heroes)

If(heroes != Warrior)
    Loop 2 (selecting travel)
else travel=Horse

Loop 3 (selecing weapon)

Upvotes: 1

Related Questions