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

Java国际象棋代码报错:无法读取null对象的pieceColor字段

问题描述

运行国际象棋棋盘相关Java代码时,触发空指针异常:

Cannot read field "pieceColor" because "elem" is null

错误出现在Board类的avalia方法中if(elem.pieceColor == pieceColor){这一行。

需求:给定棋子颜色(例如黑色),统计棋盘上该颜色的所有棋子,并根据PieceType枚举计算它们的总价值。

相关代码如下:

Main类

import m2_praticas.xadrez.enums.PieceColor;

public class Main {
    public static void main(String[] args) {
        Board board = new Board();

        System.out.println(board.avalia(PieceColor.BLACK));
    }
}

Board类

import m2_praticas.xadrez.enums.PieceColor;
import m2_praticas.xadrez.enums.PieceType;

public class Board {
    Piece board[][];

    public Board(){
        board = new Piece[8][8]; // Creates a new board

        // For loop to set the pieces
        for (int i = 0; i < board.length; i++){ // columns
            for (int j = 0; j < board[i].length; j++){ // rows
                //System.out.println("[" + i + "]" + "[" + j + "]");
                if(i == 0 && j >= 0){ // 0, 0 & 0, 1
                    board[i][j] = new Piece(PieceColor.BLACK, PieceType.ROOK); // 2 black rooks
                }
                if(i == 0 && j >= 2){
                    board[i][j] = new Piece(PieceColor.BLACK, PieceType.KNIGHT); // 2 black knights
                }
                if(i == 0 && j >= 4){
                    board[i][j] = new Piece(PieceColor.BLACK, PieceType.BISHOP); // 2 black bishops
                }
                if(i == 0 && j >= 6){
                    board[i][j] = new Piece(PieceColor.BLACK, PieceType.QUEEN); // 1 black queen
                }
                if(i == 0 && j >= 7){
                    board[i][j] = new Piece(PieceColor.BLACK, PieceType.KING); // 1 black king
                }
                if(i == 1 && j >= 0){
                    board[i][j] = new Piece(PieceColor.BLACK, PieceType.PAWN); // 8 black pawns
                }
                // ---------------------------------
                if(i == 6 && j >= 0){
                    board[i][j] = new Piece(PieceColor.WHITE, PieceType.PAWN); // 8 white pawns
                }
                if(i == 7 && j >= 0){
                    board[i][j] = new Piece(PieceColor.WHITE, PieceType.ROOK); // 2 white rooks
                }
                if(i == 7 && j >= 2){
                    board[i][j] = new Piece(PieceColor.WHITE, PieceType.KNIGHT); // 2 white knights
                }
                if(i == 7 && j >= 4){
                    board[i][j] = new Piece(PieceColor.WHITE, PieceType.BISHOP); // 2 white bishops
                }
                if(i == 7 && j >= 6){
                    board[i][j] = new Piece(PieceColor.WHITE, PieceType.QUEEN); // 1 white queen
                }
                if(i == 7 && j >= 7){
                    board[i][j] = new Piece(PieceColor.WHITE, PieceType.KING); // 1 white king
                }
            }
        }
    }

    public int avalia(PieceColor pieceColor){
        int totalValue = 0;

        for (Piece[] p: board){
            for (Piece elem: p){
                if(elem.pieceColor == pieceColor){
                    switch (elem.pieceType){
                        case PAWN:
                            totalValue = (totalValue + PieceType.PAWN.getPieceValue());
                        break;
                        case ROOK:
                            totalValue = (totalValue + PieceType.ROOK.getPieceValue());
                        break;
                        case KNIGHT:
                            totalValue = (totalValue + PieceType.KNIGHT.getPieceValue());
                        break;
                        case BISHOP:
                            totalValue = (totalValue + PieceType.BISHOP.getPieceValue());
                        break;
                        case QUEEN:
                            totalValue = (totalValue + PieceType.QUEEN.getPieceValue());
                        break;
                        case KING:
                            totalValue = (totalValue + PieceType.KING.getPieceValue());
                        break;

                    }
                }
            }
        }
        return totalValue;
    }
}

Piece类

import m2_praticas.xadrez.enums.PieceColor;
import m2_praticas.xadrez.enums.PieceType;

public class Piece {
    PieceColor pieceColor;
    PieceType pieceType;

    public Piece(PieceColor pieceColor, PieceType pieceType) {
        this.pieceColor = pieceColor;
        this.pieceType = pieceType;
    }
}

PieceType枚举

public enum PieceType {
    PAWN(1), ROOK(5), KNIGHT(3), BISHOP(3), QUEEN(9), KING(0);

    private int pieceValue;

    PieceType(int pieceValue){
        this.pieceValue = pieceValue;
    }

    public int getPieceValue() {
        return pieceValue;
    }
}

PieceColor枚举

public enum PieceColor {
    BLACK, WHITE;
}

问题原因与修复方案

1. 空指针异常原因

  • 棋盘初始化时,第2到第5行(i=2至i=5)的所有位置未创建Piece对象,这些位置的元素为null。遍历到null元素时,直接访问elem.pieceColor必然触发空指针。
  • 棋子初始化逻辑错误:使用连续的if而非else if,导致后面的条件覆盖前面的设置(比如第0行所有列先被设为车,后续又被覆盖为马、象等),棋子位置完全不符合国际象棋规则。

2. 修复步骤

方案1:修正棋盘初始化逻辑

直接按国际象棋规则精确设置每个棋子的位置,避免条件覆盖:

public Board(){
    board = new Piece[8][8];

    // 初始化黑方棋子
    // 第0行:黑方后排
    board[0][0] = new Piece(PieceColor.BLACK, PieceType.ROOK);
    board[0][1] = new Piece(PieceColor.BLACK, PieceType.KNIGHT);
    board[0][2] = new Piece(PieceColor.BLACK, PieceType.BISHOP);
    board[0][3] = new Piece(PieceColor.BLACK, PieceType.QUEEN);
    board[0][4] = new Piece(PieceColor.BLACK, PieceType.KING);
    board[0][5] = new Piece(PieceColor.BLACK, PieceType.BISHOP);
    board[0][6] = new Piece(PieceColor.BLACK, PieceType.KNIGHT);
    board[0][7] = new Piece(PieceColor.BLACK, PieceType.ROOK);
    // 第1行:黑方兵
    for (int j = 0; j < 8; j++) {
        board[1][j] = new Piece(PieceColor.BLACK, PieceType.PAWN);
    }

    // 初始化白方棋子
    // 第6行:白方兵
    for (int j = 0; j < 8; j++) {
        board[6][j] = new Piece(PieceColor.WHITE, PieceType.PAWN);
    }
    // 第7行:白方后排
    board[7][0] = new Piece(PieceColor.WHITE, PieceType.ROOK);
    board[7][1] = new Piece(PieceColor.WHITE, PieceType.KNIGHT);
    board[7][2] = new Piece(PieceColor.WHITE, PieceType.BISHOP);
    board[7][3] = new Piece(PieceColor.WHITE, PieceType.QUEEN);
    board[7][4] = new Piece(PieceColor.WHITE, PieceType.KING);
    board[7][5] = new Piece(PieceColor.WHITE, PieceType.BISHOP);
    board[7][6] = new Piece(PieceColor.WHITE, PieceType.KNIGHT);
    board[7][7] = new Piece(PieceColor.WHITE, PieceType.ROOK);
}

方案2:遍历前判空并简化价值计算

在avalia方法中先检查元素是否为null,再访问属性,同时省去冗余的switch逻辑:

public int avalia(PieceColor pieceColor){
    int totalValue = 0;

    for (Piece[] row : board){
        for (Piece elem : row){
            // 先判空,再判断颜色
            if(elem != null && elem.pieceColor == pieceColor){
                // 直接调用枚举的getValue计算价值
                totalValue += elem.pieceType.getPieceValue();
            }
        }
    }
    return totalValue;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:55:44