diff --git a/src/board/board.rs b/src/board/board.rs index 4fa96e1..3282110 100644 --- a/src/board/board.rs +++ b/src/board/board.rs @@ -104,11 +104,13 @@ impl Board { Color::Black => lsb(self.black_pieces[PieceType::King].bitboard), }; - self.is_attacked(own_king_square, Color::opponent_color(color)) + self.is_attacked(own_king_square, color.opponent()) } - pub fn pseudo_moves_all(&self, color: Color) -> Vec { + pub fn pseudo_moves_all(&self) -> Vec { + let color = self.state.current_player(); let mut moves = vec![]; + moves.extend(self.pseudo_moves(color, PieceType::Pawn)); moves.extend(self.pseudo_moves(color, PieceType::Knight)); moves.extend(self.pseudo_moves(color, PieceType::Bishop)); @@ -245,8 +247,8 @@ pub enum Color { } impl Color { - pub const fn opponent_color(color: Self) -> Self { - match color { + pub const fn opponent(&self) -> Self { + match self { Self::White => Self::Black, Self::Black => Self::White, } diff --git a/src/board/history.rs b/src/board/history.rs index 33c8956..735820c 100644 --- a/src/board/history.rs +++ b/src/board/history.rs @@ -75,13 +75,11 @@ impl MoveParameters { pub fn add_capture_and_promotion_piece(&mut self, board: &Board, mv: Move, color: Color) { match mv.move_type { - MoveType::Capture => { - self.add_captured_piece(board, mv.dst, Color::opponent_color(color)) - } + MoveType::Capture => self.add_captured_piece(board, mv.dst, color.opponent()), MoveType::Promotion(piece) => self.add_promoted_piece(piece), MoveType::PromotionCapture(piece) => { self.add_promoted_piece(piece); - self.add_captured_piece(board, mv.dst, Color::opponent_color(color)); + self.add_captured_piece(board, mv.dst, color.opponent()); } _ => (), } diff --git a/src/movegen/attack.rs b/src/movegen/attack.rs index 98c166e..5d96a75 100644 --- a/src/movegen/attack.rs +++ b/src/movegen/attack.rs @@ -89,26 +89,21 @@ pub fn mask_bishop_attacks(bitboard: Bitboard) -> Bitboard { let mut attacks = EMPTY; let (rank_dst, file_dst) = bitboard_to_coords(bitboard); - let mut add_attacks_in_direction = - |rank_iter: Box>, file_iter: Box>| { - for (rank, file) in rank_iter.zip(file_iter) { - attacks |= square_to_bitboard(coords_to_square(rank, file)); - } - }; + let mut add_attacks_in_direction = |rank_step: isize, file_step: isize| { + let mut rank = rank_dst as isize; + let mut file = file_dst as isize; - add_attacks_in_direction(Box::new((rank_dst + 1)..=6), Box::new((file_dst + 1)..=6)); - add_attacks_in_direction( - Box::new((1..=rank_dst.saturating_sub(1)).rev()), - Box::new((file_dst + 1)..=6), - ); - add_attacks_in_direction( - Box::new((rank_dst + 1)..=6), - Box::new((1..=file_dst.saturating_sub(1)).rev()), - ); - add_attacks_in_direction( - Box::new((1..=rank_dst.saturating_sub(1)).rev()), - Box::new((1..=file_dst.saturating_sub(1)).rev()), - ); + while (1..=6).contains(&(rank + rank_step)) && (1..=6).contains(&(file + file_step)) { + rank += rank_step; + file += file_step; + attacks |= square_to_bitboard(coords_to_square(rank as usize, file as usize)); + } + }; + + add_attacks_in_direction(1, 1); + add_attacks_in_direction(-1, 1); + add_attacks_in_direction(1, -1); + add_attacks_in_direction(-1, -1); attacks } @@ -117,22 +112,24 @@ pub fn mask_rook_attacks(bitboard: Bitboard) -> Bitboard { let mut attacks = EMPTY; let (rank_dst, file_dst) = bitboard_to_coords(bitboard); - let mut add_attacks_in_direction = |iter: Box>, - is_vertical: bool| { - for coord in iter { + let mut add_attacks_in_direction = |mut coord: usize, step: isize, is_vertical: bool| { + while (1..=6).contains(&(coord as isize + step)) { + coord = (coord as isize + step) as usize; + let attack_square = if is_vertical { square_to_bitboard(coords_to_square(coord, file_dst)) } else { square_to_bitboard(coords_to_square(rank_dst, coord)) }; + attacks |= attack_square; } }; - add_attacks_in_direction(Box::new((rank_dst + 1)..=6), true); - add_attacks_in_direction(Box::new((file_dst + 1)..=6), false); - add_attacks_in_direction(Box::new((1..=rank_dst.saturating_sub(1)).rev()), true); - add_attacks_in_direction(Box::new((1..=file_dst.saturating_sub(1)).rev()), false); + add_attacks_in_direction(rank_dst, 1, true); + add_attacks_in_direction(rank_dst, -1, true); + add_attacks_in_direction(file_dst, 1, false); + add_attacks_in_direction(file_dst, -1, false); attacks } @@ -141,21 +138,27 @@ pub fn bishop_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitbo let mut attacks = EMPTY; let (rank_dst, file_dst) = bitboard_to_coords(bitboard); - let mut add_attacks_in_direction = - |rank_iter: Box>, file_iter: Box>| { - for (rank, file) in rank_iter.zip(file_iter) { - let attack_square = square_to_bitboard(coords_to_square(rank, file)); - attacks |= attack_square; - if have_common_bit(attack_square, blocker) { - break; - } - } - }; + let mut add_attacks_in_direction = |rank_step: isize, file_step: isize| { + let mut rank = rank_dst as isize; + let mut file = file_dst as isize; - add_attacks_in_direction(Box::new((rank_dst + 1)..=7), Box::new((file_dst + 1)..=7)); - add_attacks_in_direction(Box::new((0..rank_dst).rev()), Box::new((file_dst + 1)..=7)); - add_attacks_in_direction(Box::new((rank_dst + 1)..=7), Box::new((0..file_dst).rev())); - add_attacks_in_direction(Box::new((0..rank_dst).rev()), Box::new((0..file_dst).rev())); + while (0..=7).contains(&(rank + rank_step)) && (0..=7).contains(&(file + file_step)) { + rank += rank_step; + file += file_step; + + let attack_square = square_to_bitboard(coords_to_square(rank as usize, file as usize)); + attacks |= attack_square; + + if have_common_bit(attack_square, blocker) { + break; + } + } + }; + + add_attacks_in_direction(1, 1); + add_attacks_in_direction(-1, 1); + add_attacks_in_direction(1, -1); + add_attacks_in_direction(-1, -1); attacks } @@ -164,25 +167,28 @@ pub fn rook_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboar let mut attacks = EMPTY; let (rank_dst, file_dst) = bitboard_to_coords(bitboard); - let mut add_attacks_in_direction = |iter: Box>, - is_vertical: bool| { - for coord in iter { + let mut add_attacks_in_direction = |mut coord: usize, step: isize, is_vertical: bool| { + while (0..=7).contains(&(coord as isize + step)) { + coord = (coord as isize + step) as usize; + let attack_square = if is_vertical { square_to_bitboard(coords_to_square(coord, file_dst)) } else { square_to_bitboard(coords_to_square(rank_dst, coord)) }; + attacks |= attack_square; + if have_common_bit(attack_square, blocker) { break; } } }; - add_attacks_in_direction(Box::new((rank_dst + 1)..=7), true); - add_attacks_in_direction(Box::new((file_dst + 1)..=7), false); - add_attacks_in_direction(Box::new((0..rank_dst).rev()), true); - add_attacks_in_direction(Box::new((0..file_dst).rev()), false); + add_attacks_in_direction(rank_dst, 1, true); + add_attacks_in_direction(rank_dst, -1, true); + add_attacks_in_direction(file_dst, 1, false); + add_attacks_in_direction(file_dst, -1, false); attacks } diff --git a/src/movegen/move.rs b/src/movegen/move.rs index bd3c2d6..8b5d33c 100644 --- a/src/movegen/move.rs +++ b/src/movegen/move.rs @@ -234,7 +234,7 @@ impl Board { fn update_game_state(state: &mut State, mv: &Move, color: Color, pawn_move: bool) { state.set_en_passant_square(None); state.update_castling_state_quiet(mv.src, color); - state.update_castling_state_capture(mv.dst, Color::opponent_color(color)); + state.update_castling_state_capture(mv.dst, color.opponent()); state.update_half_move(mv.move_type, pawn_move); state.update_full_move(color); state.change_side(); diff --git a/src/search/negamax.rs b/src/search/negamax.rs index 5d60415..fbe234e 100644 --- a/src/search/negamax.rs +++ b/src/search/negamax.rs @@ -22,7 +22,7 @@ pub fn negamax( let (mut best_move, mut best_score, mate_score) = (None, MIN_SCORE, -MATE_SCORE + plies as i32); let mut legal_moves = 0; - for mv in game.board.pseudo_moves_all(color) { + for mv in game.board.pseudo_moves_all() { let move_parameters = MoveParameters::build(&game.board, &mv); game.board.make_move(&mv); diff --git a/src/search/perft.rs b/src/search/perft.rs index 8adf3a5..c5ab95e 100644 --- a/src/search/perft.rs +++ b/src/search/perft.rs @@ -7,7 +7,7 @@ pub fn driver(game: &mut Game, nodes: &mut u64, depth: u8) { } let color = game.current_player(); - let pseudo_moves = game.board.pseudo_moves_all(color); + let pseudo_moves = game.board.pseudo_moves_all(); for mv in pseudo_moves { let original_board = game.board.clone(); diff --git a/src/search/quiescence.rs b/src/search/quiescence.rs index b8820ce..9ac8846 100644 --- a/src/search/quiescence.rs +++ b/src/search/quiescence.rs @@ -18,7 +18,7 @@ pub fn quiescence(game: &mut Game, mut alpha: i32, beta: i32) -> (Option, let captures = game .board - .pseudo_moves_all(color) + .pseudo_moves_all() .into_iter() .filter(|m| !matches!(m.move_type, MoveType::Quiet));