Magic Bitboards: Finding all valid bishop moves in a 64-bit multiply (2008)
chessprogramming.wikispaces.com
chessprogramming.wikispaces.com
U64 bishopAttacks(U64 occ, enumSquare sq) {
occ &= mBishopTbl[sq].mask;
occ *= mBishopTbl[sq].magic;
occ >>= 64-9;
return mBishopAttacks[sq][occ];
}
Two bit-operations and one Multiply are all that is needed to "perfect hash" a bishop's position + all of the possible combinations of pieces which might block it. From there, the "occ" variable serves as a lookup-table's index, providing a pre-calculated bitmask of all of the locations a bishop can attack.It seems like the "occ" bitboard represents the occupancy of the board. (A bitmask of 1 for every piece that could block the bishop's movement). While "enumSquare" seems to be the square the bishop is actually on.
In effect, this is a time-space tradeoff, with every single bishop (or rook) attack being precomputed in a lookup table. Then, during runtime, two-bit operations + one multiply are all that is needed to use the table.
---------------
Some notes to help decipher what is going on:
* Because a chessboard is 64 squares, a 64-bit long integer is all that's needed to represent true/false values across a board. These "true-false" collections across a chessboard are called "bitboards", and can represent anything from board state (Ex: a bitboard that represents all black pawns), to "potential moves a bishop can make" that the AI should iterate against.
* The general problem to solve here is called the Sliding Piece Attack: https://chessprogramming.wikispaces.com/Sliding+Piece+Attack... . Bishops and Rooks are complicated, because they may be blocked by enemy and/or friendly pieces. Other pieces (Knights, Pawns, or Kings) have much simpler movement patterns.
That's what makes this so magnificent: the calculation in runtime is calculated in something like ~15 clock cycles on a modern machine. (2 cycles for the two bitwise operations, 5 cycles for the multiply, and 5 cycles for an L2 lookup)
Yeah, 512-bits / SIMD computations. If chessboards were bigger, then we'd probably just use the SIMD registers. 128-bit SSE is quite common, and 256-bit AVX has been around for ~5 years now.
Even less with PEXT! https://chessprogramming.wikispaces.com/BMI2#PEXTBitboards
Poking around and reading through the wiki blew my mind. I hope they are archived somewhere.
That's rather wasteful, because the centre squares need only around 2^5 occupancies, which is why "fancy" magic bitboards exist. In these, the right-shift is variable, and the occupancy calculation is added to a table of offsets to get the output, shrinking the tables from about 2MB to 800KiB for even the "easy" right-shift amounts.
So the question is whether we can find smaller magic numbers[1]. Niklas Fiekas has found a trick[2] that helps reduce the brute-force search space for magics, but it's still not trivial to solve.
[1]: http://chessprogramming.wikispaces.com/Best%20Magics%20so%20... [2]: http://www.talkchess.com/forum/viewtopic.php?t=65187
I could also make a write-up of Hyperbola Quintessence, which I think is a fantastic bit of bit-twiddling, if someone is interested.
I think once you understand the principle behind kindergarten bitboards, magic bitboards start to make more sense. It's basically a more clever way of indexing into a precomputed move table, that takes advantage of the redundancy in occupancy states, and requires even fewer instructions to determine the index. Although it does still feel kinda magic!
// return whether newboard includes a win
final boolean haswon(long newboard)
{
long y = newboard & (newboard>>HEIGHT);
if ((y & (y >> 2*HEIGHT)) != 0) // check diagonal \
return true;
y = newboard & (newboard>>H1);
if ((y & (y >> 2*H1)) != 0) // check horizontal -
return true;
y = newboard & (newboard>>H2); // check diagonal /
if ((y & (y >> 2*H2)) != 0)
return true;
y = newboard & (newboard>>1); // check vertical |
return (y & (y >> 2)) != 0;
}
Dominikus Herzberg offers a more detailed explanation [2] for the benefit of his students.[1] http://tromp.github.io/c4/Connect4.java
[2] https://github.com/denkspuren/BitboardC4/blob/master/Bitboar...
So, they're going to delete all that useful information presented on a perfect fast loading and fast scrolling website?!?!
Did you mean something else by modern, if so I'm curious what :)
Magic bitboards are awesome. Here's my implementation:
https://github.com/fogleman/MisterQueen/blob/master/src/bb.c...