Java版Craps游戏循环中断抛出异常问题求助
问题排查与修复方案
你的代码存在几个关键问题导致循环无法正常中断、抛出异常,以下是具体分析和修复措施:
问题根源
- Scanner输入缓冲区残留换行符:
in.nextInt()读取整数后,输入的换行符会留在缓冲区,后续in.nextLine()会直接读取空字符串,导致用户输入"n"时无法被正确识别,甚至引发输入异常。 - 格式化字符串错误:
gameOver方法中的printf语句使用了错误的格式符%.2%,正确格式应为%.2f%%,这会直接抛出IllegalFormatConversionException运行时异常。 - 循环中断逻辑不严谨:余额不足时直接用
break跳出,但后续仍可能执行输入处理代码;用户输入"n"时同样用break,未确保循环条件正确更新。 - 输入处理分支缺陷:无效输入仅处理一次,若用户再次输入错误字符会直接跳过,导致
playAgain状态错误。 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
相关产品推荐
相关产品推荐

