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

Java版Craps游戏循环中断抛出异常问题求助

问题排查与修复方案

你的代码存在几个关键问题导致循环无法正常中断、抛出异常,以下是具体分析和修复措施:

问题根源

  1. Scanner输入缓冲区残留换行符:in.nextInt()读取整数后,输入的换行符会留在缓冲区,后续in.nextLine()会直接读取空字符串,导致用户输入"n"时无法被正确识别,甚至引发输入异常。
  2. 格式化字符串错误:gameOver方法中的printf语句使用了错误的格式符%.2%,正确格式应为%.2f%%,这会直接抛出IllegalFormatConversionException运行时异常。
  3. 循环中断逻辑不严谨:余额不足时直接用break跳出,但后续仍可能执行输入处理代码;用户输入"n"时同样用break,未确保循环条件正确更新。
  4. 输入处理分支缺陷:无效输入仅处理一次,若用户再次输入错误字符会直接跳过,导致playAgain状态错误。
  5. rollWithPoint规则逻辑错误:初始掷骰结果未被判断就进入循环,导致多掷一次骰子,违反Craps游戏规则。

修复步骤

1. 修复Scanner输入问题

每次调用in.nextInt()后,添加in.nextLine()清空缓冲区的换行符,确保后续in.nextLine()能读取到用户实际输入的内容。

2. 修正格式化字符串

将gameOver中的printf语句修改为:

System.out.printf("Based on your play, the probability of winning is %.2f%%", winPercent);

3. 优化循环中断逻辑

  • 循环条件直接改为playAgain && total >= 10,避免余额不足时进入游戏流程。
  • 余额不足时设置playAgain = false并跳过后续输入询问,让循环自然退出。
  • 用户输入"n"时设置playAgain = false,而非直接break,确保循环正常结束并执行gameOver。

4. 完善输入处理

将无效输入的处理改为循环,直到用户输入有效的y/Y或n/N。

5. 修正rollWithPoint规则

在进入循环前先判断第一次掷骰结果,避免重复掷骰:

public static boolean rollWithPoint(int point) {
    int total = rollDice();
    if (total == point) return true;
    if (total ==7) return false;
    while(true) {
        total = rollDice();
        if (total == point) return true;
        if (total ==7) return false;
    }
}

完整修复代码

import java.util.Random;
import java.util.Scanner;

public class GameOfCrapsTester {
    
    static Scanner in = new Scanner(System.in);
    static Random rand = new Random();

    public static void main(String[] args) {
        
        System.out.println("Welcome to the game of Craps");
        System.out.println(" ");
        System.out.println("The house has given you a starting balance of $500");
        System.out.println("On each round, you will make a whole number wager.");
        System.out.println("The minimum wager is $10, and the maximum wager is your remaining balance.");
        System.out.println(" ");
        System.out.println("You may keep playing until you decide to cash in, or");
        System.out.println("    you can't cover the minimum wager.");
        System.out.println("Good Luck!");
        
        boolean win;
        double wins = 0, numOfGames = 0;
        int total = 500;    

        int pointValue = 0;
        boolean playAgain = true;
        // 循环条件直接判断余额是否满足最低赌注
        while (playAgain && total >= 10)
        {
            System.out.println(" ");
            System.out.println("Your balance is $" + total);
            System.out.println(" ");
            System.out.println("Place your bet: $");
            
            int bet = in.nextInt();
            in.nextLine(); // 清空换行符
            while (bet > total || bet < 10)
            {
                if (bet < 10)
                {
                    System.out.println("Bet must be larger than $10.");
                }
                System.out.println("I'm sorry, that's not a valid wager; please re-enter: ");
                bet = in.nextInt();
                in.nextLine(); // 清空换行符
            }
            int num = rollDice();
            // 移除num==0的无效判断(掷骰结果不可能为0)
            if ((num >= 4 && num <= 10 && num != 7))
            {
                pointValue = num; 
                System.out.println(" ");
                System.out.println("Your point value is " + pointValue);
                System.out.println(" ");
                win = rollWithPoint(pointValue);
                
                if (win)
                {
                    total = wonGame(bet, total);
                    wins++;
                    numOfGames++;
                    System.out.println("Wins: " + wins + " Number of games: " + numOfGames);
                }
                else
                {
                    total = lostGame(bet, total);
                    numOfGames++;
                    System.out.println("Wins: " + wins + " Number of games: " + numOfGames);
                }   
            }
            else if (num == 7 || num == 11)
            {
                total = wonGame(bet, total);
                wins++;
                numOfGames++;
                System.out.println("Wins: " + wins + " Number of games: " + numOfGames);
            }
            else
            {
                total = lostGame(bet, total);
                numOfGames++;
                System.out.println("Wins: " + wins + " Number of games: " + numOfGames);
            }
            
            // 余额不足时标记退出,跳过输入询问
            if (total < 10)
            {
                playAgain = false;
                continue;
            }
            
            // 循环处理输入直到有效
            boolean validInput = false;
            while (!validInput) {
                System.out.println("Keep playing (y/Y or n/N)? ");
                String again = in.nextLine();
                
                if (again.equalsIgnoreCase("y"))
                {
                    playAgain = true;
                    validInput = true;
                }
                else if (again.equalsIgnoreCase("n"))
                {
                    playAgain = false;
                    validInput = true;
                }
                else
                {
                    System.out.println("Invalid character input, try again:");
                }
            }
        }// end of loop
        
        gameOver(wins, numOfGames);
        
    } // END of main
    
    public static int rollDice() {
        
        int dice1, dice2, total;
        dice1 = rand.nextInt(6) + 1;
        dice2 = rand.nextInt(6) + 1;
        total = dice1 + dice2;
        System.out.print("Your roll: ");
        System.out.print("Dice1: " + dice1);
        System.out.print(", Dice2: " + dice2);
        System.out.println("; Roll Value: " + total);
        return total;
        
    } // END of rollDice
    
    public static boolean rollWithPoint(int point) {
        
        int total = rollDice();
        // 先判断第一次掷骰结果
        if (total == point) {
            return true;
        } else if (total == 7) {
            return false;
        }
        // 循环直到分出胜负
        while (true) {
            total = rollDice();
            if (total == point) {
                return true;
            } else if (total == 7) {
                return false;
            }
        }
    } // END of rollWithPoint

    public static int lostGame(int bet, int total) {
        
        System.out.println("Oh, I'm sorry, you lost.");
        System.out.println(" ");
        total = total - bet;
        System.out.println("Your current balance: $" + total);
        System.out.println(" ");
        return total;
        
    } // END of lostGame
    
    public static int wonGame(int bet, int total) {
        
        System.out.println("A winner!");
        System.out.println(" ");
        total = total + bet;
        System.out.println("Your current balance: $" + total);
        System.out.println(" ");
        return total;
        
    } // END of wonGame
    
    public static void gameOver(double win, double tot) {
        
        double winPercent = (win / tot) * 100;
        System.out.println(" ");
        // 修复格式化字符串
        System.out.printf("Based on your play, the probability of winning is %.2f%%", winPercent);
        System.out.println(" ");
        System.out.println("Seems you lost your shirt; better luck next time.");
        System.out.println("Have a nice day! Hope to see you soon!");
        
    } // END of gameOver
    
} // END of GameOfCraps

内容的提问来源于stack exchange,提问作者RJ Storr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:15:48