Welche Programmiersprache möchten Sie verwenden?
Verwenden Sie System.UInt64, um ein Bitboard in C # zu implementieren . Dies kann 64 Bit enthalten, 1 für jedes Quadrat des Schachbretts. Dieser Wertetyp eignet sich für viele schnelle bitweise Operationen.
Dies ist ein gutes Bitboard-Tutorial .
Hier sind einige Beispiele aus meiner eigenen C # -Schachmaschine. Wie Sie dem Code entnehmen können, kann es eine Weile dauern, bis Sie Ihren Kopf mit Bitboards umwickelt haben. Diese sind jedoch in der Regel sehr schnell, insbesondere für die Positionsbewertung.
Beispiel 1 - Bitboard-Definition:
internal UInt64 WhiteKing;
internal UInt64 WhiteQueens;
internal UInt64 WhiteRooks;
internal UInt64 WhiteBishops;
internal UInt64 WhiteKnights;
internal UInt64 WhitePawns;
internal UInt64 WhitePieces;
Beispiel 2 - Bitboard-Initialisierung:
// 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;
}
}
Beispiel 3 - Bewegungsgenerierung:
// 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];
}
Beispiel 4 - Materialbewertung berechnen:
// 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;
}
Beispiel 5 - Berechnung der Stückbeweglichkeit:
// 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];
}