チェスエンジンをプログラミングし、ビットボードを使用してゲームの状態を表現することに興味があります。ビットボードを使用するいくつかのオープンソースのチェスエンジンですが、コードを見て何が起こっているのかを理解するのはそれほど簡単ではありません。ビットボードですべての状態を表す方法に関する優れた参考資料を探しています。
ビットボードを使用してゲームの状態を維持する方法、特に特定のビットボードから有効な動きのリストを生成する方法を明確に説明するか、そのような説明への適切な参照を提供すると、緑色のチェックマークが付けられます。
コメント
- 1。 OPはトピックの知識を示していません。つまり、OPは真剣に自分自身を教育しようとはしていません。 2.これはプログラミングに関するものであり、チェスではありません
- @TonyEnnisなぜ仲間にそんなに失礼な行動をとる必要があるのですか??
- 事実を述べることは失礼でも酸っぱいことでもありません、@ AryanParekh
- @TonnyEnnis。あなたが初心者で、新しく、良い答えが得られることを期待して質問をしているだけだと想像してみてください。'そして、あなたはそのようなコメントを見ます。他の人は彼の質問に答えるのを遅らせていますか?または、自分のことを考えるには高すぎると感じますか。
回答
チェスエンジンプログラミングに最適なリソースはチェスプログラミングWiki で、ビットボードに大きなセクションがあります。ビットボードベースのエンジンを作成するために必要なものはすべてそろっていますが、それはかなり広まっていて、英語が第二言語である人々によって書かれることもあります。
コメント
- 2つのリンクは現在無効です。
- このコメントを書いている時点では、まだ機能しています。
回答
どのプログラミング言語を使用しますか?
C#でビットボードを実装するには、 System.UInt64 。これは、チェスボードの各正方形に1つずつ、64ビットを保持できます。この値のタイプは、多くの高速ビット単位操作に役立ちます。
これは優れたビットボードチュートリアル。
これが私自身のC#チェスエンジンの例です。コードからわかるように、ラップするのに時間がかかる場合があります。ビットボードを使用して動き回るが、特に位置評価の場合、通常は非常に高速である。
例1-ビットボードの定義:
internal UInt64 WhiteKing; internal UInt64 WhiteQueens; internal UInt64 WhiteRooks; internal UInt64 WhiteBishops; internal UInt64 WhiteKnights; internal UInt64 WhitePawns; internal UInt64 WhitePieces;
例2-ビットボードの初期化:
// 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の定義を提供できますか?