如何将两个Java猜数字/猜字母游戏合并到单个类中并实现选择菜单?
两种方案都可行,但推荐用多类结构(更易维护)
先直接回答你的问题:你既可以把所有代码整合到单个类里,也可以保留多个类并新增一个菜单类来调度。从代码可维护性、可读性的角度出发,强烈建议保留多个独立的游戏类,再写一个主菜单类来负责用户交互和游戏启动——这样每个类只专注做一件事,后续要修改某个游戏逻辑或者新增游戏时,改动会更清晰。
方案一:推荐的多类结构(清晰易维护)
步骤1:改造现有游戏类
把两个游戏类的main方法改成静态的play()方法(静态方法更方便直接调用),同时修复原代码里的小bug(比如GuessTheNumber中playAgain的空循环不会重新启动游戏):
改造后的GuessTheNumber.java
import java.util.Scanner; public class GuessTheNumber { public static void play() { Scanner scan = new Scanner(System.in); String playAgain; do { System.out.println("Guess a number between 1 and 100:"); int theNumber = (int)(Math.random() * 100 + 1); int numberOfTries = 0; int guess = 0; while (guess != theNumber) { guess = scan.nextInt(); numberOfTries++; if (guess < theNumber) System.out.println(guess + " is too low. Try again."); else if (guess > theNumber) System.out.println(guess + " is too high. Try again."); else { System.out.println(guess + " is correct. You win!"); System.out.println("It only took you " + numberOfTries + " tries! Good work!"); } } System.out.println("Would you like to play again (y/n)?"); playAgain = scan.next(); } while (playAgain.equalsIgnoreCase("y")); System.out.println("Thank you for playing Guess The Number! Goodbye."); // 不要在这里关闭scan,主菜单还要复用输入流 // scan.close(); } }
改造后的GuessTheLetter.java
import java.util.Scanner; public class GuessTheLetter { public static void play() { Scanner scan = new Scanner(System.in); String playAgain; do { System.out.println("Guess the Letter"); char randomLetter = (char) (Math.random() * 26 + 65); char enteredLetter = 0; int numberOfTries = 0; // 把次数放到循环内,重新游玩时重置计数 while(true){ enteredLetter = Character.toUpperCase(scan.next().charAt(0)); numberOfTries++; if(enteredLetter == randomLetter) { System.out.println("Correct Guess"); System.out.println("The letter is:" + randomLetter); System.out.println("It only took you " + numberOfTries + " tries! Good work!"); break; } else if(enteredLetter > randomLetter) { System.out.println("Incorrect Guess"); System.out.println("The letter entered is too high"); } else if(enteredLetter < randomLetter) { System.out.println("Incorrect Guess"); System.out.println("The letter entered is too low"); } } System.out.println("Would you like to play again (y/n)?"); playAgain = scan.next(); } while (playAgain.equalsIgnoreCase("y")); System.out.println("Thank you for playing Guess The Letter! Goodbye."); // 同样不要关闭scan // scan.close(); } }
步骤2:新增主菜单类GameMenu.java
这个类负责显示菜单、接收用户输入,并根据选择启动对应游戏:
import java.util.Scanner; public class GameMenu { public static void main(String[] args) { Scanner scan = new Scanner(System.in); String choice; do { System.out.println("Hello! Type 'letter' or 'number' to choose game."); System.out.println("Type 'quit' to exit."); choice = scan.next().toLowerCase(); switch(choice) { case "number": GuessTheNumber.play(); break; case "letter": GuessTheLetter.play(); break; case "quit": System.out.println("Goodbye!"); break; default: System.out.println("Invalid choice! Please enter 'letter', 'number', or 'quit'."); } } while (!choice.equalsIgnoreCase("quit")); scan.close(); } }
方案二:整合到单个类(快速实现,但不推荐长期使用)
如果只是想快速整合测试,也可以把两个游戏的逻辑封装成单个类里的方法,然后在main方法里做菜单调度:
import java.util.Scanner; public class CombinedGames { public static void main(String[] args) { Scanner scan = new Scanner(System.in); String choice; do { System.out.println("Hello! Type 'letter' or 'number' to choose game."); System.out.println("Type 'quit' to exit."); choice = scan.next().toLowerCase(); switch(choice) { case "number": playGuessTheNumber(scan); break; case "letter": playGuessTheLetter(scan); break; case "quit": System.out.println("Goodbye!"); break; default: System.out.println("Invalid choice! Please try again."); } } while (!choice.equalsIgnoreCase("quit")); scan.close(); } private static void playGuessTheNumber(Scanner scan) { String playAgain; do { System.out.println("Guess a number between 1 and 100:"); int theNumber = (int)(Math.random() * 100 + 1); int numberOfTries = 0; int guess = 0; while (guess != theNumber) { guess = scan.nextInt(); numberOfTries++; if (guess < theNumber) System.out.println(guess + " is too low. Try again."); else if (guess > theNumber) System.out.println(guess + " is too high. Try again."); else { System.out.println(guess + " is correct. You win!"); System.out.println("It only took you " + numberOfTries + " tries! Good work!"); } } System.out.println("Would you like to play again (y/n)?"); playAgain = scan.next(); } while (playAgain.equalsIgnoreCase("y")); System.out.println("Thank you for playing Guess The Number!"); } private static void playGuessTheLetter(Scanner scan) { String playAgain; do { System.out.println("Guess the Letter"); char randomLetter = (char) (Math.random() * 26 + 65); char enteredLetter = 0; int numberOfTries = 0; while(true){ enteredLetter = Character.toUpperCase(scan.next().charAt(0)); numberOfTries++; if(enteredLetter == randomLetter) { System.out.println("Correct Guess"); System.out.println("The letter is:" + randomLetter); System.out.println("It only took you " + numberOfTries + " tries! Good work!"); break; } else if(enteredLetter > randomLetter) { System.out.println("Incorrect Guess"); System.out.println("The letter entered is too high"); } else if(enteredLetter < randomLetter) { System.out.println("Incorrect Guess"); System.out.println("The letter entered is too low"); } } System.out.println("Would you like to play again (y/n)?"); playAgain = scan.next(); } while (playAgain.equalsIgnoreCase("y")); System.out.println("Thank you for playing Guess The Letter!"); } }
关键注意点
- Scanner的关闭:如果用多类结构,不要在游戏类里关闭Scanner,否则主菜单的输入流会被强制关闭,导致无法读取后续输入。统一在主菜单类结束时关闭即可。
- 代码维护性:多类结构的优势在于,后续修改某个游戏规则时,只需要改动对应的游戏类,不会影响菜单或另一个游戏的逻辑,扩展性更强。
- 循环逻辑修复:原
GuessTheNumber里的while (playAgain.equalsIgnoreCase("y"));是一个空循环,无法实现“再次游玩”的功能,改成do-while结构才能正确循环。
内容的提问来源于stack exchange,提问作者Henzi
相关产品推荐
相关产品推荐

