Connect Four项目胜负校验问题:循环遍历网格致垂直校验失效
Connect Four 胜负校验问题修复方案
看起来你在Connect Four的胜负校验功能上卡壳了,咱们一步步拆解问题、修复逻辑~
先说说你现有代码的核心问题
从你给出的代码片段来看,最大的问题在于找落子行位置的逻辑错误,以及没有聚焦在最后落子的位置去校验四个获胜方向:
- 你用
for (int i = 0; i < gameBoard.getWidth(); i++)遍历宽度(列数)来查找行位置,这明显混淆了行/列的坐标范围; - 遍历整个网格的校验方式既低效又容易漏判方向,胜负校验只需要围绕最后落下的棋子的四个方向(水平、垂直、两条对角线)检查即可。
修复后的完整校验代码
下面是重构后的gameStatus方法,核心思路是:先找到最后落子的准确位置,再分别校验四个方向的连续同色棋子数量:
public boolean gameStatus(MyBoard gameBoard, int columnPosition, CellState gameToken) { // 第一步:找到刚落下的棋子所在的行(Connect Four棋子会落到列的最底部空位) int rowPosition = -1; for (int i = gameBoard.getHeight() - 1; i >= 0; i--) { if (gameBoard.get(i, columnPosition) == gameToken) { rowPosition = i; break; } } if (rowPosition == -1) { return false; // 该列找不到对应棋子,直接返回未获胜 } // 定义四个需要校验的方向偏移量:水平、垂直、左上→右下、右上→左下 int[][] checkDirections = { {0, 1}, // 水平向右 {1, 0}, // 垂直向下 {1, 1}, // 右下对角线 {1, -1} // 左下对角线 }; // 遍历每个方向,统计连续同色棋子数量 for (int[] dir : checkDirections) { int consecutiveCount = 1; // 当前落子本身算1个 // 先往方向的反方向检查(比如向右的话,先查左边) int currentRow = rowPosition - dir[0]; int currentCol = columnPosition - dir[1]; while (currentRow >= 0 && currentRow < gameBoard.getHeight() && currentCol >= 0 && currentCol < gameBoard.getWidth() && gameBoard.get(currentRow, currentCol) == gameToken) { consecutiveCount++; currentRow -= dir[0]; currentCol -= dir[1]; } // 再往方向的正方向检查 currentRow = rowPosition + dir[0]; currentCol = columnPosition + dir[1]; while (currentRow >= 0 && currentRow < gameBoard.getHeight() && currentCol >= 0 && currentCol < gameBoard.getWidth() && gameBoard.get(currentRow, currentCol) == gameToken) { consecutiveCount++; currentRow += dir[0]; currentCol += dir[1]; } // 连续数量≥4则判定获胜 if (consecutiveCount >= 4) { return true; } } return false; }
关键修复点说明
- 准确找落子行:从列的底部往上遍历,找到第一个匹配当前棋子的行,这符合Connect Four的落子规则;
- 方向化校验:通过方向偏移量统一处理四个获胜方向,避免重复代码,也确保每个方向都被覆盖;
- 边界判断:每次检查时都判断坐标是否在网格范围内,避免数组越界异常。
内容的提问来源于stack exchange,提问作者Eivind Lamo
相关产品推荐
相关产品推荐

