Java初学者项目实战:实现一个简单的猜数字游戏

用Random生成[min,max]整数应写random.nextInt(max-min+1)+min;猜数字游戏正确范围是random.nextInt(100)+1;nextInt()后需nextLine()清缓冲区或统一用nextLine()+parseInt;多次对局宜封装playOneRound()并用while(true)+break控制。

怎么用 java.util.Random 生成真正随机的整数范围?

很多初学者直接写 random.nextInt(100),以为能生成 1–100 的数,结果发现是 0–99。关键在「范围偏移」:要生成 [min, max](含两端)的整数,必须写成 random.nextInt(max - min + 1) + min

  • 猜数字游戏通常要 1–100,所以正确写法是 random.nextInt(100) + 1
  • 别用 Math.random() 转换,它返回 double,易因类型截断出错(比如 (int)(Math.random() * 100) + 1 理论上可能因浮点误差少覆盖一个值)
  • 每次 new 一个 Random 实例没问题,但不要在循环里反复 new——不是性能问题,而是如果循环太快,System.currentTimeMillis() 作为默认种子可能重复,导致“伪随机”序列相同

为什么 Scanner.nextLine() 在读数字后会跳过输入?

这是新手最常卡住的地方:用 scanner.nextInt() 读完用户猜的数字,紧接着调用 scanner.nextLine() 想读“是否继续”,结果直接跳过,程序像卡住一样。

  • 根本原因是 nextInt() 只消费数字字符,不消费回车符(\n),而 nextLine() 会立刻读取这个残留的换行,返回空字符串
  • 修复方法只有两个:统一用 nextLine() + Integer.parseInt(),或者在 nextInt() 后加一句 scanner.nextLine() 清掉缓冲区
  • 推荐前者,代码更一致,也避免后续加其他输入时反复踩坑

如何让游戏支持多次对局而不重启程序?

单次运行只玩一局太挫,但直接套 while 循环容易逻辑缠绕,尤其“是否继续”的判断位置不对,会导致多猜一次或漏提示。

  • 把单局逻辑封装成独立方法 playOneRound(),返回 boolean 表示是否继续
  • 主循环用 while (true) + break 控制,比用布尔变量控制更清晰(避免初始值、赋值时机等干扰)
  • 注意:用户输错格式(如输字母)时,nextInt() 会抛 InputMismatchException,必须用 try-catch 捕获并调用 scanner.nextLine() 清缓冲区,否则异常后所有输入都会乱
import java.util.Random;
import java.util.Scanner;

public class GuessNumber { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Random random = new Random();

    while (true) {
        int target = random.nextInt(100) + 1;
        System.out.println("我已经想好了一个 1 到 100 的数字,开始猜吧!");

        int guess;
        int attempts = 0;
        while (true) {
            System.out.print("请输入你的猜测:");
            try {
                guess = Integer.parseInt(scanner.nextLine().trim());
                attempts++;
            } catch (NumberFormatException e) {
                System.out.println("❌ 请输入一个有效的整数!");
                continue;
            }

            if (guess == target) {
                System.out.println("✅ 恭喜你,猜对了!用了 " + attempts + " 次。");
                break;
            } else if (guess < target) {
                System.out.println("? 太小了,再试试!");
            } else {
                System.out.println("? 太大了,再试试!");
            }
        }

        System.out.print("还想再玩一局吗?(y/n):");
        String again = scanner.nextLine().trim();
        if (!again.equalsIgnoreCase("y") && !again.equalsIgnoreCase("yes")) {
            break;
        }

} System.out.println("谢谢游玩,再见!"); scanner.close(); }

}

最后提醒一句:别急着加难度等级、历史记录这些功能。先确保 nextInt()nextLine() 的配合不出错,再跑通完整流程——多数人调试半天,其实就卡在那一行没清缓冲区。