Estoy interesado en programar un motor de ajedrez y usar tableros de bits para representar el estado del juego. Sé que hay algunos motores de ajedrez de código abierto que usan bitboards, pero no es tan fácil mirar el código y comprender lo que está pasando. Estoy buscando un buen material de referencia sobre cómo representar todo el estado en bitboards.
Explicar claramente cómo mantener el estado del juego usando bitboards, y especialmente cómo generar una lista de movimientos válidos a partir de cualquier bitboard, o proporcionar buenas referencias a dicha explicación, te otorgará la marca de verificación verde.
Comentarios
- 1. OP no muestra conocimiento del tema. Es decir, el OP no ha intentado seriamente educarse. 2. Se trata de programación, no de ajedrez
- @TonyEnnis ¿Por qué tienes que comportarte de manera tan grosera con tus compañeros ??, ten un poco de respeto y muéstrale lo que debería mejorar en lugar de ser tan amargado
- Declarar hechos no es ser grosero o amargo, @AryanParekh
- @Tonny Ennis. Imagina que eres un principiante, nuevo y que simplemente estás haciendo una pregunta con la esperanza de ' obtendrás una buena respuesta. Y luego ves un comentario como ese. ¿Se repite a otras personas para responder a sus preguntas? ¿O te sientes demasiado alto para considerarlo?
Answer
El mejor recurso para la programación de motores de ajedrez es la Wiki de programación de ajedrez , que tiene una gran sección sobre tableros de bits . Todo lo que necesita para hacer un motor basado en bitboard está ahí, aunque está bastante extendido y, a veces, está escrito por personas para quienes el inglés es un segundo idioma.
Comentarios
- Los 2 enlaces no son válidos ahora.
- Todavía funcionan para mí en el momento en que escribo este comentario.
Respuesta
¿Qué lenguaje de programación quieres usar?
Para implementar un bitboard en C #, usa System.UInt64 . Puede contener 64 bits, 1 por cada casilla del tablero de ajedrez. Este tipo de valor se presta a muchas operaciones rápidas bit a bit.
Este es un buen tutorial de bitboard .
Aquí hay algunos ejemplos de mi propio motor de ajedrez C #. Como puede ver en el código, puede llevar un tiempo ajustar su Utilice bitboards, pero normalmente son muy rápidos, especialmente para la evaluación de posiciones.
Ejemplo 1 – Definición de bitboard:
internal UInt64 WhiteKing; internal UInt64 WhiteQueens; internal UInt64 WhiteRooks; internal UInt64 WhiteBishops; internal UInt64 WhiteKnights; internal UInt64 WhitePawns; internal UInt64 WhitePieces;
Ejemplo 2 – Inicialización de 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; } }
Ejemplo 3 – Generación de movimiento:
// 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]; }
Ejemplo 4: Calcular la puntuación del material:
// 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; }
Ejemplo 5 – Cálculo de la movilidad de la pieza:
// 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]; }
Comentarios
- ¿Puede proporcionar la definición de moveList?