Java实现Connect Four游戏矩阵对角线胜利检测故障排查
问题描述
我正在开发一款*四子棋(Connect 4)*游戏,目标是将四个相同棋子连成一线。我使用二维数组Player[6][7]存储棋盘,每个位置记录落子玩家。目前胜利条件中,行、列检测已正常工作,但左上到右下、左下到右上的对角线检测功能失效。以下是我的胜利检测代码:
private final Player[][] board = new Player[6][7]; // the board filled public Player hasWinner() { // Lines (rows) for(int y = 0; y < board.length; y++) { // simple lines Player last = null; int nb = 0; Player[] line = board[y]; for(int x = 0; x < line.length; x++) { Player played = line[x]; if((last == null || played == last) && played != null) { // new player or same as before nb++; if(nb == 4) // it's this ! return played; } else { // else reset nb = (played == null ? 0 : 1); } last = played; } } // Columns for(int x = 0; x < board[0].length; x++) { // simple columns Player last = null; int nb = 0; for(int y = 0; y < board.length; y++) { // for each columns Player played = board[y][x]; if((last == null || played == last) && played != null) { // new player or same as before nb++; if(nb == 4) // it's this ! return played; } else { // else reset nb = (played == null ? 0 : 1); } last = played; } } // ➡️ HERE IS THE INTERESTING PART // Diagonals for(int i = -board.length; i < board[0].length; i++) { // diagonals Player last = null; int nb = 0; for(int j = 0; j < 9; j++) { if(board.length <= j || board[j].length <= j) continue; Player played = board[j][j]; if((last == null || played == last) && played != null) { // new player or same as before nb++; if(nb == 4) // it's this ! return played; } else { // else reset nb = (played == null ? 0 : 1); } last = played; } for(int j = 9; j < 0; j--) { if(board.length <= j || board[j].length <= j) continue; Player played = board[j][board[j].length - j]; if((last == null || played == last) && played != null) { // new player or same as before nb++; if(nb == 4) // it's this ! return played; } else { // else reset nb = (played == null ? 0 : 1); } last = played; } } return null; }
请问如何修复对角线胜利检测功能?
修复方案
问题分析
原对角线检测逻辑存在多处核心错误:
- 外层循环的
i变量未被使用,完全无法遍历所有对角线 - 第一个内层循环仅覆盖了
board[j][j]这条单一主对角线,未覆盖所有左上到右下的对角线 - 第二个内层循环的条件
j < 0导致循环从未执行,且索引计算存在数组越界风险 - 未针对6行7列的棋盘尺寸设计合理的对角线遍历范围
替换后的对角线检测代码
删除原有的对角线检测块,替换为以下逻辑:
// 对角线:左上到右下(\方向) // 遍历所有能容纳4个连续棋子的起点 for (int y = 0; y <= board.length - 4; y++) { for (int x = 0; x <= board[0].length - 4; x++) { Player current = board[y][x]; if (current == null) continue; // 检查连续4个右下方向的位置是否为同一玩家 if (board[y+1][x+1] == current && board[y+2][x+2] == current && board[y+3][x+3] == current) { return current; } } } // 对角线:左下到右上(/方向) // 遍历所有能容纳4个连续棋子的起点 for (int y = 3; y < board.length; y++) { for (int x = 0; x <= board[0].length - 4; x++) { Player current = board[y][x]; if (current == null) continue; // 检查连续4个右上方向的位置是否为同一玩家 if (board[y-1][x+1] == current && board[y-2][x+2] == current && board[y-3][x+3] == current) { return current; } } }
修复说明
左上到右下对角线:
- 起点的
y范围限制在0-2(确保y+3不超过棋盘最大行索引5) - 起点的
x范围限制在0-3(确保x+3不超过棋盘最大列索引6) - 直接检查从起点开始的连续4个右下方向位置是否属于同一玩家
- 起点的
左下到右上对角线:
- 起点的
y范围限制在3-5(确保y-3不小于棋盘最小行索引0) - 起点的
x范围同样限制在0-3 - 直接检查从起点开始的连续4个右上方向位置是否属于同一玩家
- 起点的
该方案逻辑清晰,完全覆盖了棋盘上所有可能出现四子连线的对角线,同时避免了数组越界问题。
内容的提问来源于stack exchange,提问作者Elikill58
相关产品推荐
相关产品推荐

