You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java二维数组元素下落效果实现及Connect4游戏数组越界排查

解决Connect 4棋子下落的数组越界问题&实现思路

嘿,我来帮你搞定这个Connect 4的下落逻辑问题!先看你遇到的ArrayIndexOutOfBoundsException,结合你给出的代码片段,大概率是数组初始化错误加上缺少边界检查导致的,咱们一步步拆解:

为什么会触发数组越界?

你注释说a[]是用来存每列的空位数,但你初始化的时候给的是全0:

int a[] = {0,0,0,0,0,0,0,0};//stores the no. of empty space in each column

你的棋盘是8×8的,每列初始应该有8个空位才对!如果用这个全0的数组计算行号,比如你可能写了类似board[8 - a[col]][col]的代码,初始时8 - 0 = 8,但Java数组索引从0开始,8行的棋盘行索引范围是0~7,直接访问索引8肯定会越界。

另外,就算初始化对了,如果没检查列是否已满就继续放置棋子,当a[col]减到0之后再减,计算出的行号也会变成负数,同样触发越界。

正确实现棋子下落的方法

其实换个思路记录每列的可放置位置会更直观:用一个数组记录每列下一个可放置的行索引,初始时是棋盘的最底部(索引7),每次放完棋子就把这个索引往上移一行(减1)。

完整示例代码

import java.util.Arrays;

public class Connect4 {
    private char[][] board;
    private int[] nextAvailableRow; // 记录每列下一个可放置的行索引
    private static final int ROWS = 8;
    private static final int COLS = 8;
    private static final char EMPTY = '-';

    public Connect4() {
        // 初始化8×8棋盘
        board = new char[ROWS][COLS];
        for (int i = 0; i < ROWS; i++) {
            Arrays.fill(board[i], EMPTY);
        }
        // 初始化每列的可放置行:最底部(索引7)
        nextAvailableRow = new int[COLS];
        Arrays.fill(nextAvailableRow, ROWS - 1);
    }

    // 放置棋子的方法,返回是否放置成功
    public boolean dropPiece(int column, char playerPiece) {
        // 1. 检查列是否合法(0~7),以及该列是否还有空位
        if (column < 0 || column >= COLS || nextAvailableRow[column] < 0) {
            System.out.println("该列无法放置棋子!");
            return false;
        }

        // 2. 获取要放置的行索引
        int row = nextAvailableRow[column];
        // 3. 放置棋子
        board[row][column] = playerPiece;
        // 4. 更新下一个可放置的行(往上移一行)
        nextAvailableRow[column]--;

        return true;
    }

    // 打印棋盘(用于测试)
    public void printBoard() {
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        Connect4 game = new Connect4();
        // 测试:玩家1在第0列放棋子
        game.dropPiece(0, 'X');
        // 玩家2在第0列放棋子
        game.dropPiece(0, 'O');
        game.printBoard();
    }
}

关键逻辑说明

  1. 初始化阶段:nextAvailableRow数组每个元素初始为ROWS-1(也就是7),代表每列最底部的行是第一个可放置的位置。
  2. 放置棋子时:
    • 先做边界检查:列号不能超出0~7,且nextAvailableRow[column]不能小于0(小于0说明列已经满了)。
    • 拿到行索引后放置棋子,然后把该列的可放置行索引减1,下次棋子就会落在上一行。

额外思路:用空位数实现

如果你坚持用“空位数”的思路,那核心要修正初始化逻辑,再配合边界检查:

int[] emptySpacesPerCol = new int[8];
Arrays.fill(emptySpacesPerCol, 8); // 初始每列8个空位

// 放置棋子
public boolean dropPiece(int column, char piece) {
    if (column <0 || column >=8 || emptySpacesPerCol[column] <=0) {
        return false;
    }
    int row = emptySpacesPerCol[column] - 1;
    board[row][column] = piece;
    emptySpacesPerCol[column]--;
    return true;
}

这里初始空位数设为行数(8),行号直接用空位数-1,就能保证每次棋子落在当前列的最底部空位,放完后空位数减1即可。

内容的提问来源于stack exchange,提问作者Achintya Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:59:43