The following functions are needed:
uint64_t blockermask_rook (int square); uint64_t blockermask_bishop (int square); uint64_t moveboard_rook (int square, uint64_t blockerboard); uint64_t moveboard_bishop (int square, uint64_t blockerboard); uint64_t blockerboard (int index, uint64_t blockermask);
NOTE: These functions do not need to be particularly fast, because they will only be used when looking for magic numbers; and once at program startup before the magic numbers are used.
/* Example, Rook on e4: * * Blocker Mask Blocker Board Move Board * ------------ ------------- ---------- * 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 * 0 1 1 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 1 1 0 1 1 1 * 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 * 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 * 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */
The Blocker Mask is all of the squares that can be occupied and block a piece from moving further.
The Blocker Board is one of these permutations.
The Move Board is the resulting available moves for the Piece, for a given Blocker Board.
A Blocker Mask is needed to be generated for all squares, for both the Rook and Bishop.
NOTE: Blocker Masks for the Queen moves do not need to be generated as the Queen moves can make use of the same Rook and Bishop masks.
A Blocker Board is needed to be generate for each square, for both the Rook and Bishop.
NOTE: As the Blocker Boards are being generated, the resulting Move Boards should also be generated.
For each Square/Piece combo try random 64-bit numbers and see if they are magic.
Magic numbers can be confirmed by this formula:
magical_index = ((blockerboard*magic) >> (64-bits));
NOTE: This will create a magical index from 0..2^bits (0..1024 in the case of the e4 rook).
WARNING:
All of the Blocker Masks, Blocker Boards, and Move Boards should be initialized.
NOTE: The index returned by the magic formula is always an integer less than the total number of BlockerBoards (BB).
The program can efficiently look up Move Boards for Bishops and Rooks on any square (and thus also Queens).
The code for that will look something like this:
// Retrieves the Move Board for the given square and occupancy board. uint64_t magic_move_rook(int8_t square, uint64_t occupancy) { // Remove occupants that are not in the Blocker Mask for this square. occupancy &= Rook.blockmask[square]; // Calculate the magic move index. int index = (occupancy*Rook.magic[square]) >> (64-Rook.bits[square]); // Return the pre-calculated move board. return Rook.moveboard[square][index]; }
NOTE: