1use crate::bitboard::{BitBoard, EMPTY};
2use crate::color::Color;
3use crate::file::File;
4use crate::rank::Rank;
5use crate::square::Square;
6#[cfg(target_feature = "bmi2")]
7use std::arch::x86_64::{_pdep_u64, _pext_u64};
8
9include!(concat!(env!("OUT_DIR"), "/magic_gen.rs"));
11
12#[inline]
14pub fn get_bishop_rays(sq: Square) -> BitBoard {
15 unsafe { *RAYS.get_unchecked(BISHOP).get_unchecked(sq.to_index()) }
16}
17
18#[inline]
20pub fn get_rook_rays(sq: Square) -> BitBoard {
21 unsafe { *RAYS.get_unchecked(ROOK).get_unchecked(sq.to_index()) }
22}
23
24#[inline]
26pub fn get_rook_moves(sq: Square, blockers: BitBoard) -> BitBoard {
27 unsafe {
28 let magic: Magic = *MAGIC_NUMBERS.get_unchecked(ROOK).get_unchecked(sq.to_int() as usize);
29 *MOVES.get_unchecked((magic.offset as usize) + (magic.magic_number * (blockers & magic.mask)).to_size(magic.rightshift)) & get_rook_rays(sq)
30 }
31}
32
33#[cfg(target_feature = "bmi2")]
35#[inline]
36pub fn get_rook_moves_bmi(sq: Square, blockers: BitBoard) -> BitBoard {
37 unsafe {
38 let bmi2_magic = *ROOK_BMI_MASK.get_unchecked(sq.to_int() as usize);
39 let index = (_pext_u64(blockers.0, bmi2_magic.blockers_mask.0) as usize) + (bmi2_magic.offset as usize);
40 let result = _pdep_u64(*BMI_MOVES.get_unchecked(index as usize) as u64, get_rook_rays(sq).0);
41 return BitBoard(result);
42 }
43}
44
45#[inline]
47pub fn get_bishop_moves(sq: Square, blockers: BitBoard) -> BitBoard {
48 unsafe {
49 let magic: Magic = *MAGIC_NUMBERS.get_unchecked(BISHOP).get_unchecked(sq.to_int() as usize);
50 *MOVES.get_unchecked((magic.offset as usize) + (magic.magic_number * (blockers & magic.mask)).to_size(magic.rightshift)) & get_bishop_rays(sq)
51 }
52}
53
54#[inline]
56#[cfg(target_feature = "bmi2")]
57pub fn get_bishop_moves_bmi(sq: Square, blockers: BitBoard) -> BitBoard {
58 unsafe {
59 let bmi2_magic = *BISHOP_BMI_MASK.get_unchecked(sq.to_int() as usize);
60 let index = (_pext_u64(blockers.0, bmi2_magic.blockers_mask.0) as usize) + (bmi2_magic.offset as usize);
61 let result = _pdep_u64(*BMI_MOVES.get_unchecked(index as usize) as u64, get_bishop_rays(sq).0);
62 return BitBoard(result);
63 }
64}
65
66#[inline]
68pub fn get_king_moves(sq: Square) -> BitBoard {
69 unsafe { *KING_MOVES.get_unchecked(sq.to_index()) }
70}
71
72#[inline]
74pub fn get_knight_moves(sq: Square) -> BitBoard {
75 unsafe { *KNIGHT_MOVES.get_unchecked(sq.to_index()) }
76}
77
78#[inline]
81pub fn get_pawn_attacks(sq: Square, color: Color, blockers: BitBoard) -> BitBoard {
82 unsafe { *PAWN_ATTACKS.get_unchecked(color.to_index()).get_unchecked(sq.to_index()) & blockers }
83}
84#[inline]
86pub fn get_castle_moves() -> BitBoard {
87 CASTLE_MOVES
88}
89
90#[inline]
93pub fn get_pawn_quiets(sq: Square, color: Color, blockers: BitBoard) -> BitBoard {
94 unsafe {
95 if (BitBoard::from_square(sq.uforward(color)) & blockers) != EMPTY {
96 EMPTY
97 } else {
98 *PAWN_MOVES.get_unchecked(color.to_index()).get_unchecked(sq.to_index()) & !blockers
99 }
100 }
101}
102
103#[inline]
106pub fn get_pawn_moves(sq: Square, color: Color, blockers: BitBoard) -> BitBoard {
107 get_pawn_attacks(sq, color, blockers) ^ get_pawn_quiets(sq, color, blockers)
108}
109
110#[inline]
113pub fn line(sq1: Square, sq2: Square) -> BitBoard {
114 unsafe { *LINE.get_unchecked(sq1.to_index()).get_unchecked(sq2.to_index()) }
115}
116
117#[inline]
119pub fn between(sq1: Square, sq2: Square) -> BitBoard {
120 unsafe { *BETWEEN.get_unchecked(sq1.to_index()).get_unchecked(sq2.to_index()) }
121}
122
123#[inline]
125pub fn get_rank(rank: Rank) -> BitBoard {
126 unsafe { *RANKS.get_unchecked(rank.to_index()) }
127}
128
129#[inline]
131pub fn get_file(file: File) -> BitBoard {
132 unsafe { *FILES.get_unchecked(file.to_index()) }
133}
134
135#[inline]
137pub fn get_adjacent_files(file: File) -> BitBoard {
138 unsafe { *ADJACENT_FILES.get_unchecked(file.to_index()) }
139}
140
141#[inline]
142pub fn get_pawn_source_double_moves() -> BitBoard {
143 PAWN_SOURCE_DOUBLE_MOVES
144}
145
146#[inline]
147pub fn get_pawn_dest_double_moves() -> BitBoard {
148 PAWN_DEST_DOUBLE_MOVES
149}