비트 보드로 체스 상태를 나타내는 방법


11

체스 엔진을 프로그래밍하고 비트 보드를 사용하여 게임 상태를 나타내는 데 관심이 있습니다. 비트 보드를 사용하는 오픈 소스 체스 엔진이 몇 가지 있지만 코드를보고 무슨 일이 일어나고 있는지 이해하기 쉽지 않습니다. 비트 보드에서 모든 상태를 나타내는 방법에 대한 좋은 참고 자료를 찾고 있습니다.

비트 보드를 사용하여 게임 상태를 유지하는 방법, 특히 특정 비트 보드에서 유효한 이동 목록을 생성하거나 이러한 설명에 대한 적절한 참조를 제공하는 방법을 명확하게 설명하면 녹색 확인 표시가 나타납니다.


3
1. OP는 주제에 대한 지식이 없음을 보여줍니다. 즉, OP는 자신을 교육하기 위해 진지하게 시도하지 않았습니다. 2.이 프로그래밍에 관한하지 체스
토니 에니스

답변:


10

체스 엔진 프로그래밍을위한 최고의 리소스는 비트 보드에 대한 섹션 이 큰 체스 프로그래밍 위키 입니다. 비트 보드 기반 엔진을 만드는 데 필요한 모든 것이 있지만, 영어가 제 2 언어 인 사람들이 작성하기도합니다.


2 개의 링크가 유효하지 않습니다.
Jackson Tale

1
그들은 내가이 의견을 쓰는 시점에서 여전히 나를 위해 일합니다.
dfan

8

어떤 프로그래밍 언어를 사용 하시겠습니까?

C #에서 비트 보드를 구현하려면 System.UInt64를 사용하십시오 . 이것은 체스 보드의 각 정사각형에 대해 64 비트, 1을 보유 할 수 있습니다. 이 값 유형은 많은 빠른 비트 단위 연산에 적합합니다.

이것은 좋은 비트 보드 튜토리얼 입니다.

내 C # 체스 엔진의 몇 가지 예가 있습니다. 코드에서 알 수 있듯이 비트 보드를 사용하여 머리를 감싸는 데 시간이 걸릴 수 있지만 일반적으로 위치 평가에 특히 빠릅니다.

예 1-비트 보드 정의 :

internal UInt64 WhiteKing;
internal UInt64 WhiteQueens;
internal UInt64 WhiteRooks;
internal UInt64 WhiteBishops;
internal UInt64 WhiteKnights;
internal UInt64 WhitePawns;
internal UInt64 WhitePieces;

예 2-비트 보드 초기화 :

// Initialise piece bitboards using square contents.
private void InitPieceBitboards()
{
    this.WhiteKing = 0; 
    this.WhiteQueens = 0; 
    this.WhiteRooks = 0; 
    this.WhiteBishops = 0; 
    this.WhiteKnights = 0; 
    this.WhitePawns = 0;

    for (Int16 i = 0; i < 64; i++)
    {
        if (this.Squares[i] == Constants.WHITE_KING)
        {
            this.WhiteKing = this.WhiteKing | Constants.BITSET[i];
        }
        if (this.Squares[i] == Constants.WHITE_QUEEN)
        {
            this.WhiteQueens = this.WhiteQueens | Constants.BITSET[i];
        } 
        if (this.Squares[i] == Constants.WHITE_ROOK) 
        {
            this.WhiteRooks = this.WhiteRooks | Constants.BITSET[i];
        }
        if (this.Squares[i] == Constants.WHITE_BISHOP) 
        {
            this.WhiteBishops = this.WhiteBishops | Constants.BITSET[i];
        }
        if (this.Squares[i] == Constants.WHITE_KNIGHT) 
        {
            this.WhiteKnights = this.WhiteKnights | Constants.BITSET[i];
        }
        if (this.Squares[i] == Constants.WHITE_PAWN) 
        {
            this.WhitePawns = this.WhitePawns | Constants.BITSET[i];
        }

        this.WhitePieces = this.WhiteKing | this.WhiteQueens | 
                           this.WhiteRooks | this.WhiteBishops | 
                           this.WhiteKnights | this.WhitePawns;
        this.BlackPieces = this.BlackKing | this.BlackQueens | 
                           this.BlackRooks | this.BlackBishops | 
                           this.BlackKnights | this.BlackPawns;
        this.SquaresOccupied = this.WhitePieces | this.BlackPieces;
    }
}

예 3-이동 생성 :

// We can't capture one of our own pieces.
eligibleSquares = ~this.WhitePieces;

// Generate moves for white knights.
remainingKnights = this.WhiteKnights;

// Generate the moves for each knight...
while (remainingKnights != 0)
{
    squareFrom = BitOps.BitScanForward(remainingKnights);
    generatedMoves = Constants.ATTACKS_KNIGHT[squareFrom] & eligibleSquares;
    while (generatedMoves != 0)
    {
        squareTo = BitOps.BitScanForward(generatedMoves);
        moveList.Add(new Move(squareFrom, squareTo, Constants.WHITE_KNIGHT, 
                              this.Squares[squareTo], Constants.EMPTY));
        generatedMoves ^= Constants.BITSET[squareTo];
    }
    // Finished with this knight - move on to the next one.
    remainingKnights ^= Constants.BITSET[squareFrom];
}    

예 4-재료 점수 계산 :

// Material score from scratch, in centipawns from White's perspective.
internal static Int32 ScoreMaterial(Board position)
{
    return BitOps.BitCountWegner(position.WhitePawns)   * Constants.VALUE_PAWN +
           BitOps.BitCountWegner(position.WhiteKnights) * Constants.VALUE_KNIGHT +
           BitOps.BitCountWegner(position.WhiteBishops) * Constants.VALUE_BISHOP +
           BitOps.BitCountWegner(position.WhiteRooks)   * Constants.VALUE_ROOK   +
           BitOps.BitCountWegner(position.WhiteQueens)  * Constants.VALUE_QUEEN  -
           BitOps.BitCountWegner(position.BlackPawns)   * Constants.VALUE_PAWN   -
           BitOps.BitCountWegner(position.BlackKnights) * Constants.VALUE_KNIGHT -
           BitOps.BitCountWegner(position.BlackBishops) * Constants.VALUE_BISHOP -
           BitOps.BitCountWegner(position.BlackRooks)   * Constants.VALUE_ROOK   -
           BitOps.BitCountWegner(position.BlackQueens)  * Constants.VALUE_QUEEN;
}

예 5-피스 이동성 계산 :

// Calculate mobility score for white knights.
remainingPieces = position.WhiteKnights;
while (remainingPieces != 0)
{
    squareFrom = BitOps.BitScanForward(remainingPieces);
    mobilityKnight += BitOps.BitCountWegner(Constants.ATTACKS_KNIGHT[squareFrom]
                                            & unoccupiedSquares);
    remainingPieces ^= Constants.BITSET[squareFrom];
 }

moveList의 정의를 제공 할 수 있습니까?
Carlos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.