stellar

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

attacks.c (2891B)


      1 #include "attacks.h"
      2 #include "internal.h"
      3 #include "magic.h"
      4 
      5 #define UNUSED(x) (void)(x)
      6 
      7 // Magic constants
      8 
      9 U64 attacks_wpawn_get(Square square, U64 occupancy) {
     10     UNUSED(occupancy);
     11     return pawn_attacks[WHITE][square];
     12 }
     13 
     14 U64 attacks_bpawn_get(Square square, U64 occupancy) {
     15     UNUSED(occupancy);
     16     return pawn_attacks[BLACK][square];
     17 }
     18 
     19 U64 attacks_knight_get(Square square, U64 occupancy) {
     20     UNUSED(occupancy);
     21     return knight_attacks[square];
     22 }
     23 
     24 U64 attakcs_king_get(Square square, U64 occupancy) {
     25     UNUSED(occupancy);
     26     return king_attacks[square];
     27 }
     28 
     29 U64 attacks_bishop_get(Square square, U64 occupancy) {
     30     occupancy &= bishop_masks[square];
     31     occupancy = hash(occupancy, bishop_magic_numbers[square],
     32                      bishop_relevant_bits[square]);
     33     return bishop_attacks[square][occupancy];
     34 }
     35 
     36 U64 attacks_rook_get(Square square, U64 occupancy) {
     37     occupancy &= rook_masks[square];
     38     occupancy =
     39         hash(occupancy, rook_magic_numbers[square], rook_relevant_bits[square]);
     40     return rook_attacks[square][occupancy];
     41 }
     42 
     43 U64 attacks_queen_get(Square square, U64 occupancy) {
     44     return (attacks_bishop_get(square, occupancy) |
     45             attacks_rook_get(square, occupancy));
     46 }
     47 
     48 void attacks_init_leapers(void) {
     49     for (Square square = 0; square < 64; square++) {
     50         pawn_attacks[WHITE][square] = pawn_mask(WHITE, square);
     51         pawn_attacks[BLACK][square] = pawn_mask(BLACK, square);
     52         knight_attacks[square] = knight_mask(square);
     53         king_attacks[square] = king_mask(square);
     54     }
     55 }
     56 
     57 void attacks_init_sliders(int bishop) {
     58     for (Square square = 0; square < 64; square++) {
     59         U64 attack_mask;
     60 
     61         if (bishop) {
     62             bishop_masks[square] = bishop_mask(square);
     63             attack_mask = bishop_masks[square];
     64         } else {
     65             rook_masks[square] = rook_mask(square);
     66             attack_mask = rook_masks[square];
     67         }
     68 
     69         int relevant_bits = bit_count(attack_mask);
     70         int occupancy_indicies = 1 << relevant_bits;
     71 
     72         for (int index = 0; index < occupancy_indicies; index++) {
     73             U64 occupancy = set_occupancy(index, relevant_bits, attack_mask);
     74             if (bishop) {
     75                 int magic_index = (occupancy * bishop_magic_numbers[square]) >>
     76                                   (64 - bishop_relevant_bits[square]);
     77                 bishop_attacks[square][magic_index] =
     78                     bishop_on_the_fly(square, occupancy);
     79             } else {
     80                 int magic_index = hash(occupancy, rook_magic_numbers[square],
     81                                        rook_relevant_bits[square]);
     82                 rook_attacks[square][magic_index] =
     83                     rook_on_the_fly(square, occupancy);
     84             }
     85         }
     86     }
     87 }
     88 
     89 void attacks_init(void) {
     90     attacks_init_leapers();
     91     attacks_init_sliders(0);
     92     attacks_init_sliders(1);
     93 }