Skip to content
105 changes: 29 additions & 76 deletions src/board/parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::Board;
use crate::{
lookup::between,
types::{CastlingKind, Color, Piece, PieceType, Square},
lookup::{between, ray_pass},
types::{CastlingKind, Color, HOME_RANK, KING_TO_FILE, Piece, PieceType, ROOK_TO_FILE, Square},
};

#[derive(Debug)]
Expand Down Expand Up @@ -67,81 +67,34 @@ impl Board {

fn set_castling(&mut self, rights: &str) {
for right in rights.chars() {
match right {
'K' => {
let mut rook_from = Square::H1;
while self.piece_on(rook_from).piece_type() != PieceType::Rook {
rook_from = rook_from.shift(-1);
}

let king_from = self.king_square(Color::White);
self.set_castling_for(CastlingKind::WhiteKingside, king_from, Square::G1, rook_from, Square::F1);
}
'Q' => {
let mut rook_from = Square::A1;
while self.piece_on(rook_from).piece_type() != PieceType::Rook {
rook_from = rook_from.shift(1);
}

let king_from = self.king_square(Color::White);
self.set_castling_for(CastlingKind::WhiteQueenside, king_from, Square::C1, rook_from, Square::D1);
}
'k' => {
let mut rook_from = Square::H8;
while self.piece_on(rook_from).piece_type() != PieceType::Rook {
rook_from = rook_from.shift(-1);
}

let king_from = self.king_square(Color::Black);
self.set_castling_for(CastlingKind::BlackKingside, king_from, Square::G8, rook_from, Square::F8);
}
'q' => {
let mut rook_from = Square::A8;
while self.piece_on(rook_from).piece_type() != PieceType::Rook {
rook_from = rook_from.shift(1);
}

let king_from = self.king_square(Color::Black);
self.set_castling_for(CastlingKind::BlackQueenside, king_from, Square::C8, rook_from, Square::D8);
}
token @ 'A'..='H' => {
let king_from = self.king_square(Color::White);
let rook_from = Square::from_rank_file(0, token as u8 - b'A');

let kind = if king_from.file() < rook_from.file() {
CastlingKind::WhiteKingside
} else {
CastlingKind::WhiteQueenside
};

let (king_to, rook_to) = match kind {
CastlingKind::WhiteKingside => (Square::G1, Square::F1),
CastlingKind::WhiteQueenside => (Square::C1, Square::D1),
_ => unreachable!(),
};

self.set_castling_for(kind, king_from, king_to, rook_from, rook_to);
}
token @ 'a'..='h' => {
let king_from = self.king_square(Color::Black);
let rook_from = Square::from_rank_file(7, token as u8 - b'a');

let kind = if king_from.file() < rook_from.file() {
CastlingKind::BlackKingside
} else {
CastlingKind::BlackQueenside
};

let (king_to, rook_to) = match kind {
CastlingKind::BlackKingside => (Square::G8, Square::F8),
CastlingKind::BlackQueenside => (Square::C8, Square::D8),
_ => unreachable!(),
};

self.set_castling_for(kind, king_from, king_to, rook_from, rook_to);
}
_ => continue,
if !matches!(right.to_ascii_uppercase(), 'A'..='H' | 'K' | 'Q') {
continue;
}

let color = if right.is_uppercase() { Color::White } else { Color::Black };
let king_from = self.king_square(color);
let mut search_step = right.to_ascii_uppercase() as i8 - b'A' as i8 - king_from.file() as i8;

if right.eq_ignore_ascii_case(&'K') {
search_step = Square::RIGHT;
}
if right.eq_ignore_ascii_case(&'Q') {
search_step = Square::LEFT;
}

let rook_from =
(ray_pass(king_from, king_from.shift(search_step)) & self.colored_pieces(color, PieceType::Rook)).lsb();

let king_side = rook_from > king_from;

let rights = if king_side { CastlingKind::KINGSIDE[color] } else { CastlingKind::QUEENSIDE[color] };

let king_to =
Square::from_rank_file(HOME_RANK[color].clone() as u8, KING_TO_FILE[king_side as usize].clone() as u8);
let rook_to =
Square::from_rank_file(HOME_RANK[color].clone() as u8, ROOK_TO_FILE[king_side as usize].clone() as u8);

self.set_castling_for(rights, king_from, king_to, rook_from, rook_to);
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/tools/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ const POSITIONS: &[&str] = &[
"8/8/1k1r2p1/p1p2nPp/P3RN1P/8/4KP2/8 b - - 13 55",
"5r1k/1p3p1p/2p2p2/1q2bP1Q/3p1P2/1PP1R1P1/6KP/2N5 w - - 0 25",
"8/8/5pk1/5Nn1/R3r1P1/8/6K1/8 w - - 4 65",
"rbbnkqrn/pppppppp/8/8/8/8/PPPPPPPP/RBBNKQRN w AGag - 0 1",
"nbrknrbq/pppppppp/8/8/8/8/PPPPPPPP/NBRKNRBQ w CFcf - 0 1",
"nqnbbrkr/pppppppp/8/8/8/8/PPPPPPPP/NQNBBRKR w FHfh - 0 1",
"nqrnbkrb/pppppppp/8/8/8/8/PPPPPPPP/NQRNBKRB w KQkq - 0 1",
"rqkbbnnr/pppppppp/8/8/8/8/PPPPPPPP/BBNNRKRQ w GEha - 0 1",
];

const DEFAULT_DEPTH: i32 = 12;
Expand Down
4 changes: 4 additions & 0 deletions src/types/bitboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ impl Bitboard {
Square::new(self.0.trailing_zeros() as u8)
}

pub const fn msb(self) -> Square {
Square::new(63 - self.0.leading_zeros() as u8)
}

pub const fn shift(self, offset: i8) -> Self {
if offset > 0 { Self(self.0 << offset) } else { Self(self.0 >> -offset) }
}
Expand Down
8 changes: 6 additions & 2 deletions src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,21 @@ pub const MAX_MOVES: usize = 256;

#[rustfmt::skip]
#[repr(u8)]
#[derive(PartialEq, PartialOrd)]
#[derive(Clone, PartialEq, PartialOrd)]
pub enum Rank { R1, R2, R3, R4, R5, R6, R7, R8 }

pub const PROMO_RANK: [Rank; 2] = [Rank::R8, Rank::R1];
pub const HOME_RANK: [Rank; 2] = [Rank::R1, Rank::R8];
pub const PAWN_HOME_RANK: [Rank; 2] = [Rank::R2, Rank::R7];

#[rustfmt::skip]
#[repr(u8)]
#[derive(PartialEq, PartialOrd)]
#[derive(Clone, PartialEq, PartialOrd)]
pub enum File { A, B, C, D, E, F, G, H }

pub const KING_TO_FILE: [File; 2] = [File::C, File::G];
pub const ROOK_TO_FILE: [File; 2] = [File::D, File::F];

impl File {
pub fn is_kingside(&self) -> bool {
*self >= File::E
Expand Down
2 changes: 1 addition & 1 deletion src/types/square.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::types::{Color, File, Rank};
/// Represents a square on a bitboard corresponding to the [Little-Endian Rank-File Mapping][LERFM].
///
/// [LERFM]: https://www.chessprogramming.org/Square_Mapping_Considerations#Little-Endian_Rank-File_Mapping
#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Debug, Default)]
#[repr(u8)]
#[rustfmt::skip]
pub enum Square {
Expand Down