You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java猜数字游戏ArrayList重复添加相同输入问题排查

Java猜数字游戏ArrayList历史记录重复显示问题修复

问题背景

使用Java开发数字版刽子手猜数字游戏,核心规则如下:

  • 计算机在0-1000区间生成随机目标数字,开局需明确告知玩家猜测范围
  • 玩家单局最多拥有10次猜测机会
  • 每完成1次有效猜测,剩余猜测次数减1
  • 每次玩家提交新猜测前,系统需展示全部历史猜测记录
  • 猜测正确直接判定获胜结束;猜测值大于目标数字提示「你的猜测偏大」,小于目标数字提示「你的猜测偏小」
  • 无效输入(含字母、符号、重复猜测已猜数字)首次触发给予警告,第二次触发直接扣除1次猜测机会

当前代码可启动运行,但存在历史记录展示异常:每次展示历史猜测数字时始终重复显示同一个数值,初步判断新输入未正确存入ArrayList,仅重复读取首次输入内容,问题原始代码如下:

import java.util.*;
import java.lang.*;
public class NumberGuess {
    public static void main(String[] args) {
        int tries = 10;
        ArrayList<Integer> guessed = new ArrayList();
        int warnings = 2;
        int i = 0;
        Random rand = new Random();
        int random = rand.nextInt(1000);
        private void StartMenu () {
            System.out.println("\" Welcome to the Number guessing game!\n I am thinking of a number between 0-1000\n You have 1 warning.\n You have 1 warning.\n ------------ ");
        }
        public char[] ToCharacterArray (String input){
            char arr[] = new char[input.length()];
            arr = input.toCharArray();
            return arr;
        }
        public boolean CheckInput ( char arr[]){
            if (Character.isDigit(arr[0])) {
                return true;
            } else {
                return false;
            }
        }
        String input;
        while (tries > 0 && warnings > 0) {
            System.out.println("You have " + tries + " guesses left.");
            if (tries == 10) {
                System.out.println("guessed number: ");
            } else {
                System.out.println("guessed number: ");
                for (Integer a : guessed) {
                    System.out.println(guessed.get(i));
                }
            }
            System.out.println("Please guess a number:");
            Scanner sc = new Scanner(System.in);
            input = sc.next();
            char InputString[] = ToCharacterArray(input);
            if (CheckInput(InputString)) {
                int intInput = Integer.parseInt(input);
                guessed.add(intInput);
                if (intInput > random) {
                    System.out.println("Your guess is greater");
                }
                if (intInput < random) {
                    System.out.println("Your guess is smaller");
                }
                if (intInput == random) {
                    System.out.println("Congrats! You win.");
                    System.out.println("The guessed number is: " + intInput);
                    tries = -1;
                }
            }
            tries--;
        }
    }
}

核心问题定位

  1. 直接导致历史记录重复的根因:遍历历史记录时用了for-each循环,但循环内未使用遍历得到的元素a,反而一直用初始值为0的固定索引i调用guessed.get(i),i从未自增,所以每次都只读取列表第一个元素(也就是第一次存入的猜测值),看起来就像所有记录都是同一个数。
  2. 语法错误:Java不允许在方法内部定义其他方法,你写的StartMenu/ToCharacterArray/CheckInput三个方法全部定义在main方法内部,本身不符合语法规范。
  3. 输入校验逻辑缺陷:现有校验仅判断输入首字符是否为数字,后续字符包含字母/符号时仍会被判定为合法,调用Integer.parseInt时会直接抛异常;且未实现重复猜测的校验逻辑。
  4. 逻辑不匹配需求:
    • 随机数生成范围错误:rand.nextInt(1000)生成的是0-999的整数,不符合0-1000的区间要求
    • 次数扣减逻辑错误:无论输入是否合法都会执行tries--,不符合「有效猜测才扣次数、非法输入第二次才扣次数」的规则
    • 开局菜单方法从未被调用,且提示文本重复
    • 每次循环都新建Scanner对象,存在资源浪费
    • 10次机会用完后未做失败判定提示

修复后完整代码

import java.util.*;

public class NumberGuess {
    private static int tries = 10;
    private static final ArrayList<Integer> guessed = new ArrayList<>();
    private static int warnings = 1;
    private static final Random rand = new Random();
    private static final int target = rand.nextInt(1001); // 生成0-1000的目标数字
    private static final Scanner sc = new Scanner(System.in);

    // 开局菜单
    private static void startMenu() {
        System.out.println("Welcome to the Number guessing game!");
        System.out.println("I am thinking of a number between 0-1000");
        System.out.println("You have " + tries + " guesses total.");
        System.out.println("Invalid input will give you 1 warning first, second invalid input will cost 1 guess.");
        System.out.println("------------");
    }

    // 校验输入是否为纯数字
    private static boolean isNumeric(String input) {
        if (input == null || input.isEmpty()) {
            return false;
        }
        for (char c : input.toCharArray()) {
            if (!Character.isDigit(c)) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        startMenu();
        while (tries > 0) {
            System.out.println("\nYou have " + tries + " guesses left.");
            // 展示历史猜测记录
            System.out.print("Already guessed numbers: ");
            if (guessed.isEmpty()) {
                System.out.println("None");
            } else {
                // 修复遍历bug,直接输出遍历到的元素
                for (Integer num : guessed) {
                    System.out.print(num + " ");
                }
                System.out.println();
            }

            System.out.println("Please guess a number:");
            String input = sc.next();

            // 校验输入合法性
            if (!isNumeric(input)) {
                if (warnings > 0) {
                    System.out.println("Invalid input! You have " + warnings + " warning left, please enter a valid integer.");
                    warnings--;
                    continue;
                } else {
                    System.out.println("Invalid input! You have no warning left, cost 1 guess.");
                    tries--;
                    continue;
                }
            }

            int guess = Integer.parseInt(input);
            // 校验是否重复猜测
            if (guessed.contains(guess)) {
                if (warnings > 0) {
                    System.out.println("You already guessed " + guess + "! You have " + warnings + " warning left.");
                    warnings--;
                    continue;
                } else {
                    System.out.println("You already guessed " + guess + "! No warning left, cost 1 guess.");
                    tries--;
                    continue;
                }
            }

            // 有效猜测,加入历史记录,扣减次数
            guessed.add(guess);
            tries--;

            // 判断猜测结果
            if (guess == target) {
                System.out.println("Congrats! You win.");
                System.out.println("The correct number is: " + target);
                sc.close();
                return;
            } else if (guess > target) {
                System.out.println("你的猜测偏大");
            } else {
                System.out.println("你的猜测偏小");
            }
        }
        // 次数用完失败
        System.out.println("\nYou have no guesses left, game over!");
        System.out.println("The correct number is: " + target);
        sc.close();
    }
}

内容的提问来源于stack exchange,提问作者Mr.Robot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 17:15:42