java - 父类(super class)上 protected 数组的值意外更改

标签 java inheritance chess bitboard

我正在使用位板编写一个国际象棋引擎,我想为位板初始值设定项创建一个可扩展的 API,这将允许我在将来添加更多变体,例如 chess960。

所以我想出了以下抽象父类(super class),它为所有类型的初始化器提供了统一的接口(interface):它分配用于存储位板的数组,然后调用必须由任何子类实现的抽象方法 init() ,在里面应该创建位板并将其分配给相应的数组

public abstract class BitboardInitializer {
 
    private static final int NUMBER_OF_PLAYERS = 2;
 
    protected long[] pawnsPositions, knightsPositions, bishopsPositions,
            rooksPositions, queenPositions, kingPositions;
 
    protected BitboardInitializer() {
        pawnsPositions = knightsPositions = bishopsPositions =
                rooksPositions = queenPositions = kingPositions = new long[NUMBER_OF_PLAYERS];
        init();
    }
 
    protected abstract void init();
 
    public long getPawnsPositionsAs(int side) {
        return pawnsPositions[side];
    }
 
    public long getKnightsPositionsAs(int side) {
        return knightsPositions[side];
    }
 
    public long getBishopsPositionsAs(int side) {
        return bishopsPositions[side];
    }
 
    public long getRooksPositionsAs(int side) {
        return rooksPositions[side];
    }
 
    public long getQueenPositionsAs(int side) {
        return queenPositions[side];
    }
 
    public long getKingPositionsAs(int side) {
        return kingPositions[side];
    }
}

一种初始化标准国际象棋位板的实现,它只是分配硬编码的位板值,因为标准国际象棋总是以一种方式开始。 Side.WhiteSide.Black 是两个静态最终字段,用作数组索引以避免不一致。白色 = 0,黑色 = 1:

public final class StandardChessInitializer extends BitboardInitializer {
 
    public StandardChessInitializer() {
        super();
    }
 
    protected void init() {
        pawnsPositions[Side.WHITE] =
                0b00000000_00000000_00000000_00000000_00000000_00000000_11111111_00000000L;
        pawnsPositions[Side.BLACK] =
                0b00000000_11111111_00000000_00000000_00000000_00000000_00000000_00000000L;
        knightsPositions[Side.WHITE] =
                0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_01000010L;
        knightsPositions[Side.BLACK] =
                0b01000010_00000000_00000000_00000000_00000000_00000000_00000000_00000000L;
        bishopsPositions[Side.WHITE] =
                0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00100100L;
        bishopsPositions[Side.BLACK] =
                0b00100100_00000000_00000000_00000000_00000000_00000000_00000000_00000000L;
        rooksPositions[Side.WHITE] =
                0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_10000001L;
        rooksPositions[Side.BLACK] =
                0b10000001_00000000_00000000_00000000_00000000_00000000_00000000_00000000L;
        queenPositions[Side.WHITE] =
                0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00010000L;
        queenPositions[Side.BLACK] =
                0b00010000_00000000_00000000_00000000_00000000_00000000_00000000_00000000L;
        kingPositions[Side.WHITE] =
                0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00001000L;
        kingPositions[Side.BLACK] =
                0b00001000_00000000_00000000_00000000_00000000_00000000_00000000_00000000L;
    }
}

问题是,通过调用任何父类(super class)的 getter 方法,我得到白色(索引 0)的二进制 1000 和黑色(索引 1)的 1000000000000000000000000000000000000000000000000000000000000 的二进制,而不是分配的值(value)观

非常感谢对这种奇怪行为的解释,提前致谢。

最佳答案

问题出在 BitboardInitializer 构造函数中,您在其中初始化所有数组引用以指向同一数组:

protected BitboardInitializer() {
    pawnsPositions = knightsPositions = bishopsPositions =
            rooksPositions = queenPositions = kingPositions = new long[NUMBER_OF_PLAYERS];
    init();
}

应该是:

protected BitboardInitializer() {
    pawnsPositions = new long[NUMBER_OF_PLAYERS];
    knightsPositions = new long[NUMBER_OF_PLAYERS];
    bishopsPositions = new long[NUMBER_OF_PLAYERS];
    rooksPositions = new long[NUMBER_OF_PLAYERS];
    queenPositions = new long[NUMBER_OF_PLAYERS];
    kingPositions = new long[NUMBER_OF_PLAYERS];
    init();
}

关于java - 父类(super class)上 protected 数组的值意外更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62884634/

相关文章:

python - 以对象表示的数据

java - 如何在Retrofit2/rxJava中刷新ACCESS-TOKEN

java - 我想用鼠标输入在窗口上绘制像素

c++ - 基类 "Object",懒惰/聪明还是愚蠢?

Python:在初始评估后向类添加父类

algorithm - 带a-b修剪和换位表的Minimax

java - 使用差异进化的函数值

c - 从 C 中的变量值中查找变量

java - 如何从不同的范围创建对象

java - 在无序数组中找到最近的数字