I am beginning to understand magic bitboards. I have successfully implemented them with Rooks, and I am currently working with Bishops. The method is very similar though.


I have a bishop on g7 and a rook on e5. Obviously the bishops moves are restricted by the rook, however my resulting bishop moves are wrong. He can travel to all squares after the rook. I think that on an empty board, my bishop can travel fine, so it must be how I deal with magics.

[FEN "8/8/5B2/8/3r4/8/8/8 w - - 0 1"]


After looking at this a while, assuming my bishops moves are fine, it is to do with the indexing when I pre-calculate the move set. Here is how I do that:

   for (int sq = 0; sq <= 63; sq++){
        UInt64 blockerMask = innerBAtks(sq); // Get attack squares for bishop on an empty board
        int bits = BitOperations.PopCount(blockerMask);  
        UInt64[] blockerBoardArray = test(blockerMask);   
        BishopMagic[sq].blockerMask = blockerMask;
        BishopMagic[sq].blockerBoards = new UInt64[1 << bits];
        BishopMagic[sq].moveBoard = new UInt64[1 << bits];

        for (int i = 0; i < (1 << bits); i++){
            UInt64 blockerBoard = blockerBoardArray[i]; 
            UInt64 index = (magicB[sq] * blockerBoard) >> (64 - nBBits[sq]);
            BishopMagic[sq].blockerBoards[index] = blockerBoard;
            BishopMagic[sq].moveBoard[index] = moveBoardBishop(sq, blockerBoard);

To use it, I do the following:

        int sq = BitOperations.TrailingZeroCount(bishopPos);
        UInt64 blockerBoard = 0x0;
        UInt64 occupancy = ((northEast(sq) | southEast(sq) | northWest(sq) | southWest(sq)) & ~LUTable.Border);
        blockerBoard = board.AllPieces & occupancy;
        UInt64 moveIndex = (magic.magicB[sq] * blockerBoard) >> (64 - magic.nBBits[sq]);
        occupancy = magic.BishopMagic[sq].moveBoard[moveIndex];
        return occupancy;

If you need more information, please let me know!

  • It's hard to know what the problem is without a little more information. Are you saying that the move board you get back in the case you mentioned is as if the bishop was moving on an empty board? In that case I'd double check your moveBoardBishop method. And are you sure occupancy is being calculated correctly in the second block? The directions thing seems strange to me when you have innerBAttacks that would do the job. Post the bodies of some of your other methods and we can get a better idea of where the problem is – Jeff Wilson Jun 26 '20 at 13:08