internal.c (4035B)
1 #include "internal.h" 2 3 U64 king_attacks[64]; 4 U64 knight_attacks[64]; 5 U64 pawn_attacks[2][64]; 6 U64 rook_attacks[64][4096]; // 2048K 7 U64 bishop_attacks[64][512]; // 256 K 8 9 U64 rook_masks[64]; 10 U64 bishop_masks[64]; 11 12 // clang-format off 13 const int bishop_relevant_bits[64] = { 14 6, 5, 5, 5, 5, 5, 5, 6, 15 5, 5, 5, 5, 5, 5, 5, 5, 16 5, 5, 7, 7, 7, 7, 5, 5, 17 5, 5, 7, 9, 9, 7, 5, 5, 18 5, 5, 7, 9, 9, 7, 5, 5, 19 5, 5, 7, 7, 7, 7, 5, 5, 20 5, 5, 5, 5, 5, 5, 5, 5, 21 6, 5, 5, 5, 5, 5, 5, 6, 22 }; 23 24 const int rook_relevant_bits[64] = { 25 12, 11, 11, 11, 11, 11, 11, 12, 26 11, 10, 10, 10, 10, 10, 10, 11, 27 11, 10, 10, 10, 10, 10, 10, 11, 28 11, 10, 10, 10, 10, 10, 10, 11, 29 11, 10, 10, 10, 10, 10, 10, 11, 30 11, 10, 10, 10, 10, 10, 10, 11, 31 11, 10, 10, 10, 10, 10, 10, 11, 32 12, 11, 11, 11, 11, 11, 11, 12, 33 }; 34 // clang-format on 35 36 int hash(U64 key, U64 magic, int relevant_bits) { 37 return (key * magic) >> (64 - relevant_bits); 38 } 39 40 U64 set_occupancy(int index, int bits_in_mask, U64 attack_mask) { 41 U64 occupancy = C64(0); 42 43 for (int count = 0; count < bits_in_mask; count++) { 44 Square square = bit_lsb_index(attack_mask); 45 bit_pop(attack_mask, square); 46 47 if (index & (1 << count)) bit_set(occupancy, square); 48 } 49 50 return occupancy; 51 } 52 53 U64 attacks_slide_mask(Square square, U64 block, const direction_f dir[4], 54 int len[4]) { 55 U64 bitboard = C64(0), attacks = C64(0), tmp; 56 int i, j; 57 58 bit_set(bitboard, square); 59 for (i = 0; i < 4; i++) { 60 for (j = 0, tmp = bitboard; j < len[i]; j++) { 61 attacks |= tmp = (dir[i])(tmp); 62 if (tmp & block) break; 63 } 64 } 65 return attacks; 66 } 67 68 // Mask Attacks 69 70 const direction_f attacks_bishop_direction[4] = {noEaOne, noWeOne, soEaOne, 71 soWeOne}; 72 const direction_f attacks_rook_direction[4] = {westOne, soutOne, eastOne, 73 nortOne}; 74 75 U64 pawn_mask(int side, Square square) { 76 U64 bitboard = C64(0); 77 78 bit_set(bitboard, square); 79 if (side == WHITE) 80 return noWeOne(bitboard) | noEaOne(bitboard); 81 else 82 return soWeOne(bitboard) | soEaOne(bitboard); 83 } 84 85 U64 knight_mask(Square square) { 86 U64 bitboard = C64(0), attacks = C64(0), tmp; 87 88 bit_set(bitboard, square); 89 tmp = nortOne(nortOne(bitboard)); 90 attacks |= westOne(tmp) | eastOne(tmp); 91 tmp = soutOne(soutOne(bitboard)); 92 attacks |= westOne(tmp) | eastOne(tmp); 93 tmp = westOne(westOne(bitboard)); 94 attacks |= soutOne(tmp) | nortOne(tmp); 95 tmp = eastOne(eastOne(bitboard)); 96 attacks |= soutOne(tmp) | nortOne(tmp); 97 98 return attacks; 99 } 100 101 U64 king_mask(Square square) { 102 U64 bitboard = C64(0), attacks = C64(0); 103 104 bit_set(bitboard, square); 105 attacks |= westOne(bitboard) | eastOne(bitboard); 106 attacks |= soutOne(bitboard) | nortOne(bitboard); 107 attacks |= soutOne(bitboard) | nortOne(bitboard); 108 attacks |= soEaOne(bitboard) | noEaOne(bitboard); 109 attacks |= soWeOne(bitboard) | noWeOne(bitboard); 110 111 return attacks; 112 } 113 114 U64 bishop_mask(Square square) { 115 int tr = square / 8, tf = square % 8; 116 int len[4] = {MIN(7 - tf, 7 - tr) - 1, MIN(tf, 7 - tr) - 1, 117 MIN(7 - tf, tr) - 1, MIN(tf, tr) - 1}; 118 return attacks_slide_mask(square, C64(0), attacks_bishop_direction, len); 119 } 120 121 U64 rook_mask(Square square) { 122 int tr = square / 8, tf = square % 8; 123 int len[4] = {tf - 1, tr - 1, 6 - tf, 6 - tr}; 124 125 return attacks_slide_mask(square, C64(0), attacks_rook_direction, len); 126 } 127 128 U64 bishop_on_the_fly(Square square, U64 block) { 129 int tr = square / 8, tf = square % 8; 130 int len[4] = {MIN(7 - tf, 7 - tr), MIN(tf, 7 - tr), MIN(7 - tf, tr), 131 MIN(tf, tr)}; 132 133 return attacks_slide_mask(square, block, attacks_bishop_direction, len); 134 } 135 136 U64 rook_on_the_fly(Square square, U64 block) { 137 int tr = square / 8, tf = square % 8; 138 int len[4] = {tf, tr, 7 - tf, 7 - tr}; 139 140 return attacks_slide_mask(square, block, attacks_rook_direction, len); 141 }