Wie man den Schachzustand mit einem Bitboard darstellt


10

Ich bin daran interessiert, eine Schach-Engine zu programmieren und Bitboards zu verwenden, um den Stand des Spiels darzustellen. Ich weiß, dass es einige Open-Source-Schach-Engines gibt, die Bitboards verwenden, aber es ist nicht so einfach, sich den Code anzusehen und zu verstehen, was los ist. Ich suche nach gutem Referenzmaterial, wie man den gesamten Status in Bitboards darstellt.

Wenn Sie klar erklären, wie Sie den Status des Spiels mithilfe von Bitboards aufrechterhalten und insbesondere eine Liste gültiger Züge aus einem bestimmten Bitboard erstellen oder gute Verweise auf eine solche Erklärung angeben, erhalten Sie das grüne Häkchen.


3
1. OP zeigt keine Kenntnis des Themas. Das heißt, das OP hat nicht ernsthaft versucht, sich weiterzubilden. 2. Hier geht es um Programmierung, nicht um Schach
Tony Ennis

Antworten:


10

Die beste Ressource für die Programmierung von Schachmaschinen ist das Schachprogrammier-Wiki , das einen großen Abschnitt über Bitboards enthält . Alles, was Sie brauchen, um eine Bitboard-basierte Engine zu erstellen, ist vorhanden, obwohl sie ziemlich verbreitet ist und manchmal von Leuten geschrieben wird, für die Englisch eine zweite Sprache ist.


Die 2 Links sind jetzt ungültig.
Jackson Tale

1
Sie arbeiten immer noch für mich, als ich diesen Kommentar schreibe.
dfan

8

Welche Programmiersprache möchten Sie verwenden?

Verwenden Sie System.UInt64, um ein Bitboard in C # zu implementieren . Dies kann 64 Bit enthalten, 1 für jedes Quadrat des Schachbretts. Dieser Wertetyp eignet sich für viele schnelle bitweise Operationen.

Dies ist ein gutes Bitboard-Tutorial .

Hier sind einige Beispiele aus meiner eigenen C # -Schachmaschine. Wie Sie dem Code entnehmen können, kann es eine Weile dauern, bis Sie Ihren Kopf mit Bitboards umwickelt haben. Diese sind jedoch in der Regel sehr schnell, insbesondere für die Positionsbewertung.

Beispiel 1 - Bitboard-Definition:

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

Beispiel 2 - Bitboard-Initialisierung:

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

Beispiel 3 - Bewegungsgenerierung:

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

Beispiel 4 - Materialbewertung berechnen:

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

Beispiel 5 - Berechnung der Stückbeweglichkeit:

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

Können Sie die Definition von moveList angeben?
Carlos
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.