Java井字棋程序故障:重复选择提示异常及逻辑语句失效
Java井字棋程序故障修复方案
核心问题分析
- 回合逻辑完全颠倒:代码中判断X回合的条件
j%2 ==0被错误地用来输出无效提示,而非处理X的落子;且X和O的落子逻辑块会在每次循环中都执行,导致同一回合内两次处理落子。 - 棋盘字符串未动态更新:初始创建的
gameboard字符串不会随a-i变量的修改而更新,导致始终显示初始状态。 - 胜利条件存在错误:其中一条X的胜利判断错误地检查了
a、e、f,而非正确的对角线a、e、i。 - 平局判断位置错误:平局判断放在循环内部,而循环条件是
j<9,当j=9时循环已退出,无法触发平局提示。 - 缺少输入合法性校验:未检查用户输入的坐标是否在1-3范围内,导致无效坐标被判定为已占用的格子。
修复后的完整代码
import java.util.Scanner; public class TicTacToeGame { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int j = 0; // 初始化棋盘为空 char a = ' ', b = ' ', c = ' '; char d = ' ', e = ' ', f = ' '; char g = ' ', h = ' ', i = ' '; // 打印初始空棋盘 printGameBoard(a, b, c, d, e, f, g, h, i); while (j < 9) { int x = getValidInput(scanner, "请输入x坐标(1-3): "); int y = getValidInput(scanner, "请输入y坐标(1-3): "); boolean validMove = false; char currentPlayer = (j % 2 == 0) ? 'X' : 'O'; // 处理当前玩家的落子 if (currentPlayer == 'X') { if (x == 1 && y == 1 && a == ' ') { a = 'X'; validMove = true; } else if (x == 1 && y == 2 && b == ' ') { b = 'X'; validMove = true; } else if (x == 1 && y == 3 && c == ' ') { c = 'X'; validMove = true; } else if (x == 2 && y == 1 && d == ' ') { d = 'X'; validMove = true; } else if (x == 2 && y == 2 && e == ' ') { e = 'X'; validMove = true; } else if (x == 2 && y == 3 && f == ' ') { f = 'X'; validMove = true; } else if (x == 3 && y == 1 && g == ' ') { g = 'X'; validMove = true; } else if (x == 3 && y == 2 && h == ' ') { h = 'X'; validMove = true; } else if (x == 3 && y == 3 && i == ' ') { i = 'X'; validMove = true; } } else { if (x == 1 && y == 1 && a == ' ') { a = 'O'; validMove = true; } else if (x == 1 && y == 2 && b == ' ') { b = 'O'; validMove = true; } else if (x == 1 && y == 3 && c == ' ') { c = 'O'; validMove = true; } else if (x == 2 && y == 1 && d == ' ') { d = 'O'; validMove = true; } else if (x == 2 && y == 2 && e == ' ') { e = 'O'; validMove = true; } else if (x == 2 && y == 3 && f == ' ') { f = 'O'; validMove = true; } else if (x == 3 && y == 1 && g == ' ') { g = 'O'; validMove = true; } else if (x == 3 && y == 2 && h == ' ') { h = 'O'; validMove = true; } else if (x == 3 && y == 3 && i == ' ') { i = 'O'; validMove = true; } } if (validMove) { j++; // 检查胜利条件 checkWin(a, b, c, d, e, f, g, h, i); // 打印更新后的棋盘 printGameBoard(a, b, c, d, e, f, g, h, i); } else { System.out.println("你不能选择这个格子,它已经被占用了或者坐标无效!"); } } // 循环结束说明平局 System.out.println("平局!"); scanner.close(); } // 打印棋盘的工具方法 private static void printGameBoard(char a, char b, char c, char d, char e, char f, char g, char h, char i) { System.out.println("\n 1 2 3"); System.out.println("1 " + a + "| " + b + " | " + c); System.out.println(" - - - - -"); System.out.println("2 " + d + "| " + e + " | " + f); System.out.println(" - - - - -"); System.out.println("3 " + g + "| " + h + " | " + i); System.out.println(" - - - - -\n"); } // 获取合法输入的工具方法 private static int getValidInput(Scanner scanner, String prompt) { int input; while (true) { System.out.print(prompt); if (scanner.hasNextInt()) { input = scanner.nextInt(); if (input >= 1 && input <= 3) { break; } else { System.out.println("输入必须是1-3之间的整数!"); } } else { System.out.println("请输入有效的整数!"); scanner.next(); // 清除无效输入 } } return input; } // 检查胜利条件的工具方法 private static void checkWin(char a, char b, char c, char d, char e, char f, char g, char h, char i) { // 检查X的胜利 if ((a == 'X' && b == 'X' && c == 'X') || (d == 'X' && e == 'X' && f == 'X') || (g == 'X' && h == 'X' && i == 'X') || (a == 'X' && e == 'X' && i == 'X') || (a == 'X' && d == 'X' && g == 'X') || (b == 'X' && e == 'X' && h == 'X') || (c == 'X' && f == 'X' && i == 'X') || (c == 'X' && e == 'X' && g == 'X')) { System.out.println("X获胜!"); System.exit(0); } // 检查O的胜利 if ((a == 'O' && b == 'O' && c == 'O') || (d == 'O' && e == 'O' && f == 'O') || (g == 'O' && h == 'O' && i == 'O') || (a == 'O' && e == 'O' && i == 'O') || (a == 'O' && d == 'O' && g == 'O') || (b == 'O' && e == 'O' && h == 'O') || (c == 'O' && f == 'O' && i == 'O') || (c == 'O' && e == 'O' && g == 'O')) { System.out.println("O获胜!"); System.exit(0); } } }
关键修复说明
- 回合逻辑修正:通过
j%2==0判断当前玩家是X还是O,每次循环仅处理当前玩家的落子,避免同一回合多次操作。 - 动态更新棋盘:使用工具方法
printGameBoard每次打印前重新构建棋盘字符串,确保显示最新状态。 - 修复胜利条件:修正了对角线胜利判断的错误,并将所有胜利条件简化为逻辑AND表达式,提高可读性。
- 调整平局判断:将平局提示移至循环结束后,确保所有格子填满且无胜利者时触发。
- 添加输入校验:通过
getValidInput方法确保用户输入的坐标是1-3之间的整数,避免无效输入导致的错误提示。 - 代码结构优化:将重复的打印、输入校验、胜利判断逻辑提取为工具方法,提升代码可维护性。
内容的提问来源于stack exchange,提问作者apel
相关产品推荐
相关产品推荐

