Bagaimana cara mewakili negara catur dengan bitboard

11

Saya tertarik memprogram mesin catur dan menggunakan bitboard untuk mewakili kondisi permainan. Saya tahu ada beberapa mesin catur open source yang menggunakan bitboard, tetapi tidak begitu mudah untuk melihat kode dan memahami apa yang sedang terjadi. Saya mencari bahan referensi yang bagus tentang cara mewakili semua negara dalam bitboard.

Menjelaskan dengan jelas bagaimana mempertahankan keadaan permainan menggunakan bitboard, dan terutama bagaimana membuat daftar langkah yang valid dari bitboard yang diberikan, atau memberikan referensi yang bagus untuk penjelasan seperti itu akan memberi Anda tanda centang hijau.

aksioma
sumber
3
1. OP tidak menunjukkan pengetahuan tentang topik tersebut. Artinya, OP belum berusaha serius untuk mendidik dirinya sendiri. 2. Ini tentang pemrograman, bukan catur
Tony Ennis

Jawaban:

10

Sumber daya terbaik untuk pemrograman mesin catur adalah Chiki Programming Wiki , yang memiliki bagian besar pada bitboard . Semua yang Anda butuhkan untuk membuat mesin berbasis bitboard ada di sana, meskipun agak tersebar dan terkadang ditulis oleh orang-orang yang bahasa Inggrisnya adalah bahasa kedua.

dfan
sumber
2 tautan tidak valid sekarang.
Jackson Tale
1
Mereka masih bekerja untuk saya pada saat saya menulis komentar ini.
dfan
8

Bahasa pemrograman apa yang ingin Anda gunakan?

Untuk mengimplementasikan bitboard di C #, gunakan System.UInt64 . Ini dapat menampung 64 bit, 1 untuk setiap kuadrat papan catur. Jenis nilai ini cocok untuk banyak operasi bitwise cepat.

Ini adalah tutorial bitboard yang bagus .

Berikut adalah beberapa contoh dari mesin catur C # saya sendiri. Seperti yang dapat Anda lihat dari kode, dibutuhkan waktu untuk membungkus kepala Anda menggunakan bitboard, tetapi biasanya sangat cepat, terutama untuk evaluasi posisi.

Contoh 1 - Definisi Bitboard:

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

Contoh 2 - Inisialisasi Bitboard:

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

Contoh 3 - Pindahkan generasi:

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

Contoh 4 - Hitung skor materi:

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

Contoh 5 - Menghitung mobilitas bagian:

// 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];
 }
HTTP 410
sumber
dapatkah Anda memberikan definisi moveList?
Carlos