Simply put, small bits are an effective way to take a position and get legal steps for the moving part.
First, you need to find magic numbers. Some of the code you write to search for magic numbers will also be reused when using magic numbers.
To get started, you need to write 5 functions. They do not have to be particularly fast, because you will only use them when searching for magic numbers and once when starting the program before using your magic numbers. You can use any old technique in these functions.
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);
So, you may ask yourself: da f% q is a blocking mask, a movement board and a blocker panel? Well, I just made the conditions, but here is what I mean:
/* Example, Rook on e4: * * The blocker mask A blocker board The 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 */
A blocking mask is all the squares that can be occupied and so that your part moves further. The extreme squares do not have to be part of this, because your piece cannot move beyond this square. The number 1 in this board determines how many large search tables you need for this partial and square combination. In this case there are 10 of them, therefore there are 2 ^ 10 (1024) possible permutations of pieces that can block the rook e4.
The blocker board is one of these permutations. In this example, there are fragments on b4, c4, e2, e5 and e7. These are enemy and friendly things. The blocker board is always a subset of the blocker mask (it does not need to display shapes on other squares (for example, blockers = occupancy & blockermask; )).
The movement board is the available available moves for your unit, for this blocking board. This includes the ability to capture your play. Note that it also includes capturing your own parts (but you can just And this with NOT pieces in their places to remove them).
So, basically you need to create a blocker mask on all squares, both for the rook and for the bishop. And you also need to create all the possible blockers on each square, both for the rook and for the bishop. When you create blocker boards, you must also generate resulting displacement boards. Store all this in arrays for later use.
Now that you have it, for each combination of squares / parts you produce random 64-bit numbers and see if they are magical. You will find out how magical they are using the magic formula, return ((blockerboard*magic) >> (64-bits)); , which will create a magic index of 0..2 ^ bits (0..1024 in the case of the rook e4). For a certain part / square, if two blocker panels ever generate the same magic index , but these two blocker boards have different displacement boards, then this is a Muggle number, and you should try a new one.
Once you get this, you will have 64 magic rook numbers and 64 magic bishops numbers. To use them, when you start the program, you will initialize all blocking masks, blocking boards and move the boards. And now your program can effectively look for boards for bishops and rooks on any square (and therefore also the queen). The code for this 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 aren't 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]; }