Mám zájem o programování šachového enginu a použití bitboardů k vyjádření stavu hry. Vím, že existují několik šachových modulů s otevřeným zdrojovým kódem, které používají bitboardy, ale není tak snadné podívat se na kód a pochopit, o co jde. Hledám dobrý referenční materiál o tom, jak reprezentovat celý stav v bitboardech.
Jasné vysvětlení, jak udržovat stav hry pomocí bitboardů, a zejména jak vygenerovat seznam platných tahů z kteréhokoli daného bitboardu, nebo poskytnutí dobrých odkazů na takové vysvětlení, vám zajistí zelenou značku zaškrtnutí.
Komentáře
- 1. OP nevykazuje žádné znalosti daného tématu. To znamená, že OP se nepokusil vážně se vzdělávat. 2. Tady jde o programování, ne o šachy
- @TonyEnnis Proč musíte jednat tak hrubě k bližním ??, mít trochu respektu a ukázat mu, v čem by se měla zlepšit, než aby byla tak kyselá
- Uvedení faktů není hrubé ani kyselé, @AryanParekh
- @Tonny Ennis. Představte si, že jste začátečník, nový a jen se ptáte v naději, že ' dostanete dobrou odpověď. A pak uvidíte takový komentář. Odpovídají na jeho otázky další lidé? Nebo se cítíte příliš vysoko na to, abyste to zvážili.
Odpověď
Nejlepší zdroj pro programování šachových strojů je Chess Programming Wiki , která má velkou sekci na bitboardech . Všechno, co potřebujete k výrobě bitcoinového enginu, je tam, i když je poměrně rozšířené a někdy je napsáno lidmi, pro které je angličtina druhým jazykem.
Komentáře
- Tyto 2 odkazy jsou nyní neplatné.
- Stále pro mě fungují, když píšu tento komentář.
Odpověď
Jaký programovací jazyk chcete použít?
K implementaci bitboardu v C # použijte System.UInt64 . To může pojmout 64 bitů, 1 pro každý čtverec šachovnice. Tento typ hodnoty je vhodný pro mnoho rychlých bitových operací.
Toto je dobrý výukový program pro bitboardy .
Zde je několik příkladů z mého vlastního šachového enginu C #. Jak vidíte z kódu, zabalení vašeho obsahu může chvíli trvat začněte používat bitboardy, ale obvykle jsou velmi rychlé, zejména pro vyhodnocení polohy.
Příklad 1 – definice bitboardu:
internal UInt64 WhiteKing; internal UInt64 WhiteQueens; internal UInt64 WhiteRooks; internal UInt64 WhiteBishops; internal UInt64 WhiteKnights; internal UInt64 WhitePawns; internal UInt64 WhitePieces;
Příklad 2 – Inicializace bitboardu:
// 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; } }
Příklad 3 – Generování přesunu:
// 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]; }
Příklad 4 – Výpočet skóre materiálu:
// 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; }
Příklad 5 – Výpočet pohyblivosti kusu:
// 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]; }
Komentáře
- můžete poskytnout definici moveList?