diff --git a/src/board.rs b/src/board.rs index 1024f15..3212217 100644 --- a/src/board.rs +++ b/src/board.rs @@ -5,12 +5,13 @@ use crate::attack::{ get_rook_attacks, }; use crate::bitboard::{have_common_bit, lsb, square_to_bitboard}; -use crate::game::{Castle, State}; use crate::movegen::{ bishop_pseudo_moves, king_pseudo_moves, knight_pseudo_moves, pawn_pseudo_moves, queen_pseudo_moves, rook_pseudo_moves, }; use crate::r#move::{Move, MoveType, Promote}; +use crate::square::Square; +use crate::state::{Castle, State}; #[derive(Debug, PartialEq, Eq, Clone)] pub struct Board { @@ -242,14 +243,14 @@ impl Board { } } - fn move_rook_castle(square: usize, pieces: &mut [Piece; 6]) { - let (rook_source, rook_target) = match square { - 2 | 58 => (square - 2, square + 1), - 6 | 62 => (square + 1, square - 1), + fn move_rook_castle(king_dst: usize, pieces: &mut [Piece; 6]) { + let (rook_src, rook_dst) = match king_dst { + Square::C1 | Square::C8 => (king_dst - 2, king_dst + 1), + Square::G1 | Square::G8 => (king_dst + 1, king_dst - 1), _ => return, }; - Self::move_piece(rook_source, rook_target, pieces); + Self::move_piece(rook_src, rook_dst, pieces); } fn promote_piece(square: usize, pieces: &mut [Piece; 6], promote: Promote) { diff --git a/src/fen.rs b/src/fen.rs index 3ee569c..325e541 100644 --- a/src/fen.rs +++ b/src/fen.rs @@ -1,5 +1,6 @@ use crate::board::{Board, Color, Kind, Piece}; -use crate::game::{Castle, Game, State}; +use crate::game::Game; +use crate::state::{Castle, State}; use String as FenError; pub fn from_fen(fen: &str) -> Result { diff --git a/src/game.rs b/src/game.rs index 977c5d9..638191e 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,7 +1,4 @@ -use crate::{ - board::{Board, Color}, - fen::from_fen, -}; +use crate::{board::Board, fen::from_fen}; use String as FenError; #[derive(Debug, PartialEq, Eq)] @@ -30,120 +27,3 @@ impl Default for Game { Self::new() } } - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub struct State { - side_to_move: Color, - castling_ability: [Castle; 2], - en_passant_target_square: Option, - halfmove_clock: u8, - fullmove_counter: u8, -} - -impl State { - pub const fn new() -> Self { - Self { - side_to_move: Color::White, - castling_ability: [Castle::Both, Castle::Both], - en_passant_target_square: None, - halfmove_clock: 0, - fullmove_counter: 1, - } - } - - pub const fn load_state( - side_to_move: Color, - castling_ability: [Castle; 2], - en_passant_target_square: Option, - halfmove_clock: u8, - fullmove_counter: u8, - ) -> Self { - Self { - side_to_move, - castling_ability, - en_passant_target_square, - halfmove_clock, - fullmove_counter, - } - } - - pub const fn get_en_passant_target_square(&self) -> Option { - self.en_passant_target_square - } - - pub fn set_castling_ability(&mut self, color: Color, castle: Castle) { - match color { - Color::White => self.castling_ability[0] = castle, - Color::Black => self.castling_ability[1] = castle, - } - } - - pub fn update_castling_state_quiet(&mut self, source: usize, color: Color) { - self.update_castling_state_capture(source, color); - - match (source, color) { - (4, Color::White) => self.set_castling_ability(color, Castle::None), - (60, Color::Black) => self.set_castling_ability(color, Castle::None), - _ => (), - } - } - - pub fn update_castling_state_capture(&mut self, target: usize, color: Color) { - let (short_square, long_square) = match color { - Color::White => (7, 0), - Color::Black => (63, 56), - }; - - if target == short_square { - match self.get_castling_ability(color) { - Castle::Both => self.set_castling_ability(color, Castle::Long), - Castle::Short => self.set_castling_ability(color, Castle::None), - _ => (), - } - } - - if target == long_square { - match self.get_castling_ability(color) { - Castle::Both => self.set_castling_ability(color, Castle::Short), - Castle::Long => self.set_castling_ability(color, Castle::None), - _ => (), - } - } - } - - pub fn change_side(&mut self) { - self.side_to_move = match self.side_to_move { - Color::White => Color::Black, - Color::Black => Color::White, - } - } - - pub const fn next_turn(&self) -> Color { - self.side_to_move - } - - pub fn set_en_passant_target_square(&mut self, sq: Option) { - self.en_passant_target_square = sq; - } - - pub const fn get_castling_ability(&self, color: Color) -> Castle { - match color { - Color::White => self.castling_ability[0], - Color::Black => self.castling_ability[1], - } - } -} - -impl Default for State { - fn default() -> Self { - Self::new() - } -} - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum Castle { - Short, - Long, - Both, - None, -} diff --git a/src/main.rs b/src/main.rs index cc0cfbf..8d867b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ pub mod r#move; pub mod movegen; pub mod perft; pub mod square; +pub mod state; fn main() { attack::init_attacks(); diff --git a/src/movegen.rs b/src/movegen.rs index 7893b88..ecd2cde 100644 --- a/src/movegen.rs +++ b/src/movegen.rs @@ -7,8 +7,8 @@ use crate::bitboard::{ RANK_5, RANK_7, RANK_8, }; use crate::board::{Board, Color}; -use crate::game::Castle; use crate::r#move::{Move, MoveType, Promote}; +use crate::state::Castle; use u64 as Bitboard; pub fn pawn_pseudo_moves( diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..0cd924a --- /dev/null +++ b/src/state.rs @@ -0,0 +1,118 @@ +use crate::board::Color; + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct State { + side_to_move: Color, + castling_ability: [Castle; 2], + en_passant_target_square: Option, + halfmove_clock: u8, + fullmove_counter: u8, +} + +impl State { + pub const fn new() -> Self { + Self { + side_to_move: Color::White, + castling_ability: [Castle::Both, Castle::Both], + en_passant_target_square: None, + halfmove_clock: 0, + fullmove_counter: 1, + } + } + + pub const fn load_state( + side_to_move: Color, + castling_ability: [Castle; 2], + en_passant_target_square: Option, + halfmove_clock: u8, + fullmove_counter: u8, + ) -> Self { + Self { + side_to_move, + castling_ability, + en_passant_target_square, + halfmove_clock, + fullmove_counter, + } + } + + pub const fn get_en_passant_target_square(&self) -> Option { + self.en_passant_target_square + } + + pub fn set_castling_ability(&mut self, color: Color, castle: Castle) { + match color { + Color::White => self.castling_ability[0] = castle, + Color::Black => self.castling_ability[1] = castle, + } + } + + pub fn update_castling_state_quiet(&mut self, source: usize, color: Color) { + self.update_castling_state_capture(source, color); + + match (source, color) { + (4, Color::White) => self.set_castling_ability(color, Castle::None), + (60, Color::Black) => self.set_castling_ability(color, Castle::None), + _ => (), + } + } + + pub fn update_castling_state_capture(&mut self, target: usize, color: Color) { + let (short_square, long_square) = match color { + Color::White => (7, 0), + Color::Black => (63, 56), + }; + + if target == short_square { + match self.get_castling_ability(color) { + Castle::Both => self.set_castling_ability(color, Castle::Long), + Castle::Short => self.set_castling_ability(color, Castle::None), + _ => (), + } + } + + if target == long_square { + match self.get_castling_ability(color) { + Castle::Both => self.set_castling_ability(color, Castle::Short), + Castle::Long => self.set_castling_ability(color, Castle::None), + _ => (), + } + } + } + + pub fn change_side(&mut self) { + self.side_to_move = match self.side_to_move { + Color::White => Color::Black, + Color::Black => Color::White, + } + } + + pub const fn next_turn(&self) -> Color { + self.side_to_move + } + + pub fn set_en_passant_target_square(&mut self, sq: Option) { + self.en_passant_target_square = sq; + } + + pub const fn get_castling_ability(&self, color: Color) -> Castle { + match color { + Color::White => self.castling_ability[0], + Color::Black => self.castling_ability[1], + } + } +} + +impl Default for State { + fn default() -> Self { + Self::new() + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum Castle { + Short, + Long, + Both, + None, +}