Comment représenter l'état des échecs avec un bitboard

11

Je suis intéressé par la programmation d'un moteur d'échecs et l'utilisation de bitboards pour représenter l'état du jeu. Je sais qu'il existe quelques moteurs d'échecs open source qui utilisent des bitboards, mais ce n'est pas si facile de regarder le code et de comprendre ce qui se passe. Je recherche un bon matériel de référence sur la façon de représenter tout l'état dans les bitboards.

Expliquer clairement comment maintenir l'état du jeu à l'aide de bitboards, et surtout comment générer une liste de mouvements valides à partir d'un bitboard donné, ou fournir de bonnes références à une telle explication vous fera gagner la coche verte.

axiopistie
la source
3
1. OP ne montre aucune connaissance du sujet. Autrement dit, le PO n'a pas essayé sérieusement de s'instruire. 2. Il s'agit de programmation, pas d'échecs
Tony Ennis

Réponses:

10

La meilleure ressource pour la programmation du moteur d'échecs est le wiki de programmation d'échecs , qui a une grande section sur les bitboards . Tout ce dont vous avez besoin pour créer un moteur à base de bitboard est là, bien qu'il soit plutôt étalé et parfois écrit par des personnes pour lesquelles l'anglais est une deuxième langue.

dfan
la source
Les 2 liens sont invalides maintenant.
Jackson Tale
1
Ils travaillent toujours pour moi au moment où j'écris ce commentaire.
dfan
8

Quel langage de programmation souhaitez-vous utiliser?

Pour implémenter un bitboard en C #, utilisez System.UInt64 . Cela peut contenir 64 bits, 1 pour chaque carré de l'échiquier. Ce type de valeur se prête à de nombreuses opérations rapides au niveau du bit.

Ceci est un bon tutoriel bitboard .

Voici quelques exemples de mon propre moteur d'échecs C #. Comme vous pouvez le voir dans le code, cela peut prendre un certain temps pour vous envelopper avec des bitboards, mais ils sont généralement très rapides, en particulier pour l'évaluation de la position.

Exemple 1 - Définition du Bitboard:

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

Exemple 2 - Initialisation de 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;
    }
}

Exemple 3 - Génération de mouvement:

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

Exemple 4 - Calculer le score matériel:

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

Exemple 5 - Calcul de la mobilité des pièces:

// 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];
 }
HTTP 410
la source
pouvez-vous donner la définition de moveList?
Carlos