Sunt interesat să programez un motor de șah și să folosesc bitboards pentru a reprezenta starea jocului. Știu că există câteva motoare de șah open source care folosesc bitboard-uri, dar nu este atât de ușor să privești codul și să înțelegi ce se întâmplă. Caut materiale de referință bune despre cum să reprezint toată starea în bitboard-uri.
Explicați în mod clar cum să mențineți starea jocului folosind bitboard-uri și, mai ales, cum să generați o listă de mutări valide dintr-un bitboard dat sau să furnizați referințe bune la o astfel de explicație, veți câștiga bifa verde.
Comentarii
- 1. OP nu arată cunoștințe despre subiect. Adică, PO nu a încercat serios să se educe. 2. Este vorba despre programare, nu despre șah
- @TonyEnnis De ce trebuie să te comporti atât de nepoliticos cu semenii ??, să ai un pic de respect și să-i arăți ce ar trebui să îmbunătățească, mai degrabă decât să fie atât de acră
- Afirmarea faptelor nu este nepoliticoasă sau acră, @AryanParekh
- @Tonny Ennis. Imaginați-vă că ați fost un începător, nou și că purtați doar o întrebare în speranța că ' veți obține un răspuns bun. Și apoi vezi un comentariu de genul asta. Au fost reluate alte persoane pentru a răspunde la întrebările sale? Sau vă simțiți prea ridicat pentru a-l lua în considerare.
Răspuns
Cea mai bună resursă pentru programarea motorului de șah este Wiki de programare a șahului , care are o secțiune mare pe bitboard-uri . Tot ce aveți nevoie pentru a crea un motor bazat pe bitboard este acolo, deși este destul de răspândit și uneori scris de oameni pentru care engleza este a doua limbă.
Comentarii
- Cele 2 linkuri sunt nevalide acum.
- Acestea funcționează în continuare pentru mine încă din momentul în care scriu acest comentariu.
Răspunde
Ce limbaj de programare vrei să folosești?
Pentru a implementa un bitboard în C #, folosește System.UInt64 . Acesta poate conține 64 de biți, 1 pentru fiecare pătrat al tabloului de șah. Acest tip de valoare se pretează la multe operații rapide pe biți.
Acesta este un tutorial bun pentru bitboard .
Iată câteva exemple din propriul meu motor de șah C #. După cum puteți vedea din cod, poate dura ceva timp să vă înfășurați folosiți plăcile de biți, dar acestea sunt de obicei foarte rapide, în special pentru evaluarea poziției.
Exemplul 1 – Definiția plăcii de biți:
internal UInt64 WhiteKing; internal UInt64 WhiteQueens; internal UInt64 WhiteRooks; internal UInt64 WhiteBishops; internal UInt64 WhiteKnights; internal UInt64 WhitePawns; internal UInt64 WhitePieces;
Exemplul 2 – Inițializare 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; } }
Exemplul 3 – Generare mutare:
// 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]; }
Exemplul 4 – Calculați scorul materialului:
// 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; }
Exemplul 5 – Calculul mobilității piesei:
// 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]; }
Comentarii
- puteți furniza definiția moveList?