Bir bitboard ile satranç devleti nasıl temsil edilir


11

Bir satranç motorunu programlamak ve oyunun durumunu göstermek için bitboard'ları kullanmakla ilgileniyorum. Bitboard kullanan birkaç açık kaynaklı satranç motoru olduğunu biliyorum, ancak koda bakmak ve neler olduğunu anlamak o kadar kolay değil. Bitboard'larda tüm durumun nasıl temsil edileceği konusunda iyi referans materyalleri arıyorum.

Bitboard'ları kullanarak oyunun durumunu nasıl koruyacağınızı ve özellikle herhangi bir bitboarddan geçerli hareketlerin bir listesini nasıl oluşturacağınızı veya böyle bir açıklamaya iyi referanslar verdiğinizi açık bir şekilde yeşil onay işareti kazanacaksınız.


3
1. OP konu hakkında hiçbir bilgi göstermez. Yani, OP kendini eğitmeye ciddiye almadı. 2. Bu satranç değil programlama ile ilgilidir
Tony Ennis

Yanıtlar:


10

Satranç motoru programlama için en iyi kaynak , bitboard'larda büyük bir bölümü olan Chess Programming Wiki'dir . Bitboard tabanlı bir motor yapmak için ihtiyacınız olan her şey orada olmasına rağmen, oldukça yayılmış ve bazen İngilizce ikinci dil olan insanlar tarafından yazılmıştır.


2 bağlantı şu anda geçersiz.
Jackson Tale

1
Bu yorumu yazdığım sırada hala benim için çalışıyorlar.
dfan

8

Hangi programlama dilini kullanmak istiyorsunuz?

C # 'da bir bitboard uygulamak için System.UInt64 kullanın . Bu, satranç tahtasının her karesi için 1, 64 bit tutabilir. Bu değer türü, birçok hızlı bitsel işlem için uygundur.

Bu iyi bir bitboard öğreticisidir .

İşte kendi C # satranç motorumdan bazı örnekler. Koddan da görebileceğiniz gibi, başınızı bitboard kullanarak sarmak biraz zaman alabilir, ancak özellikle konum değerlendirmesi için genellikle çok hızlıdır.

Örnek 1 - Bitboard tanımı:

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

Örnek 2 - Bitboard'u başlatma:

// 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;
    }
}

Örnek 3 - Hareket üretimi:

// 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];
}    

Örnek 4 - Malzeme puanını hesaplayın:

// 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;
}

Örnek 5 - Parça hareketliliğinin hesaplanması:

// 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 tanımını sağlayabilir misiniz?
Carlos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.