TicTacToe游戏无法接收坐标输入问题排查及优化建议
问题解决与代码优化
核心问题修复
1. 棋盘未初始化空格
Board类的棋盘数组默认初始化为空字符'\u0000',而非空格' ',导致判断board[row][col] == ' '始终不成立,无法放置图标。需添加构造函数初始化棋盘:
public Board() { // 初始化棋盘为空格 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { board[i][j] = ' '; } } }
2. Scanner输入冲突
Player类中每个实例都创建独立Scanner,会与Main中的Scanner产生输入缓冲区问题。修改为共用一个Scanner:
// Player类修改 public class Player { char icon; String name; public void PlayerInfo(Scanner scanner) { System.out.print("Enter player's name: "); name = scanner.nextLine(); } } // Main中调用方式修改 player1.PlayerInfo(scanner); player2.PlayerInfo(scanner);
3. 玩家切换逻辑错误
原代码用board.Row + board.Col判断玩家,但这两个变量从未更新,导致永远是同一玩家操作。改为用已落子数量判断:
// Main中新增变量统计落子数 int moveCount = 0; while (!GameOver) { board.PrintBoard(board.board); Player currentPlayer = moveCount % 2 == 0 ? player1 : player2; // ... 其他代码 // 落子成功后才计数 if (row >=0 && row <3 && col >=0 && col <3) { if (board.board[row][col] == ' ') { board.board[row][col] = currentPlayer.icon; moveCount++; GameOver = Board.HaveWon(board.board, currentPlayer); // ... } } }
修正后的完整代码
Main类
package com.mycompany.tictactoe; import java.util.Scanner; public class Tictactoe { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Player player1 = new Player(); Player player2 = new Player(); player1.icon = 'X'; player1.PlayerInfo(scanner); player2.icon = 'O'; player2.PlayerInfo(scanner); Board board = new Board(); boolean gameOver = false; int moveCount = 0; while (!gameOver) { board.PrintBoard(board.board); Player currentPlayer = moveCount % 2 == 0 ? player1 : player2; System.out.print("Player " + currentPlayer.name + " (" + currentPlayer.icon + ") enter row (0-2): "); int row = scanner.nextInt(); System.out.print("Player " + currentPlayer.name + " (" + currentPlayer.icon + ") enter column (0-2): "); int col = scanner.nextInt(); scanner.nextLine(); // 清除输入缓冲区的换行符 if (row >= 0 && row < 3 && col >= 0 && col < 3) { if (board.board[row][col] == ' ') { board.board[row][col] = currentPlayer.icon; moveCount++; gameOver = Board.HaveWon(board.board, currentPlayer); if (gameOver) { board.PrintBoard(board.board); // 打印获胜最终棋盘 System.out.println("Player " + currentPlayer.name + " has won!"); } else if (moveCount == 9) { // 判断平局 board.PrintBoard(board.board); System.out.println("It's a draw!"); gameOver = true; } } else { System.out.println("Invalid move: this spot is already taken."); } } else { System.out.println("Invalid input: row and column must be between 0 and 2."); } } scanner.close(); } }
Player类
package com.mycompany.tictactoe; import java.util.Scanner; public class Player { char icon; String name; public void PlayerInfo(Scanner scanner) { System.out.print("Enter player's name: "); name = scanner.nextLine(); } }
Board类
package com.mycompany.tictactoe; public class Board { char[][] board = new char[3][3]; public Board() { // 初始化棋盘为空格 for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { board[i][j] = ' '; } } } public void PrintBoard(char[][] board) { for (int row = 0; row < board.length; row++) { for (int col = 0; col < board[row].length; col++) { System.out.print(board[row][col] + " | "); } System.out.println(); if (row < board.length - 1) { System.out.println("---------"); } } } public static boolean HaveWon(char[][] board, Player player) { // 检查行 for (int row = 0; row < board.length; row++) { if (board[row][0] == player.icon && board[row][1] == player.icon && board[row][2] == player.icon) { return true; } } // 检查列 for (int col = 0; col < board[0].length; col++) { if (board[0][col] == player.icon && board[1][col] == player.icon && board[2][col] == player.icon) { return true; } } // 检查对角线 if (board[0][0] == player.icon && board[1][1] == player.icon && board[2][2] == player.icon) { return true; } if (board[0][2] == player.icon && board[1][1] == player.icon && board[2][0] == player.icon) { return true; } return false; } }
额外优化建议
- 变量命名规范:遵循Java驼峰命名法,比如
GameOver改为gameOver,Row/Col改为row/col,提升代码可读性。 - 提取输入方法:将行/列输入逻辑封装成独立方法,避免重复代码,同时处理非整数输入的异常情况。
- 封装棋盘操作:在Board类中添加
placeIcon(int row, int col, char icon)方法,代替直接修改数组,增强封装性。 - 常量定义:将棋盘大小(3)定义为常量
public static final int BOARD_SIZE = 3;,避免硬编码。
内容的提问来源于stack exchange,提问作者daniell e
相关产品推荐
相关产品推荐

