我使用 Java 制作的菜单中的无限循环
Infinite loop in a menu I made using Java
下面是代码。我有一个 switch 语句,以便用户可以在打印出的给定选项之间输入他们的选择。当我输入 2、3 或任何其他数字时,它工作正常。但是一旦我 select 第一个选项(玩游戏),它就会转到那个方法并且工作正常。但是一旦方法结束并且 case 中断编译器 returns 到 while 循环的顶部并且不会让用户选择另一个选项。相反,它会再次选择第一个选项并继续这个无限循环。我该如何解决这个问题?
package rockPaperScissors;
import java.util.Random;
import java.util.Scanner;
public class RockPaperScissors {
public static void main(String[] args) {
System.out.println("Welcome to Rock Paper Scissors!");
Scores scores = new Scores(); //Object that holds two integers and allows you to increment them
Scanner playerChoice = new Scanner(System.in);
int option = 0;
do{
System.out.println("Select an option!");
System.out.println("1: Play the game");
System.out.println("2: Check the score");
System.out.println("3: Quit the game");
option = playerChoice.nextInt(); /*Shouldn't this line stop and let me
enter another option for the menu? */
switch(option) {
case 1: playGame(scores);
break;
case 2: getScore(scores);
break;
case 3: System.out.println("Thanks for playing!");
break;
default: System.out.println("You must pick one of given options\n");
break;
}
} while(option != 3);
playerChoice.close();
}
我觉得奇怪的是,这里的这段代码完全符合我的要求,但它们本质上是一样的:
import java.util.Scanner;
public class Menu {
public static void main(String[] args) {
System.out.println("Welcome to a simple menu that does nothing!\n");
Scanner input = new Scanner(System.in);
int menuChoice;
do{
System.out.println("Please select an option!\n");
System.out.println("1: This does nothing");
System.out.println("2: This also does nothing");
System.out.println("3: You guessed it, it does nothing");
System.out.println("4: Quit\n");
menuChoice = input.nextInt();
switch(menuChoice){
case 1: System.out.println("You chose option 1");
break;
case 2: System.out.println("You chose option 2");
break;
case 3: System.out.println("You chose option 3");
break;
case 4: System.out.println("Goodbye!");
break;
default: System.out.println("ENTER A VALID INPUT");
}
}while(menuChoice != 4);
input.close();
}
}
编辑:
所以 playGame 是一种实际处理游戏中剪刀石头布部分的方法。
private static Scores playGame(Scores scores) {
System.out.println("Pick either rock, paper, or scissors");
//The player makes a choice
Scanner scanner = new Scanner(System.in);
String playerDecision = "";
if(scanner.hasNextLine()){
playerDecision = scanner.nextLine();
}
//Check to see if the player chose one of the given options
if(playerDecision.equalsIgnoreCase("rock") == false && playerDecision.equalsIgnoreCase("paper") == false && playerDecision.equalsIgnoreCase("scissors") == false){
System.out.println("You must select either rock, paper, or scissors");
scanner.close();
return scores;
}
//The computer makes a random choice
Random random = new Random();
String gameArray[] = {"rock", "paper", "scissors"};
int randNum = random.nextInt(3);
String computerChoice = gameArray[randNum];
System.out.println("You chose: " + playerDecision + "\nThe computer choice: " + computerChoice);
if(playerDecision.equalsIgnoreCase(computerChoice)){ //If it's a tie
System.out.println("It's a tie!");
scanner.close();
return scores;
} else if(playerDecision.equalsIgnoreCase("rock")){ //If the player chooses rock
if(computerChoice.equalsIgnoreCase("paper")){ //If the computer chooses paper
System.out.println("The computer wins!");
scores.incrementComputerScore();
scanner.close();
return scores;
} else if(computerChoice.equalsIgnoreCase("scissors")){ //If the computer chooses scissors
System.out.println("You win!");
scores.incrementPlayerScore();
scanner.close();
return scores;
}
} else if(playerDecision.equalsIgnoreCase("paper")){ //If the player chooses paper
if(computerChoice.equalsIgnoreCase("rock")){ //If the computer chooses rock
System.out.println("You win!");
scores.incrementPlayerScore();
scanner.close();
return scores;
}else if(computerChoice.equalsIgnoreCase("scissors")){ //If the computer chooses scissor
System.out.println("The computer wins!");
scores.incrementComputerScore();
scanner.close();
return scores;
}
} else if(playerDecision.equalsIgnoreCase("scissors")){ //If the player chooses scissors
if(computerChoice.equalsIgnoreCase("rock")){ //If the computer chooses rock
System.out.println("The computer wins!");
scores.incrementComputerScore();
scanner.close();
return scores;
}else if(computerChoice.equalsIgnoreCase("paper")){ //If the computer chooses paper
System.out.println("You win!");
scores.incrementPlayerScore();
scanner.close();
return scores;
}
}
scanner.close();
return scores;
}
您正在使用 playgame()
方法关闭扫描器,通过关闭扫描器,您也关闭了用于构造它的输入流。 Scanner.close()
的 javadoc 对此进行了解释
因为程序的输入流现已关闭,您的主循环不会 return 对您的 scanner.nextInt()
有任何意义的完整信息(hasNextInt()
现在 return false) 并且由于扫描仪的当前实现,它将 return 最后一个有效值。
要解决问题,您可以使用多种解决方案。
通过扫描仪玩游戏(推荐)
通过向接受原始扫描仪的 playgame 添加参数,可以防止它需要在 playgame 主体内关闭的事实
public void playGame(Score scores, Scanner scan) { // change arguments of constructor
....
// scanner.close() // Drop this line too
}
没有关闭游戏内的扫描仪
还有另一种方法可以解决这个问题,那就是不在 playgame 方法中关闭扫描器,但是不推荐这样做,因为扫描器可能会在流上预读并消耗针对主菜单的字节,这个问题是您的用户交互用例真的很大。
下面是代码。我有一个 switch 语句,以便用户可以在打印出的给定选项之间输入他们的选择。当我输入 2、3 或任何其他数字时,它工作正常。但是一旦我 select 第一个选项(玩游戏),它就会转到那个方法并且工作正常。但是一旦方法结束并且 case 中断编译器 returns 到 while 循环的顶部并且不会让用户选择另一个选项。相反,它会再次选择第一个选项并继续这个无限循环。我该如何解决这个问题?
package rockPaperScissors;
import java.util.Random;
import java.util.Scanner;
public class RockPaperScissors {
public static void main(String[] args) {
System.out.println("Welcome to Rock Paper Scissors!");
Scores scores = new Scores(); //Object that holds two integers and allows you to increment them
Scanner playerChoice = new Scanner(System.in);
int option = 0;
do{
System.out.println("Select an option!");
System.out.println("1: Play the game");
System.out.println("2: Check the score");
System.out.println("3: Quit the game");
option = playerChoice.nextInt(); /*Shouldn't this line stop and let me
enter another option for the menu? */
switch(option) {
case 1: playGame(scores);
break;
case 2: getScore(scores);
break;
case 3: System.out.println("Thanks for playing!");
break;
default: System.out.println("You must pick one of given options\n");
break;
}
} while(option != 3);
playerChoice.close();
}
我觉得奇怪的是,这里的这段代码完全符合我的要求,但它们本质上是一样的:
import java.util.Scanner;
public class Menu {
public static void main(String[] args) {
System.out.println("Welcome to a simple menu that does nothing!\n");
Scanner input = new Scanner(System.in);
int menuChoice;
do{
System.out.println("Please select an option!\n");
System.out.println("1: This does nothing");
System.out.println("2: This also does nothing");
System.out.println("3: You guessed it, it does nothing");
System.out.println("4: Quit\n");
menuChoice = input.nextInt();
switch(menuChoice){
case 1: System.out.println("You chose option 1");
break;
case 2: System.out.println("You chose option 2");
break;
case 3: System.out.println("You chose option 3");
break;
case 4: System.out.println("Goodbye!");
break;
default: System.out.println("ENTER A VALID INPUT");
}
}while(menuChoice != 4);
input.close();
}
}
编辑:
所以 playGame 是一种实际处理游戏中剪刀石头布部分的方法。
private static Scores playGame(Scores scores) {
System.out.println("Pick either rock, paper, or scissors");
//The player makes a choice
Scanner scanner = new Scanner(System.in);
String playerDecision = "";
if(scanner.hasNextLine()){
playerDecision = scanner.nextLine();
}
//Check to see if the player chose one of the given options
if(playerDecision.equalsIgnoreCase("rock") == false && playerDecision.equalsIgnoreCase("paper") == false && playerDecision.equalsIgnoreCase("scissors") == false){
System.out.println("You must select either rock, paper, or scissors");
scanner.close();
return scores;
}
//The computer makes a random choice
Random random = new Random();
String gameArray[] = {"rock", "paper", "scissors"};
int randNum = random.nextInt(3);
String computerChoice = gameArray[randNum];
System.out.println("You chose: " + playerDecision + "\nThe computer choice: " + computerChoice);
if(playerDecision.equalsIgnoreCase(computerChoice)){ //If it's a tie
System.out.println("It's a tie!");
scanner.close();
return scores;
} else if(playerDecision.equalsIgnoreCase("rock")){ //If the player chooses rock
if(computerChoice.equalsIgnoreCase("paper")){ //If the computer chooses paper
System.out.println("The computer wins!");
scores.incrementComputerScore();
scanner.close();
return scores;
} else if(computerChoice.equalsIgnoreCase("scissors")){ //If the computer chooses scissors
System.out.println("You win!");
scores.incrementPlayerScore();
scanner.close();
return scores;
}
} else if(playerDecision.equalsIgnoreCase("paper")){ //If the player chooses paper
if(computerChoice.equalsIgnoreCase("rock")){ //If the computer chooses rock
System.out.println("You win!");
scores.incrementPlayerScore();
scanner.close();
return scores;
}else if(computerChoice.equalsIgnoreCase("scissors")){ //If the computer chooses scissor
System.out.println("The computer wins!");
scores.incrementComputerScore();
scanner.close();
return scores;
}
} else if(playerDecision.equalsIgnoreCase("scissors")){ //If the player chooses scissors
if(computerChoice.equalsIgnoreCase("rock")){ //If the computer chooses rock
System.out.println("The computer wins!");
scores.incrementComputerScore();
scanner.close();
return scores;
}else if(computerChoice.equalsIgnoreCase("paper")){ //If the computer chooses paper
System.out.println("You win!");
scores.incrementPlayerScore();
scanner.close();
return scores;
}
}
scanner.close();
return scores;
}
您正在使用 playgame()
方法关闭扫描器,通过关闭扫描器,您也关闭了用于构造它的输入流。 Scanner.close()
因为程序的输入流现已关闭,您的主循环不会 return 对您的 scanner.nextInt()
有任何意义的完整信息(hasNextInt()
现在 return false) 并且由于扫描仪的当前实现,它将 return 最后一个有效值。
要解决问题,您可以使用多种解决方案。
通过扫描仪玩游戏(推荐)
通过向接受原始扫描仪的 playgame 添加参数,可以防止它需要在 playgame 主体内关闭的事实
public void playGame(Score scores, Scanner scan) { // change arguments of constructor
....
// scanner.close() // Drop this line too
}
没有关闭游戏内的扫描仪 还有另一种方法可以解决这个问题,那就是不在 playgame 方法中关闭扫描器,但是不推荐这样做,因为扫描器可能会在流上预读并消耗针对主菜单的字节,这个问题是您的用户交互用例真的很大。