Connect4复刻版无法正确统计横向连续棋子问题求助
Connect4游戏开发问题修复
问题说明
我正在IDE中编写计算机科学1的期末作业,复刻Connect4游戏,但遇到两个问题:
- 玩家放置相邻棋子时,
horizontalLeft和horizontalRight变量无法正确递增 - 调整
leftCount/rightCount的位置后,在最右侧叠放棋子时游戏会莫名卡顿
原代码
//Sam Stevens import java.util.*; public class MyProgram { public static void main(String[] args) { String[][] gameboard = new String[7][7]; //first value "i" is the height, second "j" is the width. for(int i = 0; i< gameboard.length; i++){ for(int j = 0; j< gameboard[0].length; j++){ gameboard[i][j] = "_"; } } //Initialize Gameboard print(gameboard); for(int i = 0; i < 10; i++){ play(gameboard); } //this for loop makes the game last 10 turns } public static void print(String[][] gb){ System.out.println("\n"); for(int i = 0; i< gb.length; i++){ for(int j = 0; j< gb[0].length; j++){ System.out.printf("%-3s ", gb[i][j]); } System.out.println(); } } //print out the gameboard public static void play(String[][] gb){ Scanner input = new Scanner(System.in); boolean cont = true; do{ System.out.println("Player 1, where would you like to go? (1,2,3,4,5,6,7)"); int p1choice = input.nextInt() - 1; boolean moving = true; int i = 6; int j = p1choice; int yIndex = 0; do{ if(i>=0){ if(gb[i][j] == "_"){ gb[i][j] = "1"; moving = false; yIndex = i; } i--; } else{ System.out.println("Invalid move. Sucks to be you."); moving = false; } }while(moving); print(gb); checkWin(gb, "1", p1choice, yIndex); System.out.println("Player 2, where would you like to go? (1,2,3,4,5,6,7)"); int p2choice = input.nextInt() - 1; moving = true; i = 6; j = p2choice; int yIndexP2 = 0; do{ if(i>=0){ if(gb[i][j] == "_"){ gb[i][j] = "2"; moving = false; yIndexP2 = i; } i--; } else{ System.out.println("Invalid move. Sucks to be you."); moving = false; } }while(moving); print(gb); checkWin(gb, "2", p2choice, yIndexP2); }while(!cont); } public static void checkWin(String[][] gb, String p, int heightIndex, int widthIndex){ //p tells us which player we are checking for and we can use it as which piece we're looking for. int horizontalLeft = 0; int horizontalRight = 0; int verticalUp = 0; int verticalDown = 0; //check pieces to the left boolean leftContinue = true; if(widthIndex != 0){ int leftCount = 1; do{ if(gb[heightIndex][widthIndex - leftCount] == p){ horizontalLeft ++; leftCount ++; } else{ leftContinue = false; } }while(leftContinue && (widthIndex - leftCount >= 0)); } //check pieces to the right boolean rightContinue = true; if(widthIndex != 6){ int rightCount = 1; do{ if(gb[heightIndex][widthIndex + rightCount] == p){ horizontalRight ++; rightCount ++; } else{ rightContinue = false; } }while(rightContinue && (widthIndex + rightCount <= 6)); } System.out.println(p + " " + horizontalLeft + " " + horizontalRight); //BELOW HERE SHOULD BE ONLY CHECK WIN if(horizontalLeft + horizontalRight >= 3){ System.out.println("Game over. Player " + p + " wins!"); } } }
问题根源与修复方案
1. 参数顺序传反(核心问题)
调用checkWin方法时,错误地将**列索引(width)和行索引(height)**的顺序传反了:
- 原调用:
checkWin(gb, "1", p1choice, yIndex); - 正确调用:
checkWin(gb, "1", yIndex, p1choice);
p1choice是玩家选择的列(width),yIndex是棋子落下的行(height),但checkWin方法的参数定义是int heightIndex, int widthIndex,传反后会在错误的行上检查相邻棋子,导致计数变量无法递增。
2. 字符串比较错误
Java中判断字符串内容相等必须使用equals()方法,而非==(==比较的是对象引用地址)。原代码中所有gb[...][...] == p的写法都要改成gb[...][...].equals(p),否则无法正确识别相同玩家的棋子。
3. 循环逻辑优化(解决卡顿)
调整循环条件的判断顺序,先检查索引是否合法,再判断棋子是否匹配,避免潜在的索引越界问题。同时确保leftCount/rightCount仅在匹配时自增,防止无效循环。
修复后的关键代码片段
修复后的play方法调用部分
// Player 1 调用修复 print(gb); checkWin(gb, "1", yIndex, p1choice); // 交换yIndex和p1choice的顺序 // Player 2 调用修复 print(gb); checkWin(gb, "2", yIndexP2, p2choice); // 交换yIndexP2和p2choice的顺序
修复后的checkWin方法
public static void checkWin(String[][] gb, String p, int heightIndex, int widthIndex){ int horizontalLeft = 0; int horizontalRight = 0; int verticalUp = 0; int verticalDown = 0; // 检查左侧棋子 int leftCount = 1; while (widthIndex - leftCount >= 0 && gb[heightIndex][widthIndex - leftCount].equals(p)) { horizontalLeft++; leftCount++; } // 检查右侧棋子 int rightCount = 1; while (widthIndex + rightCount <= 6 && gb[heightIndex][widthIndex + rightCount].equals(p)) { horizontalRight++; rightCount++; } System.out.println(p + " " + horizontalLeft + " " + horizontalRight); if(horizontalLeft + horizontalRight >= 3){ System.out.println("Game over. Player " + p + " wins!"); } }
额外优化建议
- 游戏结束后应终止循环,当前代码的
for(int i=0; i<10; i++)会强制进行10回合,可在checkWin中添加退出逻辑 - 无效输入处理可优化,比如玩家输入超出1-7范围时重新提示,而非直接结束移动
- 垂直方向的胜利检测尚未实现,可参考水平检测的逻辑完成
内容的提问来源于stack exchange,提问作者Sam Stevens
相关产品推荐
相关产品推荐

