Ich bin daran interessiert, eine Schach-Engine zu programmieren und Bitboards zu verwenden, um den Status des Spiels darzustellen. Ich weiß, dass es solche gibt Einige Open-Source-Schach-Engines, die Bitboards verwenden, aber es ist nicht so einfach, den Code zu betrachten und zu verstehen, was vor sich geht. Ich suche nach gutem Referenzmaterial, wie der gesamte Status in Bitboards dargestellt werden kann.
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.
Kommentare
- 1. OP zeigt keine Kenntnis des Themas. Das heißt, das OP hat nicht ernsthaft versucht, sich weiterzubilden. 2. Hier geht es um Programmieren, nicht um Schach.
- @TonyEnnis Warum musst du so unhöflich gegenüber Mitmenschen sein?, Ein bisschen Respekt haben und ihm zeigen, was sie verbessern sollte, anstatt so sauer zu sein
- Die Angabe von Fakten ist nicht unhöflich oder sauer, @AryanParekh
- @Tonny Ennis. Stellen Sie sich vor, Sie waren ein Anfänger, neu und stellten lediglich eine Frage in der Hoffnung, dass Sie ' eine gute Antwort erhalten. Und dann sehen Sie einen solchen Kommentar. Werden andere Personen erneut gestartet, um seine Fragen zu beantworten? Oder fühlen Sie sich zu hoch, um darüber nachzudenken?
Antwort
Die beste Ressource für die Programmierung von Schachengines ist das Schachprogrammier-Wiki , das einen großen Abschnitt auf Bitboards enthält. Alles, was Sie brauchen, um eine Bitboard-basierte Engine zu erstellen, ist vorhanden, obwohl sie „ziemlich verbreitet und manchmal von Leuten geschrieben ist, für die Englisch eine zweite Sprache ist.
Kommentare
- Die 2 Links sind jetzt ungültig.
- Sie funktionieren immer noch für mich, wenn ich diesen Kommentar schreibe.
Antwort
Welche Programmiersprache möchten Sie verwenden?
Um ein Bitboard in C # zu implementieren, verwenden Sie System.UInt64 . Dies kann 64 Bit enthalten, 1 für jedes Quadrat des Schachbretts. Dieser Werttyp eignet sich für viele schnelle bitweise Operationen.
Dies ist eine gutes Bitboard-Tutorial .
Hier sind einige Beispiele aus meiner eigenen C # -Schach-Engine Verwenden Sie Bitboards, 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]; }
Kommentare
- Können Sie die Definition von moveList angeben?