วิธีแสดงสถานะหมากรุกด้วย bitboard


11

ฉันสนใจการเขียนโปรแกรมตัวหมากรุกและใช้ bitboards เพื่อเป็นตัวแทนของเกม ฉันรู้ว่ามีเครื่องมือหมากรุกโอเพนซอร์ซสองสามตัวที่ใช้บิตบอร์ด แต่มันไม่ง่ายนักที่จะดูรหัสและเข้าใจสิ่งที่เกิดขึ้น ฉันกำลังมองหาวัสดุอ้างอิงที่ดีเกี่ยวกับวิธีการแสดงสถานะทั้งหมดใน bitboards

อธิบายวิธีรักษาสถานะของเกมอย่างชัดเจนโดยใช้ bitboards และโดยเฉพาะอย่างยิ่งวิธีสร้างรายการการเคลื่อนไหวที่ถูกต้องจาก bitboard ที่กำหนดหรือการอ้างอิงที่ดีกับคำอธิบายนั้นจะทำให้คุณได้รับเครื่องหมายถูกสีเขียว


3
1. OP ไม่แสดงความรู้ในหัวข้อ นั่นคือ OP ไม่ได้พยายามอย่างจริงจังเพื่อให้ความรู้กับตัวเอง 2. เป็นเรื่องเกี่ยวกับการเขียนโปรแกรมไม่ใช่หมากรุก
Tony Ennis

คำตอบ:


10

ทรัพยากรที่ดีที่สุดสำหรับการเขียนโปรแกรมเครื่องยนต์หมากรุกเป็นหมากรุก Programming วิกิพีเดียซึ่งมีขนาดใหญ่ส่วน bitboards ทุกสิ่งที่คุณต้องการในการสร้างเอ็นจิ้นบิตบอร์ดจะอยู่ที่นั่นแม้ว่ามันจะค่อนข้างกระจายออกไปและบางครั้งก็เขียนโดยคนที่ภาษาอังกฤษเป็นภาษาที่สอง


ลิงก์ 2 ไม่ถูกต้องในขณะนี้
Jackson Tale

1
พวกเขายังคงทำงานให้ฉันได้ตามเวลาที่ฉันเขียนความคิดเห็นนี้
dfan

8

คุณต้องการใช้ภาษาโปรแกรมภาษาใด

ในการดำเนินการ bitboard ใน C # ให้ใช้System.UInt64 สิ่งนี้สามารถเก็บ 64 บิต 1 สำหรับแต่ละตารางกระดานหมากรุก ชนิดของค่านี้ให้ตัวเองกับการดำเนินการระดับบิตเร็วจำนวนมาก

นี้เป็นที่ดี bitboard กวดวิชา

นี่คือตัวอย่างจากเครื่องมือหมากรุก C # ของฉันเอง อย่างที่คุณเห็นจากโค้ดมันใช้เวลาสักพักหนึ่งในการพันหัวโดยใช้ bitboards แต่โดยทั่วไปมันจะเร็วมากโดยเฉพาะการประเมินตำแหน่ง

ตัวอย่างที่ 1 - นิยามของ Bitboard:

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

ตัวอย่างที่ 2 - การกำหนดค่าเริ่มต้นของ 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;
    }
}

ตัวอย่างที่ 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.