12

I'm interested in programming a chess engine and using bitboards to represent the state of the game. I know there are a few open source chess engines that use bitboards, but its not so easy to look at the code and understand what is going on. I'm looking for good reference material on how to represent all the state in bitboards.

Clearly explaining how to maintain the state of the game using bitboards, and especially how to generate a list of valid moves from any given bitboard, or supplying good references to such an explanation will earn you the green check mark.

6
  • 3
    1. OP shows no knowledge of the topic. That is, the OP has not tried seriously to educate himself. 2. This is about programming, not chess
    – Tony Ennis
    Sep 12, 2013 at 12:13
  • 1
    @TonyEnnis Why do you have to act so rude to fellow people??, have a little bit of respect and show him what she should improve rather than being so sour
    – user24649
    Sep 6, 2020 at 12:04
  • 1
    @Tonny Ennis. Imagine you were a a beginner, new and were merely asking a question in hopes you'll get a good answer. And then you see a comment like that. Are other people retarted to answer his questions? Or do you feel too high of yourself to consider it.
    – user24649
    Sep 9, 2020 at 4:31
  • 1
    @TonyEnnis People like you are what make stack exchange so toxic.
    – Marlon
    May 30, 2021 at 21:45
  • 1
    @TonyEnnis programming specific to chess engines is explicitly on-topic.
    – qwr
    Aug 21, 2022 at 0:25

2 Answers 2

14

The best resource for chess engine programming is the Chess Programming Wiki, which has a large section on bitboards. Everything you need to make a bitboard-based engine is there, although it's rather spread out and sometimes written by people for whom English is a second language.

0
11

What programming language do you want to use?

To implement a bitboard in C#, use System.UInt64. This can hold 64 bits, 1 for each square of the chess board. This value type lends itself to many fast bitwise operations.

This is a good bitboard tutorial.

Here are some examples from my own C# chess engine. As you can see from the code, it can take a while to wrap your head around using bitboards, but they are typically very fast, especially for position evaluation.

Example 1 - Bitboard definition:

internal UInt64 WhiteKing;
internal UInt64 WhiteQueens;
internal UInt64 WhiteRooks;
internal UInt64 WhiteBishops;
internal UInt64 WhiteKnights;
internal UInt64 WhitePawns;
internal UInt64 WhitePieces;

Example 2 - Bitboard initialisation:

// 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;
    }
}

Example 3 - Move generation:

// 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];
}    

Example 4 - Calculate material score:

// 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;
}

Example 5 - Calculating piece mobility:

// 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];
 }
1
  • can you provide the definition of moveList?
    – Carlos
    Jul 11, 2017 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.