2

我正在使用位板编写一个国际象棋引擎,我想为位板初始化器制作一个可扩展的 API,这将允许我在未来添加更多变体,如 chess960。

所以我想出了下面的抽象超类,它为所有类型的初始化器提供了一个统一的接口:它分配用于存储位板的数组,然后调用必须由任何子类实现的抽象方法 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];
    }
}

An implementation to initialize standard chess bitboards, it simply assign the hard-coded bitboards values because standard chess starts always in one way. Side.White and Side.Black are two static final fields used as array indexes to avoid inconsistence. white = 0, black = 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;
    }
}

The problem is that by calling any superclass' getter method I get binary 1000 for white (index 0) and 100000000000000000000000000000000000000000000000000000000000 for black (index 1) instead of the assigned values

An explanation of this strange behaviour would be highly appreciated, thanks in advance.

4

1 回答 1

3

The problem is in the BitboardInitializer constructor, where you are initializing all of your array references to point to the same array:

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();
}
于 2020-07-13T21:49:55.017 回答