chess:programming:magic_bitboards:calculate_magic_numbers
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
chess:programming:magic_bitboards:calculate_magic_numbers [2021/10/27 22:27] – peter | chess:programming:magic_bitboards:calculate_magic_numbers [2021/10/28 00:00] (current) – [Determine Magic Numbers] peter | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Chess - Programming - Magic BitBoards - Calculate Magic Numbers ====== | ====== Chess - Programming - Magic BitBoards - Calculate Magic Numbers ====== | ||
- | To start off, the following functions are needed: | + | The following functions are needed: |
<code cpp> | <code cpp> | ||
Line 23: | Line 23: | ||
/* Example, Rook on e4: | /* Example, Rook on e4: | ||
| | ||
- | | + | |
+ | | ||
| | ||
| | ||
Line 39: | Line 40: | ||
* The edge squares do not need to be a part of that, because the piece cannot move further past that square anyway. | * The edge squares do not need to be a part of that, because the piece cannot move further past that square anyway. | ||
- | * The number of 1s in this BitBoard determine how large of a lookup table is needed for this piece & square | + | * The number of 1s in this BitBoard determine how large of a lookup table is needed for this Piece & Square |
* In this case, there are 10 ones, so there are 2^10 (1024) possible permutations of pieces that can block an e4 rook. | * In this case, there are 10 ones, so there are 2^10 (1024) possible permutations of pieces that can block an e4 rook. | ||
Line 46: | Line 47: | ||
* In this example, there are pieces on b4, c4, e2, e5, and e7. | * In this example, there are pieces on b4, c4, e2, e5, and e7. | ||
- | * These are enemy and friendly pieces. | + | * These pieces |
- | * A Blocker Board is always a subset of the blocker mask (it need not show pieces on other squares. | + | * A Blocker Board is always a subset of the blocker mask (it need not show pieces on other squares). |
* blockers = occupancy & blockermask. | * blockers = occupancy & blockermask. | ||
- | The **Move Board** is the resulting available moves for your piece, for a given Blocker Board. | + | The **Move Board** is the resulting available moves for the Piece, for a given Blocker Board. |
- | * This includes possible captures for this piece. | + | * This includes possible captures for this Piece. |
* This also includes capturing own pieces (but these can easily be removed by doing an AND with a NOT of own piece locations). | * This also includes capturing own pieces (but these can easily be removed by doing an AND with a NOT of own piece locations). | ||
</ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ===== Generate a Blocker Mask for all squares ===== | ||
+ | |||
+ | A Blocker Mask is needed to be generated for all squares, for both the Rook and Bishop. | ||
+ | |||
+ | <WRAP info> | ||
+ | **NOTE: | ||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ===== Generate all possible Blocker Boards for all squares ===== | ||
+ | |||
+ | A Blocker Board is needed to be generate for each square, for both the Rook and Bishop. | ||
+ | |||
+ | <WRAP info> | ||
+ | **NOTE: | ||
+ | |||
+ | * Store all of this stuff in arrays for later use. | ||
+ | |||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ===== Determine Magic Numbers ===== | ||
+ | |||
+ | For each Square/ | ||
+ | |||
+ | Magic numbers can be confirmed by this formula: | ||
+ | |||
+ | <code cpp> | ||
+ | magical_index = ((blockerboard*magic) >> (64-bits)); | ||
+ | </ | ||
+ | |||
+ | <WRAP info> | ||
+ | **NOTE: | ||
+ | |||
+ | * **magic** is the random 64-bit number. | ||
+ | * At this time this is done by trial-and-error, | ||
+ | * It is just luck/ | ||
+ | * Ideally no gaps should be between each index, i.e. a perfect hash. | ||
+ | |||
+ | * This should result in 64 magic rook numbers and 64 magic bishop numbers. | ||
+ | * The index returned by the magic formula is always an integer less than the total number of BlockerBoards. | ||
+ | |||
+ | * These indexes will be used to determine where to store each BlockerBoards corresponding MoveBoard within an array. | ||
+ | * The MoveBoard are just stored at the index calculated by these pre-programmed good magics. | ||
+ | |||
+ | * While this example of the Rook at e4 has 1024 BlockerBoards, | ||
+ | * For two different BlockerBoards that have the same MoveBoard, the magic could calculate two different indices or it could calculate the same index for both. | ||
+ | * As long as the MoveBoards are the same, it is okay for the index to collide. | ||
+ | |||
+ | </ | ||
+ | |||
+ | <WRAP important> | ||
+ | **WARNING: | ||
+ | |||
+ | * For a certain Piece/ | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ---- | ||
+ | |||
+ | ===== Using the Magics at Program Startup ===== | ||
+ | |||
+ | All of the Blocker Masks, Blocker Boards, and Move Boards should be initialized. | ||
+ | |||
+ | <WRAP info> | ||
+ | **NOTE: | ||
+ | |||
+ | * Each BB has a corresponding MoveBoard (MB). | ||
+ | * When searching for magics, each MB is being calculated | ||
+ | * At engine startup, the MBs are recalculated with the slow algorithm and then they are just stored at the index calculated by your pre-programmed good magics. | ||
+ | |||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ===== Using the Magics during a game ===== | ||
+ | |||
+ | 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: | ||
+ | |||
+ | <code cpp> | ||
+ | // 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]; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <WRAP info> | ||
+ | **NOTE: | ||
+ | |||
+ | * **index** points to the right spot in the moveboard array. | ||
+ | |||
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
chess/programming/magic_bitboards/calculate_magic_numbers.1635373651.txt.gz · Last modified: 2021/10/27 22:27 by peter