Mi interessa programmare un motore scacchistico e utilizzare bitboard per rappresentare lo stato del gioco. So che ci sono alcuni motori scacchistici open source che utilizzano bitboard, ma non è così facile guardare il codice e capire cosa sta succedendo. Sto cercando un buon materiale di riferimento su come rappresentare tutto lo stato nei bitboard.
Spiegare chiaramente come mantenere lo stato del gioco usando i bitboard, e soprattutto come generare un elenco di mosse valide da un dato bitboard, o fornire buoni riferimenti a tale spiegazione ti farà guadagnare il segno di spunta verde.
Commenti
- 1. OP non mostra alcuna conoscenza dellargomento. Cioè, lOP non ha cercato seriamente di istruirsi. 2. Si tratta di programmazione, non di scacchi
- @TonyEnnis Perché devi comportarti in modo così scortese con gli altri ??, avere un po di rispetto e mostrargli cosa dovrebbe migliorare invece di essere così aspro
- Affermare i fatti non significa essere scortesi o aspri, @AryanParekh
- @Tonny Ennis. Immagina di essere un principiante, nuovo e di fare semplicemente una domanda nella speranza che ' ottenga una buona risposta. E poi vedi un commento del genere. Altre persone sono costrette a rispondere alle sue domande? O ti senti troppo in alto di te stesso per prenderlo in considerazione.
Risposta
La migliore risorsa per la programmazione del motore scacchistico è il Wiki di programmazione scacchistica , che ha unampia sezione sui bitboard . Tutto ciò di cui hai bisogno per creare un motore basato su bitboard è lì, anche se è piuttosto diffuso e talvolta scritto da persone per le quali linglese è una seconda lingua.
Commenti
- I 2 link non sono validi adesso.
- Funzionano ancora per me dal momento in cui scrivo questo commento.
Risposta
Quale linguaggio di programmazione desideri utilizzare?
Per implementare una bitboard in C #, utilizza System.UInt64 . Può contenere 64 bit, 1 per ogni quadrato della scacchiera. Questo tipo di valore si presta a molte operazioni bit per bit veloci.
Questo è un buon tutorial su bitboard .
Ecco alcuni esempi dal mio motore di scacchi C #. Come puoi vedere dal codice, può volerci un po per avvolgere il tuo andare in giro usando bitboard, ma in genere sono molto veloci, soprattutto per la valutazione della posizione.
Esempio 1 – definizione di bitboard:
internal UInt64 WhiteKing; internal UInt64 WhiteQueens; internal UInt64 WhiteRooks; internal UInt64 WhiteBishops; internal UInt64 WhiteKnights; internal UInt64 WhitePawns; internal UInt64 WhitePieces;
Esempio 2 – Inizializzazione 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; } }
Esempio 3 – Generazione di mosse:
// 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]; }
Esempio 4 – Calcola il punteggio del materiale:
// 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; }
Esempio 5 – Calcolo della mobilità dei pezzi:
// 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]; }
Commenti
- puoi fornire la definizione di moveList?