Rename names for better readability
This commit is contained in:
@@ -213,7 +213,7 @@ pub fn set_occupancy(index: u64, relevant_bits: usize, mut attack_mask: Bitboard
|
|||||||
occupancy
|
occupancy
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pawn_attacks(square: usize, color: Color) -> Bitboard {
|
pub fn fetch_pawn_attacks(square: usize, color: Color) -> Bitboard {
|
||||||
unsafe {
|
unsafe {
|
||||||
match color {
|
match color {
|
||||||
Color::White => PAWN_ATTACKS[square][0],
|
Color::White => PAWN_ATTACKS[square][0],
|
||||||
@@ -222,17 +222,17 @@ pub fn get_pawn_attacks(square: usize, color: Color) -> Bitboard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_knight_attacks(square: usize) -> Bitboard {
|
pub fn fetch_knight_attacks(square: usize) -> Bitboard {
|
||||||
unsafe { KNIGHT_ATTACKS[square] }
|
unsafe { KNIGHT_ATTACKS[square] }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_king_attacks(square: usize) -> Bitboard {
|
pub fn fetch_king_attacks(square: usize) -> Bitboard {
|
||||||
unsafe { KING_ATTACKS[square] }
|
unsafe { KING_ATTACKS[square] }
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::magic::{BISHOP_MAGIC, ROOK_MAGIC};
|
use crate::magic::{BISHOP_MAGIC, ROOK_MAGIC};
|
||||||
|
|
||||||
pub fn get_bishop_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard {
|
pub fn fetch_bishop_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard {
|
||||||
unsafe {
|
unsafe {
|
||||||
occupancy &= mask_bishop_attacks(square_to_bitboard_wrapping(square));
|
occupancy &= mask_bishop_attacks(square_to_bitboard_wrapping(square));
|
||||||
occupancy = occupancy.wrapping_mul(BISHOP_MAGIC[square]);
|
occupancy = occupancy.wrapping_mul(BISHOP_MAGIC[square]);
|
||||||
@@ -241,7 +241,7 @@ pub fn get_bishop_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rook_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard {
|
pub fn fetch_rook_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard {
|
||||||
unsafe {
|
unsafe {
|
||||||
occupancy &= mask_rook_attacks(square_to_bitboard_wrapping(square));
|
occupancy &= mask_rook_attacks(square_to_bitboard_wrapping(square));
|
||||||
occupancy = occupancy.wrapping_mul(ROOK_MAGIC[square]);
|
occupancy = occupancy.wrapping_mul(ROOK_MAGIC[square]);
|
||||||
@@ -250,8 +250,8 @@ pub fn get_rook_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_queen_attacks(occupancy: Bitboard, square: usize) -> Bitboard {
|
pub fn fetch_queen_attacks(occupancy: Bitboard, square: usize) -> Bitboard {
|
||||||
get_rook_attacks(occupancy, square) | get_bishop_attacks(occupancy, square)
|
fetch_rook_attacks(occupancy, square) | fetch_bishop_attacks(occupancy, square)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_pawn_attacks() {
|
pub fn init_pawn_attacks() {
|
||||||
@@ -449,7 +449,7 @@ mod tests {
|
|||||||
init_bishop_attacks();
|
init_bishop_attacks();
|
||||||
let bishop_d3_square = 0x80000_u64.trailing_zeros() as usize;
|
let bishop_d3_square = 0x80000_u64.trailing_zeros() as usize;
|
||||||
let blockers = 0x602000020;
|
let blockers = 0x602000020;
|
||||||
let attacks = get_bishop_attacks(blockers, bishop_d3_square);
|
let attacks = fetch_bishop_attacks(blockers, bishop_d3_square);
|
||||||
assert_eq!(attacks, 0x80402214001422);
|
assert_eq!(attacks, 0x80402214001422);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -460,7 +460,7 @@ mod tests {
|
|||||||
init_rook_attacks();
|
init_rook_attacks();
|
||||||
let rook_d3_square = 0x80000_u64.trailing_zeros() as usize;
|
let rook_d3_square = 0x80000_u64.trailing_zeros() as usize;
|
||||||
let blockers = 0x800000000600800;
|
let blockers = 0x800000000600800;
|
||||||
let attacks = get_rook_attacks(blockers, rook_d3_square);
|
let attacks = fetch_rook_attacks(blockers, rook_d3_square);
|
||||||
assert_eq!(attacks, 0x808080808370800);
|
assert_eq!(attacks, 0x808080808370800);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -473,7 +473,7 @@ mod tests {
|
|||||||
|
|
||||||
let queen_d3_square = 0x80000_u64.trailing_zeros() as usize;
|
let queen_d3_square = 0x80000_u64.trailing_zeros() as usize;
|
||||||
let blockers = 0x800000602600820;
|
let blockers = 0x800000602600820;
|
||||||
let queen_attacks = get_queen_attacks(blockers, queen_d3_square);
|
let queen_attacks = fetch_queen_attacks(blockers, queen_d3_square);
|
||||||
assert_eq!(queen_attacks, 0x888482a1c371c22);
|
assert_eq!(queen_attacks, 0x888482a1c371c22);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
125
src/board.rs
125
src/board.rs
@@ -1,8 +1,8 @@
|
|||||||
use u64 as Bitboard;
|
use u64 as Bitboard;
|
||||||
|
|
||||||
use crate::attack::{
|
use crate::attack::{
|
||||||
get_bishop_attacks, get_king_attacks, get_knight_attacks, get_pawn_attacks, get_queen_attacks,
|
fetch_bishop_attacks, fetch_king_attacks, fetch_knight_attacks, fetch_pawn_attacks,
|
||||||
get_rook_attacks,
|
fetch_queen_attacks, fetch_rook_attacks,
|
||||||
};
|
};
|
||||||
use crate::bitboard::{have_common_bit, lsb, square_to_bitboard};
|
use crate::bitboard::{have_common_bit, lsb, square_to_bitboard};
|
||||||
use crate::movegen::{
|
use crate::movegen::{
|
||||||
@@ -76,42 +76,44 @@ impl Board {
|
|||||||
self.state = state;
|
self.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_white_occupancies(&self) -> Bitboard {
|
pub fn white_occupancies(&self) -> Bitboard {
|
||||||
self.white_pieces.iter().fold(0, |acc, p| p.bitboard | acc)
|
self.white_pieces.iter().fold(0, |acc, p| p.bitboard | acc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_black_occupancies(&self) -> Bitboard {
|
pub fn black_occupancies(&self) -> Bitboard {
|
||||||
self.black_pieces.iter().fold(0, |acc, p| p.bitboard | acc)
|
self.black_pieces.iter().fold(0, |acc, p| p.bitboard | acc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_occupancies(&self) -> Bitboard {
|
pub fn all_occupancies(&self) -> Bitboard {
|
||||||
self.get_white_occupancies() | self.get_black_occupancies()
|
self.white_occupancies() | self.black_occupancies()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_attacked(&self, sq: usize, opponent_color: Color) -> bool {
|
pub fn is_attacked(&self, square: usize, opponent_color: Color) -> bool {
|
||||||
let all_occupancies = self.get_all_occupancies();
|
let all_occupancies = self.all_occupancies();
|
||||||
let (enemy, own_color) = match opponent_color {
|
let (opponent, own_color) = match opponent_color {
|
||||||
Color::Black => (&self.black_pieces, Color::White),
|
Color::Black => (&self.black_pieces, Color::White),
|
||||||
Color::White => (&self.white_pieces, Color::Black),
|
Color::White => (&self.white_pieces, Color::Black),
|
||||||
};
|
};
|
||||||
|
|
||||||
have_common_bit(
|
have_common_bit(
|
||||||
enemy[Kind::Pawn.idx()].bitboard,
|
opponent[Kind::Pawn.idx()].bitboard,
|
||||||
get_pawn_attacks(sq, own_color),
|
fetch_pawn_attacks(square, own_color),
|
||||||
) || have_common_bit(enemy[Kind::Knight.idx()].bitboard, get_knight_attacks(sq))
|
) || have_common_bit(
|
||||||
|| have_common_bit(
|
opponent[Kind::Knight.idx()].bitboard,
|
||||||
enemy[Kind::Bishop.idx()].bitboard,
|
fetch_knight_attacks(square),
|
||||||
get_bishop_attacks(all_occupancies, sq),
|
) || have_common_bit(
|
||||||
)
|
opponent[Kind::Bishop.idx()].bitboard,
|
||||||
|| have_common_bit(
|
fetch_bishop_attacks(all_occupancies, square),
|
||||||
enemy[Kind::Rook.idx()].bitboard,
|
) || have_common_bit(
|
||||||
get_rook_attacks(all_occupancies, sq),
|
opponent[Kind::Rook.idx()].bitboard,
|
||||||
)
|
fetch_rook_attacks(all_occupancies, square),
|
||||||
|| have_common_bit(
|
) || have_common_bit(
|
||||||
enemy[Kind::Queen.idx()].bitboard,
|
opponent[Kind::Queen.idx()].bitboard,
|
||||||
get_queen_attacks(all_occupancies, sq),
|
fetch_queen_attacks(all_occupancies, square),
|
||||||
)
|
) || have_common_bit(
|
||||||
|| have_common_bit(enemy[Kind::King.idx()].bitboard, get_king_attacks(sq))
|
opponent[Kind::King.idx()].bitboard,
|
||||||
|
fetch_king_attacks(square),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_move_legit(&self, square: usize, opponent_color: Color) -> bool {
|
pub fn is_move_legit(&self, square: usize, opponent_color: Color) -> bool {
|
||||||
@@ -129,17 +131,17 @@ impl Board {
|
|||||||
moves
|
moves
|
||||||
}
|
}
|
||||||
pub fn pseudo_moves(&self, color: Color, kind: Kind) -> Vec<Move> {
|
pub fn pseudo_moves(&self, color: Color, kind: Kind) -> Vec<Move> {
|
||||||
let all_occupancies = self.get_all_occupancies();
|
let all_occupancies = self.all_occupancies();
|
||||||
let (pieces, enemy_occupancies, own_occupancies) = match color {
|
let (pieces, opponent_occupancies, own_occupancies) = match color {
|
||||||
Color::White => (
|
Color::White => (
|
||||||
self.white_pieces[kind.idx()].bitboard,
|
self.white_pieces[kind.idx()].bitboard,
|
||||||
self.get_black_occupancies(),
|
self.black_occupancies(),
|
||||||
self.get_white_occupancies(),
|
self.white_occupancies(),
|
||||||
),
|
),
|
||||||
Color::Black => (
|
Color::Black => (
|
||||||
self.black_pieces[kind.idx()].bitboard,
|
self.black_pieces[kind.idx()].bitboard,
|
||||||
self.get_white_occupancies(),
|
self.white_occupancies(),
|
||||||
self.get_black_occupancies(),
|
self.black_occupancies(),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -147,8 +149,8 @@ impl Board {
|
|||||||
Kind::Pawn => pawn_pseudo_moves(
|
Kind::Pawn => pawn_pseudo_moves(
|
||||||
pieces,
|
pieces,
|
||||||
all_occupancies,
|
all_occupancies,
|
||||||
enemy_occupancies,
|
opponent_occupancies,
|
||||||
self.state.get_en_passant_target_square(),
|
self.state.en_passant_target_square(),
|
||||||
color,
|
color,
|
||||||
),
|
),
|
||||||
Kind::Knight => knight_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
Kind::Knight => knight_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
||||||
@@ -175,9 +177,9 @@ impl Board {
|
|||||||
Color::Black => &self.black_pieces,
|
Color::Black => &self.black_pieces,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.state.update_castling_state_quiet(mv.source, color);
|
self.state.update_castling_state_quiet(mv.src, color);
|
||||||
self.state
|
self.state
|
||||||
.update_castling_state_capture(mv.target, Color::opponent_color(color));
|
.update_castling_state_capture(mv.dst, Color::opponent_color(color));
|
||||||
self.state.change_side();
|
self.state.change_side();
|
||||||
|
|
||||||
let own_king_square = lsb(pieces[Kind::King.idx()].bitboard);
|
let own_king_square = lsb(pieces[Kind::King.idx()].bitboard);
|
||||||
@@ -192,52 +194,52 @@ impl Board {
|
|||||||
|
|
||||||
match &mv.move_type {
|
match &mv.move_type {
|
||||||
MoveType::Quiet => {
|
MoveType::Quiet => {
|
||||||
Self::move_piece(mv.source, mv.target, own_pieces);
|
Self::move_piece(mv.src, mv.dst, own_pieces);
|
||||||
self.state.set_en_passant_target_square(None);
|
self.state.set_en_passant_target_square(None);
|
||||||
}
|
}
|
||||||
MoveType::Capture => {
|
MoveType::Capture => {
|
||||||
Self::move_piece(mv.source, mv.target, own_pieces);
|
Self::move_piece(mv.src, mv.dst, own_pieces);
|
||||||
Self::remove_piece(mv.target, opponent_pieces);
|
Self::remove_piece(mv.dst, opponent_pieces);
|
||||||
self.state.set_en_passant_target_square(None);
|
self.state.set_en_passant_target_square(None);
|
||||||
}
|
}
|
||||||
MoveType::EnPassant => {
|
MoveType::EnPassant => {
|
||||||
Self::move_piece(mv.source, mv.target, own_pieces);
|
Self::move_piece(mv.src, mv.dst, own_pieces);
|
||||||
Self::remove_pawn_enpassant(mv.target, opponent_pieces, color);
|
Self::remove_pawn_enpassant(mv.dst, opponent_pieces, color);
|
||||||
self.state.set_en_passant_target_square(None);
|
self.state.set_en_passant_target_square(None);
|
||||||
}
|
}
|
||||||
MoveType::DoublePush => {
|
MoveType::DoublePush => {
|
||||||
Self::move_piece(mv.source, mv.target, own_pieces);
|
Self::move_piece(mv.src, mv.dst, own_pieces);
|
||||||
let en_passant = match color {
|
let en_passant = match color {
|
||||||
Color::White => Some(mv.source + 8),
|
Color::White => Some(mv.src + 8),
|
||||||
Color::Black => Some(mv.source - 8),
|
Color::Black => Some(mv.src - 8),
|
||||||
};
|
};
|
||||||
self.state.set_en_passant_target_square(en_passant);
|
self.state.set_en_passant_target_square(en_passant);
|
||||||
}
|
}
|
||||||
MoveType::Promotion(promote) => {
|
MoveType::Promotion(promote) => {
|
||||||
Self::remove_piece(mv.source, own_pieces);
|
Self::remove_piece(mv.src, own_pieces);
|
||||||
Self::promote_piece(mv.target, own_pieces, *promote);
|
Self::promote_piece(mv.dst, own_pieces, *promote);
|
||||||
self.state.set_en_passant_target_square(None);
|
self.state.set_en_passant_target_square(None);
|
||||||
}
|
}
|
||||||
MoveType::PromotionCapture(promote) => {
|
MoveType::PromotionCapture(promote) => {
|
||||||
Self::remove_piece(mv.source, own_pieces);
|
Self::remove_piece(mv.src, own_pieces);
|
||||||
Self::remove_piece(mv.target, opponent_pieces);
|
Self::remove_piece(mv.dst, opponent_pieces);
|
||||||
Self::promote_piece(mv.target, own_pieces, *promote);
|
Self::promote_piece(mv.dst, own_pieces, *promote);
|
||||||
self.state.set_en_passant_target_square(None);
|
self.state.set_en_passant_target_square(None);
|
||||||
}
|
}
|
||||||
MoveType::Castle => {
|
MoveType::Castle => {
|
||||||
Self::move_piece(mv.source, mv.target, own_pieces);
|
Self::move_piece(mv.src, mv.dst, own_pieces);
|
||||||
Self::move_rook_castle(mv.target, own_pieces);
|
Self::move_rook_castle(mv.dst, own_pieces);
|
||||||
self.state.set_en_passant_target_square(None);
|
self.state.set_en_passant_target_square(None);
|
||||||
self.state.set_castling_ability(color, Castle::None)
|
self.state.set_castling_ability(color, Castle::None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_piece(source: usize, target: usize, pieces: &mut [Piece; 6]) {
|
fn move_piece(src: usize, dst: usize, pieces: &mut [Piece; 6]) {
|
||||||
for p in pieces.iter_mut() {
|
for p in pieces.iter_mut() {
|
||||||
if have_common_bit(p.bitboard, square_to_bitboard(source)) {
|
if have_common_bit(p.bitboard, square_to_bitboard(src)) {
|
||||||
p.bitboard &= !square_to_bitboard(source);
|
p.bitboard &= !square_to_bitboard(src);
|
||||||
p.bitboard |= square_to_bitboard(target);
|
p.bitboard |= square_to_bitboard(dst);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,12 +279,7 @@ impl Board {
|
|||||||
Color::Black => square + 8,
|
Color::Black => square + 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
for p in pieces.iter_mut() {
|
Self::remove_piece(piece_to_remove, pieces);
|
||||||
if have_common_bit(p.bitboard, square_to_bitboard(piece_to_remove)) {
|
|
||||||
p.bitboard &= !(square_to_bitboard(piece_to_remove));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,11 +346,11 @@ mod tests {
|
|||||||
const FEN_EXAMPLE: [&str; 1] = ["8/6P1/4n2b/1p6/1Kp5/6n1/4b3/1k6 w - - 0 1"];
|
const FEN_EXAMPLE: [&str; 1] = ["8/6P1/4n2b/1p6/1Kp5/6n1/4b3/1k6 w - - 0 1"];
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_occupancies() -> Result<(), String> {
|
fn test_occupancies() -> Result<(), String> {
|
||||||
let new_game = from_fen(FEN_EXAMPLE[0])?;
|
let new_game = from_fen(FEN_EXAMPLE[0])?;
|
||||||
assert_eq!(new_game.board.get_white_occupancies(), 0x40000002000000);
|
assert_eq!(new_game.board.white_occupancies(), 0x40000002000000);
|
||||||
assert_eq!(new_game.board.get_black_occupancies(), 0x900204401002);
|
assert_eq!(new_game.board.black_occupancies(), 0x900204401002);
|
||||||
assert_eq!(new_game.board.get_all_occupancies(), 0x40900206401002);
|
assert_eq!(new_game.board.all_occupancies(), 0x40900206401002);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
src/move.rs
16
src/move.rs
@@ -19,24 +19,24 @@ pub enum MoveType {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||||
pub struct Move {
|
pub struct Move {
|
||||||
pub source: usize,
|
pub src: usize,
|
||||||
pub target: usize,
|
pub dst: usize,
|
||||||
pub move_type: MoveType,
|
pub move_type: MoveType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Move {
|
impl Move {
|
||||||
pub const fn new(source: usize, target: usize) -> Self {
|
pub const fn new(src: usize, dst: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
source,
|
src,
|
||||||
target,
|
dst,
|
||||||
move_type: MoveType::Quiet,
|
move_type: MoveType::Quiet,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn new_with_type(source: usize, target: usize, move_type: MoveType) -> Self {
|
pub const fn new_with_type(src: usize, dst: usize, move_type: MoveType) -> Self {
|
||||||
Self {
|
Self {
|
||||||
source,
|
src,
|
||||||
target,
|
dst,
|
||||||
move_type,
|
move_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::attack::{
|
use crate::attack::{
|
||||||
get_bishop_attacks, get_king_attacks, get_knight_attacks, get_pawn_attacks, get_queen_attacks,
|
fetch_bishop_attacks, fetch_king_attacks, fetch_knight_attacks, fetch_pawn_attacks,
|
||||||
get_rook_attacks,
|
fetch_queen_attacks, fetch_rook_attacks,
|
||||||
};
|
};
|
||||||
use crate::bitboard::{
|
use crate::bitboard::{
|
||||||
have_common_bit, lsb, square_to_bitboard, NOT_FILE_A, NOT_FILE_H, RANK_1, RANK_2, RANK_4,
|
have_common_bit, lsb, square_to_bitboard, NOT_FILE_A, NOT_FILE_H, RANK_1, RANK_2, RANK_4,
|
||||||
@@ -14,7 +14,7 @@ use u64 as Bitboard;
|
|||||||
pub fn pawn_pseudo_moves(
|
pub fn pawn_pseudo_moves(
|
||||||
pawns: Bitboard,
|
pawns: Bitboard,
|
||||||
all_occupancies: Bitboard,
|
all_occupancies: Bitboard,
|
||||||
enemy_occupancies: Bitboard,
|
opponent_occupancies: Bitboard,
|
||||||
en_passant_square: Option<usize>,
|
en_passant_square: Option<usize>,
|
||||||
color: Color,
|
color: Color,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
@@ -24,7 +24,7 @@ pub fn pawn_pseudo_moves(
|
|||||||
moves.extend(white_pawn_quiet_moves(pawns, all_occupancies));
|
moves.extend(white_pawn_quiet_moves(pawns, all_occupancies));
|
||||||
moves.extend(white_pawn_capture_moves(
|
moves.extend(white_pawn_capture_moves(
|
||||||
pawns,
|
pawns,
|
||||||
enemy_occupancies,
|
opponent_occupancies,
|
||||||
en_passant_square,
|
en_passant_square,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ pub fn pawn_pseudo_moves(
|
|||||||
moves.extend(black_pawn_quiet_moves(pawns, all_occupancies));
|
moves.extend(black_pawn_quiet_moves(pawns, all_occupancies));
|
||||||
moves.extend(black_pawn_capture_moves(
|
moves.extend(black_pawn_capture_moves(
|
||||||
pawns,
|
pawns,
|
||||||
enemy_occupancies,
|
opponent_occupancies,
|
||||||
en_passant_square,
|
en_passant_square,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -44,9 +44,9 @@ fn white_pawn_quiet_moves(pawns: Bitboard, occupancies: Bitboard) -> Vec<Move> {
|
|||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
let empty = !occupancies;
|
let empty = !occupancies;
|
||||||
|
|
||||||
let mut single_push_targets = (pawns << 8) & empty;
|
let mut single_push = (pawns << 8) & empty;
|
||||||
while single_push_targets != 0 {
|
while single_push != 0 {
|
||||||
let to = lsb(single_push_targets);
|
let to = lsb(single_push);
|
||||||
let from = to - 8;
|
let from = to - 8;
|
||||||
|
|
||||||
if have_common_bit(square_to_bitboard(from), RANK_7) {
|
if have_common_bit(square_to_bitboard(from), RANK_7) {
|
||||||
@@ -59,16 +59,16 @@ fn white_pawn_quiet_moves(pawns: Bitboard, occupancies: Bitboard) -> Vec<Move> {
|
|||||||
} else {
|
} else {
|
||||||
moves.push(Move::new(from, to));
|
moves.push(Move::new(from, to));
|
||||||
}
|
}
|
||||||
single_push_targets &= single_push_targets - 1;
|
single_push &= single_push - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let single_push_targets = (pawns << 8) & empty;
|
let single_push = (pawns << 8) & empty;
|
||||||
let mut double_push_targets = (single_push_targets << 8) & empty & RANK_4;
|
let mut double_push = (single_push << 8) & empty & RANK_4;
|
||||||
while double_push_targets != 0 {
|
while double_push != 0 {
|
||||||
let to = lsb(double_push_targets);
|
let to = lsb(double_push);
|
||||||
let from = to - 16;
|
let from = to - 16;
|
||||||
moves.push(Move::new_with_type(from, to, MoveType::DoublePush));
|
moves.push(Move::new_with_type(from, to, MoveType::DoublePush));
|
||||||
double_push_targets &= double_push_targets - 1;
|
double_push &= double_push - 1;
|
||||||
}
|
}
|
||||||
moves
|
moves
|
||||||
}
|
}
|
||||||
@@ -77,9 +77,9 @@ fn black_pawn_quiet_moves(pawns: Bitboard, occupancies: Bitboard) -> Vec<Move> {
|
|||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
let empty = !occupancies;
|
let empty = !occupancies;
|
||||||
|
|
||||||
let mut single_push_targets = (pawns >> 8) & empty;
|
let mut single_push = (pawns >> 8) & empty;
|
||||||
while single_push_targets != 0 {
|
while single_push != 0 {
|
||||||
let to = lsb(single_push_targets);
|
let to = lsb(single_push);
|
||||||
let from = to + 8;
|
let from = to + 8;
|
||||||
|
|
||||||
if have_common_bit(square_to_bitboard(from), RANK_2) {
|
if have_common_bit(square_to_bitboard(from), RANK_2) {
|
||||||
@@ -92,28 +92,28 @@ fn black_pawn_quiet_moves(pawns: Bitboard, occupancies: Bitboard) -> Vec<Move> {
|
|||||||
} else {
|
} else {
|
||||||
moves.push(Move::new(from, to));
|
moves.push(Move::new(from, to));
|
||||||
}
|
}
|
||||||
single_push_targets &= single_push_targets - 1;
|
single_push &= single_push - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let single_push_targets = (pawns >> 8) & empty;
|
let single_push = (pawns >> 8) & empty;
|
||||||
let mut double_push_targets = (single_push_targets >> 8) & empty & RANK_5;
|
let mut double_push = (single_push >> 8) & empty & RANK_5;
|
||||||
while double_push_targets != 0 {
|
while double_push != 0 {
|
||||||
let to = lsb(double_push_targets);
|
let to = lsb(double_push);
|
||||||
let from = to + 16;
|
let from = to + 16;
|
||||||
moves.push(Move::new_with_type(from, to, MoveType::DoublePush));
|
moves.push(Move::new_with_type(from, to, MoveType::DoublePush));
|
||||||
double_push_targets &= double_push_targets - 1;
|
double_push &= double_push - 1;
|
||||||
}
|
}
|
||||||
moves
|
moves
|
||||||
}
|
}
|
||||||
|
|
||||||
fn white_pawn_capture_moves(
|
fn white_pawn_capture_moves(
|
||||||
pawns: Bitboard,
|
pawns: Bitboard,
|
||||||
enemy_occupancies: Bitboard,
|
opponent_occupancies: Bitboard,
|
||||||
en_passant_square: Option<usize>,
|
en_passant_square: Option<usize>,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
let mut w_pawns_capture_east = pawns & ((enemy_occupancies >> 9) & NOT_FILE_H);
|
let mut w_pawns_capture_east = pawns & ((opponent_occupancies >> 9) & NOT_FILE_H);
|
||||||
let mut w_pawns_capture_west = pawns & ((enemy_occupancies >> 7) & NOT_FILE_A);
|
let mut w_pawns_capture_west = pawns & ((opponent_occupancies >> 7) & NOT_FILE_A);
|
||||||
|
|
||||||
while w_pawns_capture_east != 0 {
|
while w_pawns_capture_east != 0 {
|
||||||
let from = lsb(w_pawns_capture_east);
|
let from = lsb(w_pawns_capture_east);
|
||||||
@@ -148,13 +148,13 @@ fn white_pawn_capture_moves(
|
|||||||
w_pawns_capture_west &= w_pawns_capture_west - 1;
|
w_pawns_capture_west &= w_pawns_capture_west - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(en_passant_square) = en_passant_square {
|
if let Some(en_passant_sq) = en_passant_square {
|
||||||
let attacked_from = get_pawn_attacks(en_passant_square, Color::Black);
|
let attacked_from = fetch_pawn_attacks(en_passant_sq, Color::Black);
|
||||||
let mut result = attacked_from & pawns;
|
let mut result = attacked_from & pawns;
|
||||||
while result != 0 {
|
while result != 0 {
|
||||||
moves.push(Move::new_with_type(
|
moves.push(Move::new_with_type(
|
||||||
lsb(result),
|
lsb(result),
|
||||||
en_passant_square,
|
en_passant_sq,
|
||||||
MoveType::EnPassant,
|
MoveType::EnPassant,
|
||||||
));
|
));
|
||||||
result &= result - 1;
|
result &= result - 1;
|
||||||
@@ -165,12 +165,12 @@ fn white_pawn_capture_moves(
|
|||||||
|
|
||||||
fn black_pawn_capture_moves(
|
fn black_pawn_capture_moves(
|
||||||
pawns: Bitboard,
|
pawns: Bitboard,
|
||||||
enemy_occupancies: Bitboard,
|
opponent_occupancies: Bitboard,
|
||||||
en_passant_square: Option<usize>,
|
en_passant_square: Option<usize>,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
let mut b_pawns_capture_east = pawns & ((enemy_occupancies << 7) & NOT_FILE_H);
|
let mut b_pawns_capture_east = pawns & ((opponent_occupancies << 7) & NOT_FILE_H);
|
||||||
let mut b_pawns_capture_west = pawns & ((enemy_occupancies << 9) & NOT_FILE_A);
|
let mut b_pawns_capture_west = pawns & ((opponent_occupancies << 9) & NOT_FILE_A);
|
||||||
|
|
||||||
while b_pawns_capture_east != 0 {
|
while b_pawns_capture_east != 0 {
|
||||||
let from = lsb(b_pawns_capture_east);
|
let from = lsb(b_pawns_capture_east);
|
||||||
@@ -206,7 +206,7 @@ fn black_pawn_capture_moves(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(en_passant_square) = en_passant_square {
|
if let Some(en_passant_square) = en_passant_square {
|
||||||
let attacked_from = get_pawn_attacks(en_passant_square, Color::White);
|
let attacked_from = fetch_pawn_attacks(en_passant_square, Color::White);
|
||||||
let mut result = attacked_from & pawns;
|
let mut result = attacked_from & pawns;
|
||||||
while result != 0 {
|
while result != 0 {
|
||||||
moves.push(Move::new_with_type(
|
moves.push(Move::new_with_type(
|
||||||
@@ -226,16 +226,16 @@ pub fn knight_pseudo_moves(
|
|||||||
own_occupancies: Bitboard,
|
own_occupancies: Bitboard,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
let enemy_occupancies = all_occupancies ^ own_occupancies;
|
let opponent_occupancies = all_occupancies ^ own_occupancies;
|
||||||
|
|
||||||
while knights != 0 {
|
while knights != 0 {
|
||||||
let knight_square = lsb(knights);
|
let knight_square = lsb(knights);
|
||||||
let from = knight_square;
|
let from = knight_square;
|
||||||
let mut attacks = get_knight_attacks(knight_square) & !own_occupancies;
|
let mut attacks = fetch_knight_attacks(knight_square) & !own_occupancies;
|
||||||
|
|
||||||
while attacks != 0 {
|
while attacks != 0 {
|
||||||
let attack_sq = lsb(attacks);
|
let attack_sq = lsb(attacks);
|
||||||
if have_common_bit(square_to_bitboard(attack_sq), enemy_occupancies) {
|
if have_common_bit(square_to_bitboard(attack_sq), opponent_occupancies) {
|
||||||
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
||||||
} else {
|
} else {
|
||||||
moves.push(Move::new(from, attack_sq));
|
moves.push(Move::new(from, attack_sq));
|
||||||
@@ -253,16 +253,16 @@ pub fn bishop_pseudo_moves(
|
|||||||
own_occupancies: Bitboard,
|
own_occupancies: Bitboard,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
let enemy_occupancies = all_occupancies ^ own_occupancies;
|
let opponent_occupancies = all_occupancies ^ own_occupancies;
|
||||||
|
|
||||||
while bishops != 0 {
|
while bishops != 0 {
|
||||||
let bishop_square = lsb(bishops);
|
let bishop_square = lsb(bishops);
|
||||||
let from = bishop_square;
|
let from = bishop_square;
|
||||||
let mut attacks = get_bishop_attacks(all_occupancies, bishop_square) & !own_occupancies;
|
let mut attacks = fetch_bishop_attacks(all_occupancies, bishop_square) & !own_occupancies;
|
||||||
|
|
||||||
while attacks != 0 {
|
while attacks != 0 {
|
||||||
let attack_sq = lsb(attacks);
|
let attack_sq = lsb(attacks);
|
||||||
if have_common_bit(square_to_bitboard(attack_sq), enemy_occupancies) {
|
if have_common_bit(square_to_bitboard(attack_sq), opponent_occupancies) {
|
||||||
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
||||||
} else {
|
} else {
|
||||||
moves.push(Move::new(from, attack_sq));
|
moves.push(Move::new(from, attack_sq));
|
||||||
@@ -280,16 +280,16 @@ pub fn rook_pseudo_moves(
|
|||||||
own_occupancies: Bitboard,
|
own_occupancies: Bitboard,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
let enemy_occupancies = all_occupancies ^ own_occupancies;
|
let opponent_occupancies = all_occupancies ^ own_occupancies;
|
||||||
|
|
||||||
while rooks != 0 {
|
while rooks != 0 {
|
||||||
let rook_square = lsb(rooks);
|
let rook_square = lsb(rooks);
|
||||||
let from = rook_square;
|
let from = rook_square;
|
||||||
let mut attacks = get_rook_attacks(all_occupancies, rook_square) & !own_occupancies;
|
let mut attacks = fetch_rook_attacks(all_occupancies, rook_square) & !own_occupancies;
|
||||||
|
|
||||||
while attacks != 0 {
|
while attacks != 0 {
|
||||||
let attack_sq = lsb(attacks);
|
let attack_sq = lsb(attacks);
|
||||||
if have_common_bit(square_to_bitboard(attack_sq), enemy_occupancies) {
|
if have_common_bit(square_to_bitboard(attack_sq), opponent_occupancies) {
|
||||||
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
||||||
} else {
|
} else {
|
||||||
moves.push(Move::new(from, attack_sq));
|
moves.push(Move::new(from, attack_sq));
|
||||||
@@ -307,16 +307,16 @@ pub fn queen_pseudo_moves(
|
|||||||
own_occupancies: Bitboard,
|
own_occupancies: Bitboard,
|
||||||
) -> Vec<Move> {
|
) -> Vec<Move> {
|
||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
let enemy_occupancies = all_occupancies ^ own_occupancies;
|
let opponent_occupancies = all_occupancies ^ own_occupancies;
|
||||||
|
|
||||||
while queens != 0 {
|
while queens != 0 {
|
||||||
let queen_square = lsb(queens);
|
let queen_square = lsb(queens);
|
||||||
let from = queen_square;
|
let from = queen_square;
|
||||||
let mut attacks = get_queen_attacks(all_occupancies, queen_square) & !own_occupancies;
|
let mut attacks = fetch_queen_attacks(all_occupancies, queen_square) & !own_occupancies;
|
||||||
|
|
||||||
while attacks != 0 {
|
while attacks != 0 {
|
||||||
let attack_sq = lsb(attacks);
|
let attack_sq = lsb(attacks);
|
||||||
if have_common_bit(square_to_bitboard(attack_sq), enemy_occupancies) {
|
if have_common_bit(square_to_bitboard(attack_sq), opponent_occupancies) {
|
||||||
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
||||||
} else {
|
} else {
|
||||||
moves.push(Move::new(from, attack_sq));
|
moves.push(Move::new(from, attack_sq));
|
||||||
@@ -338,12 +338,12 @@ pub fn king_pseudo_moves(
|
|||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
let king_square = lsb(king);
|
let king_square = lsb(king);
|
||||||
let from = king_square;
|
let from = king_square;
|
||||||
let mut attacks = get_king_attacks(king_square) & !own_occupancies;
|
let mut attacks = fetch_king_attacks(king_square) & !own_occupancies;
|
||||||
let enemy_occupancies = all_occupancies ^ own_occupancies;
|
let opponent_occupancies = all_occupancies ^ own_occupancies;
|
||||||
|
|
||||||
while attacks != 0 {
|
while attacks != 0 {
|
||||||
let attack_sq = lsb(attacks);
|
let attack_sq = lsb(attacks);
|
||||||
if have_common_bit(square_to_bitboard(attack_sq), enemy_occupancies) {
|
if have_common_bit(square_to_bitboard(attack_sq), opponent_occupancies) {
|
||||||
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
moves.push(Move::new_with_type(from, attack_sq, MoveType::Capture));
|
||||||
} else {
|
} else {
|
||||||
moves.push(Move::new(from, attack_sq));
|
moves.push(Move::new(from, attack_sq));
|
||||||
@@ -369,7 +369,7 @@ fn king_castling_moves(board: &Board, color: Color, all_occupancies: Bitboard) -
|
|||||||
};
|
};
|
||||||
|
|
||||||
match (
|
match (
|
||||||
board.state.get_castling_ability(color),
|
board.state.castling_ability(color),
|
||||||
king_and_adj_square_safety(board, color),
|
king_and_adj_square_safety(board, color),
|
||||||
) {
|
) {
|
||||||
(Castle::Both, Castle::Both) => {
|
(Castle::Both, Castle::Both) => {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ pub const fn coords_to_square(rank: usize, file: usize) -> usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Square {
|
impl Square {
|
||||||
pub const fn to_bitboard(sq: usize) -> Bitboard {
|
pub const fn to_bitboard(square: usize) -> Bitboard {
|
||||||
1_u64 << sq
|
1_u64 << square
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/state.rs
18
src/state.rs
@@ -36,7 +36,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn get_en_passant_target_square(&self) -> Option<usize> {
|
pub const fn en_passant_target_square(&self) -> Option<usize> {
|
||||||
self.en_passant_target_square
|
self.en_passant_target_square
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,10 +47,10 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_castling_state_quiet(&mut self, source: usize, color: Color) {
|
pub fn update_castling_state_quiet(&mut self, src: usize, color: Color) {
|
||||||
self.update_castling_state_capture(source, color);
|
self.update_castling_state_capture(src, color);
|
||||||
|
|
||||||
match (source, color) {
|
match (src, color) {
|
||||||
(4, Color::White) => self.set_castling_ability(color, Castle::None),
|
(4, Color::White) => self.set_castling_ability(color, Castle::None),
|
||||||
(60, Color::Black) => self.set_castling_ability(color, Castle::None),
|
(60, Color::Black) => self.set_castling_ability(color, Castle::None),
|
||||||
_ => (),
|
_ => (),
|
||||||
@@ -64,7 +64,7 @@ impl State {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if target == short_square {
|
if target == short_square {
|
||||||
match self.get_castling_ability(color) {
|
match self.castling_ability(color) {
|
||||||
Castle::Both => self.set_castling_ability(color, Castle::Long),
|
Castle::Both => self.set_castling_ability(color, Castle::Long),
|
||||||
Castle::Short => self.set_castling_ability(color, Castle::None),
|
Castle::Short => self.set_castling_ability(color, Castle::None),
|
||||||
_ => (),
|
_ => (),
|
||||||
@@ -72,7 +72,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if target == long_square {
|
if target == long_square {
|
||||||
match self.get_castling_ability(color) {
|
match self.castling_ability(color) {
|
||||||
Castle::Both => self.set_castling_ability(color, Castle::Short),
|
Castle::Both => self.set_castling_ability(color, Castle::Short),
|
||||||
Castle::Long => self.set_castling_ability(color, Castle::None),
|
Castle::Long => self.set_castling_ability(color, Castle::None),
|
||||||
_ => (),
|
_ => (),
|
||||||
@@ -91,11 +91,11 @@ impl State {
|
|||||||
self.side_to_move
|
self.side_to_move
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_en_passant_target_square(&mut self, sq: Option<usize>) {
|
pub fn set_en_passant_target_square(&mut self, square: Option<usize>) {
|
||||||
self.en_passant_target_square = sq;
|
self.en_passant_target_square = square;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn get_castling_ability(&self, color: Color) -> Castle {
|
pub const fn castling_ability(&self, color: Color) -> Castle {
|
||||||
match color {
|
match color {
|
||||||
Color::White => self.castling_ability[0],
|
Color::White => self.castling_ability[0],
|
||||||
Color::Black => self.castling_ability[1],
|
Color::Black => self.castling_ability[1],
|
||||||
|
|||||||
Reference in New Issue
Block a user