Last Stone Game(Nim)实现问题:电脑玩家始终无法执行回合
解决Last Stone Game中CPU无法轮到回合的问题
我帮你找到了核心问题,同时也发现了代码里其他几个小问题,咱们一步步来解决:
核心问题:回合切换的代码放错位置了
你看main方法里的UserOrCpu += 1;,它被写在while(true)循环的外面了!这就导致循环里的UserOrCpu永远是初始值1,永远只会执行用户回合的分支,CPU的else分支根本没机会跑。把这行代码移到循环内部,每次完成一个有效回合后就切换玩家,问题就解决了。
其他需要修正的小问题
- CPU重复执行取石操作:在else分支里,你连续调用了两次
computerMove(left),第一次调用已经输出了CPU取石的信息,第二次又调用会再次生成随机数并重复输出,这会导致CPU实际取的石头数是第二次生成的,逻辑混乱。应该只调用一次,把结果存到变量里复用。 - CPU取石的合理性检查:当前代码里CPU取石没有做合法性判断(比如不能取超过剩余石头数),虽然
generateStones生成1-2,但如果剩余石头只有1,CPU取2就会出问题,得让生成逻辑根据剩余石头数调整。 - 输出格式问题:
computerMove方法里的字符串拼接少了空格,会变成类似"There are 20stones. The computer takes2 stones"的奇怪格式,要补上空格让信息更易读。 - 输入合法性提示优化:原提示只有"Invalid entry!!",用户不知道哪里错了,最好补充说明规则(取1-3个,不超过剩余石头)。
修正后的完整代码
package HomePlace; import java.util.Random; import java.util.Scanner; public class LastStone { public static boolean isValidEntry(int left, int take) { if (left > 0 && take >= 1 && take <= 3 && left >= take) { return true; } else { System.out.println("Invalid entry!! Please take 1-3 stones, and not more than remaining stones."); return false; } } public static int userMove(int left) { Scanner input = new Scanner(System.in); System.out.print("There are " + left + " stones. How many would you like? "); return input.nextInt(); } public static int computerMove(int left) { int cpuStones = generateStones(left); System.out.println("There are " + left + " stones. The computer takes " + cpuStones + " stones."); return cpuStones; } // 根据剩余石头数生成合理的取石数(1-3,且不超过剩余) public static int generateStones(int left) { Random sr = new Random(); int maxTake = Math.min(left, 3); return sr.nextInt(maxTake) + 1; } public static void playLastStone(int winner) { if (winner % 2 == 1) { System.out.println("The Computer beats the User!"); } else { System.out.println("The User beats the Computer!"); } } public static void main(String[] args) { Scanner input = new Scanner(System.in); Random r = new Random(); int left = r.nextInt(16) + 15; // 初始石头15-30 int currentPlayer = 1; // 1代表用户,2代表CPU int take; while (true) { if (currentPlayer % 2 == 1) { // 用户回合 take = userMove(left); if (isValidEntry(left, take)) { if (left == take) { playLastStone(currentPlayer); break; } left -= take; // 切换到CPU回合 currentPlayer++; } // 输入无效则不切换回合,重新让用户输入 } else { // CPU回合 take = computerMove(left); if (left <= take) { playLastStone(currentPlayer); break; } else { left -= take; // 切换到用户回合 currentPlayer++; } } } input.close(); } }
代码说明
- 把玩家切换逻辑移到了每个有效回合结束后,确保用户和CPU能轮流进行操作。
- 修改了
generateStones方法,让它根据剩余石头数生成合理的取石数,避免CPU取超过剩余数量的石头。 - 修复了CPU回合重复调用取石方法的问题,保证逻辑一致。
- 优化了输入错误提示,让用户明确知道规则。
- 调整了输出格式,让游戏信息更清晰易读。
这样修改后,CPU就能正常轮到它的回合,游戏逻辑也更严谨啦!
内容的提问来源于stack exchange,提问作者LogicNAME
相关产品推荐
相关产品推荐

