
你的 Connect 4 实现中 checkWin 方法因行列索引传参顺序错误,导致水平方向(左/右)连子数量始终为 0,无法正确检测四连胜。核心问题是将「列索引」误作「行索引」传入,致使数组访问越界或读取错误位置。
你的 connect 4 实现中 `checkwin` 方法因行列索引传参顺序错误,导致水平方向(左/右)连子数量始终为 0,无法正确检测四连胜。核心问题是将「列索引」误作「行索引」传入,致使数组访问越界或读取错误位置。
在你当前的代码中,play() 方法在落子后调用 checkWin(gb, "1", p1choice, yIndex) —— 这里 p1choice 是玩家输入的列号(widthIndex),而 yIndex 是该列中实际落子的行号(heightIndex)。但 checkWin 方法签名却定义为:
public static void checkWin(String[][] gb, String p, int heightIndex, int widthIndex)
⚠️ 这导致参数被颠倒使用:方法内部将 heightIndex 当作列、widthIndex 当作行来访问二维数组 gb[heightIndex][widthIndex],而 Java 中二维数组约定是 gb[row][col](即 gb[i][j] 中 i 为行、j 为列)。因此,gb[heightIndex][widthIndex] 实际访问的是 gb[列][行],严重违背内存布局,造成:
- 水平检查(左右遍历)始终在错误的“行”上操作(实为列),结果恒为 _ 或越界;
- horizontalLeft 和 horizontalRight 始终为 0,无法累加;
- 即使视觉上出现横连四子,逻辑也完全无法识别。
✅ 正确做法是统一索引语义并修正参数顺序:
-
修改 checkWin 方法签名,明确参数含义:
public static void checkWin(String[][] gb, String p, int colIndex, int rowIndex) { // colIndex: 落子列(0~6),rowIndex: 落子行(0~6) } -
同步更新所有调用处(play 方法内):
checkWin(gb, "1", p1choice, yIndex); // ✅ now: (col, row) checkWin(gb, "2", p2choice, yIndexP2); // ✅ now: (col, row)
-
重写检查逻辑,确保边界安全(推荐优化版):
public static void checkWin(String[][] gb, String p, int colIndex, int rowIndex) { // 水平方向:向左 + 向右 int horizontal = 1; // 自身计1 // 向左 for (int c = colIndex - 1; c >= 0 && gb[rowIndex][c].equals(p); c--) { horizontal++; } // 向右 for (int c = colIndex + 1; c = 4) { System.out.println("Game over. Player " + p + " wins!"); System.exit(0); // 或设标志终止游戏循环 } }
? 额外注意事项:
- 你的棋盘是 String[7][7],但 Connect 4 标准为 6 行 × 7 列。当前 i=6 落子时会访问 gb[6][j]——这是第 7 行(索引从 0 开始),超出标准范围,易引发 ArrayIndexOutOfBoundsException。建议改为 String[6][7],并调整下落逻辑:初始 i = 5,循环条件 i >= 0。
- play() 中 do-while(!cont) 的 cont 始终为 true,导致无限循环。应通过 checkWin 返回胜利状态或设置全局 gameOver 标志控制主循环。
- 使用 equals() 替代 == 比较字符串内容(虽此处值为 "1"/"2" 字符串常量,但属良好实践)。
修复索引顺序后,水平连子检测将立即生效,游戏逻辑回归预期行为。这是初学者在二维数组坐标映射中最常见也最关键的陷阱之一——务必牢记:array[row][col] ≠ array[y][x] 在图形坐标系中需主动转换,而非默认等价。










