stellar

Stellar - Chess engine written in C
Log | Files | Refs

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 }