rook.cpp (3885B)
1 #include "rook.hpp" 2 #include "bit.hpp" 3 #include "bitboard.hpp" 4 #include "slider.hpp" 5 6 #include <array> 7 8 namespace attack { 9 namespace rook { 10 11 inline constexpr const int relevant_bits[64] = { 12 // clang-format off 13 12, 11, 11, 11, 11, 11, 11, 12, 14 11, 10, 10, 10, 10, 10, 10, 11, 15 11, 10, 10, 10, 10, 10, 10, 11, 16 11, 10, 10, 10, 10, 10, 10, 11, 17 11, 10, 10, 10, 10, 10, 10, 11, 18 11, 10, 10, 10, 10, 10, 10, 11, 19 11, 10, 10, 10, 10, 10, 10, 11, 20 12, 11, 11, 11, 11, 11, 11, 12, 21 // clang-format on 22 }; 23 24 inline constexpr const U64 rook_magic_numbers[64] = { 25 C64(0x8a80104000800020), C64(0x140002000100040), C64(0x2801880a0017001), C64(0x100081001000420), 26 C64(0x200020010080420), C64(0x3001c0002010008), C64(0x8480008002000100), C64(0x2080088004402900), 27 C64(0x800098204000), C64(0x2024401000200040), C64(0x100802000801000), C64(0x120800800801000), 28 C64(0x208808088000400), C64(0x2802200800400), C64(0x2200800100020080), C64(0x801000060821100), 29 C64(0x80044006422000), C64(0x100808020004000), C64(0x12108a0010204200), C64(0x140848010000802), 30 C64(0x481828014002800), C64(0x8094004002004100), C64(0x4010040010010802), C64(0x20008806104), 31 C64(0x100400080208000), C64(0x2040002120081000), C64(0x21200680100081), C64(0x20100080080080), 32 C64(0x2000a00200410), C64(0x20080800400), C64(0x80088400100102), C64(0x80004600042881), 33 C64(0x4040008040800020), C64(0x440003000200801), C64(0x4200011004500), C64(0x188020010100100), 34 C64(0x14800401802800), C64(0x2080040080800200), C64(0x124080204001001), C64(0x200046502000484), 35 C64(0x480400080088020), C64(0x1000422010034000), C64(0x30200100110040), C64(0x100021010009), 36 C64(0x2002080100110004), C64(0x202008004008002), C64(0x20020004010100), C64(0x2048440040820001), 37 C64(0x101002200408200), C64(0x40802000401080), C64(0x4008142004410100), C64(0x2060820c0120200), 38 C64(0x1001004080100), C64(0x20c020080040080), C64(0x2935610830022400), C64(0x44440041009200), 39 C64(0x280001040802101), C64(0x2100190040002085), C64(0x80c0084100102001), C64(0x4024081001000421), 40 C64(0x20030a0244872), C64(0x12001008414402), C64(0x2006104900a0804), C64(0x1004081002402), 41 }; 42 43 inline constexpr const bitboard::direction_f dir[4] = {bitboard::westOne, bitboard::soutOne, 44 bitboard::eastOne, bitboard::nortOne}; 45 46 inline constexpr U32 hash(const U64 key, const Square square) { 47 return (key * rook_magic_numbers[square]) >> (64 - relevant_bits[square]); 48 } 49 50 inline constexpr U64 mask_fly(const Square square, U64 block) { 51 int tr = square / 8, tf = square % 8; 52 int len[4] = {tf, tr, 7 - tf, 7 - tr}; 53 54 return attack::slider::mask(square, block, dir, len); 55 } 56 57 std::array<U64, 64> mask = {{0}}; 58 std::array<std::array<U64, 4096>, 64> attacks = {{{0}}}; 59 60 void init(void) { 61 for (Square square = Square::a1; square <= Square::h8; ++square) { 62 const int tr = square / 8, tf = square % 8; 63 const int len[4] = {tf - 1, tr - 1, 6 - tf, 6 - tr}; 64 65 mask[square] = attack::slider::mask(square, C64(0), dir, len); 66 } 67 68 for (Square square = Square::a1; square <= Square::h8; ++square) { 69 U64 attack_mask = mask[square]; 70 uint8_t relevant_bits = bit::count(attack_mask); 71 U64 occupancy_indices = C64(1) << relevant_bits; 72 73 for (U64 idx = 0; idx < occupancy_indices; idx++) { 74 U64 occupancy = attack::slider::occupancy(idx, relevant_bits, attack_mask); 75 U32 magic_index = hash(occupancy, square); 76 attacks[square][magic_index] = mask_fly(square, occupancy); 77 } 78 } 79 } 80 81 U64 attack(const Square square, U64 occupancy) { 82 occupancy &= mask[square]; 83 occupancy = hash(occupancy, square); 84 return attacks[square][occupancy]; 85 } 86 87 } // namespace rook 88 } // namespace attack