diff --git a/src/attack.rs b/src/attack.rs index f9cf02d..f12d1b4 100644 --- a/src/attack.rs +++ b/src/attack.rs @@ -87,143 +87,114 @@ const fn king_attacks(bitboard: Bitboard) -> Bitboard { pub fn mask_bishop_attacks(bitboard: Bitboard) -> Bitboard { let mut attacks = EMPTY; - let (target_rank, target_file) = match bitboard { + let (rank_dst, file_dst) = match bitboard { 0 => (0, 0), _ => (lsb(bitboard) / 8, lsb(bitboard) % 8), }; - let (mut rank, mut file) = (target_rank + 1, target_file + 1); - for (rank, file) in (rank..=6).zip(file..=6) { - attacks |= square_to_bitboard(coords_to_square(rank, file)); - } + 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)); + } + }; - (rank, file) = (target_rank.saturating_sub(1), target_file + 1); - for (rank, file) in (1..=rank).rev().zip(file..=6) { - attacks |= square_to_bitboard(coords_to_square(rank, file)); - } - - (rank, file) = (target_rank + 1, target_file.saturating_sub(1)); - for (rank, file) in (rank..=6).zip((1..=file).rev()) { - attacks |= square_to_bitboard(coords_to_square(rank, file)); - } - - (rank, file) = (target_rank.saturating_sub(1), target_file.saturating_sub(1)); - for (rank, file) in (1..=rank).rev().zip((1..=file).rev()) { - attacks |= square_to_bitboard(coords_to_square(rank, file)); - } + 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()), + ); attacks } pub fn mask_rook_attacks(bitboard: Bitboard) -> Bitboard { let mut attacks = EMPTY; - let (target_rank, target_file) = match bitboard { + let (rank_dst, file_dst) = match bitboard { 0 => (0, 0), _ => (lsb(bitboard) / 8, lsb(bitboard) % 8), }; - let (mut rank, mut file) = (target_rank + 1, target_file + 1); - for rank in rank..=6 { - attacks |= square_to_bitboard(coords_to_square(rank, target_file)); - } - for file in file..=6 { - attacks |= square_to_bitboard(coords_to_square(target_rank, file)); - } + let mut add_attacks_in_direction = |iter: Box>, + is_vertical: bool| { + for coord in iter { + 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; + } + }; - (rank, file) = (target_rank.saturating_sub(1), target_file.saturating_sub(1)); - for rank in (1..=rank).rev() { - attacks |= square_to_bitboard(coords_to_square(rank, target_file)); - } - for file in (1..=file).rev() { - attacks |= square_to_bitboard(coords_to_square(target_rank, file)); - } + 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); attacks } pub fn bishop_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboard { let mut attacks = EMPTY; - let (target_rank, target_file) = match bitboard { + let (rank_dst, file_dst) = match bitboard { 0 => (0, 0), _ => (lsb(bitboard) / 8, lsb(bitboard) % 8), }; - let (mut rank, mut file) = (target_rank + 1, target_file + 1); - for (rank, file) in (rank..=7).zip(file..=7) { - 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_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; + } + } + }; - file = target_file + 1; - for (rank, file) in (0..target_rank).rev().zip(file..=7) { - let attack_square = square_to_bitboard(coords_to_square(rank, file)); - attacks |= attack_square; - if have_common_bit(attack_square, blocker) { - break; - } - } - - rank = target_rank + 1; - for (rank, file) in (rank..=7).zip((0..target_file).rev()) { - let attack_square = square_to_bitboard(coords_to_square(rank, file)); - attacks |= attack_square; - if have_common_bit(attack_square, blocker) { - break; - } - } - - for (rank, file) in (0..target_rank).rev().zip((0..target_file).rev()) { - let attack_square = square_to_bitboard(coords_to_square(rank, file)); - attacks |= attack_square; - if have_common_bit(attack_square, blocker) { - break; - } - } + 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())); attacks } pub fn rook_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboard { let mut attacks = EMPTY; - let (target_rank, target_file) = match bitboard { + let (rank_dst, file_dst) = match bitboard { 0 => (0, 0), _ => (lsb(bitboard) / 8, lsb(bitboard) % 8), }; - let (mut rank, mut file) = (target_rank + 1, target_file + 1); - for rank in rank..=7 { - let attack_square = square_to_bitboard(coords_to_square(rank, target_file)); - attacks |= attack_square; - if have_common_bit(attack_square, blocker) { - break; + let mut add_attacks_in_direction = |iter: Box>, + is_vertical: bool| { + for coord in iter { + 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; + } } - } - for file in file..=7 { - let attack_square = square_to_bitboard(coords_to_square(target_rank, file)); - attacks |= attack_square; - if have_common_bit(attack_square, blocker) { - break; - } - } + }; - (rank, file) = (target_rank.saturating_sub(1), target_file.saturating_sub(1)); - for rank in (0..=rank).rev() { - let attack_square = square_to_bitboard(coords_to_square(rank, target_file)); - attacks |= attack_square; - if have_common_bit(attack_square, blocker) { - break; - } - } - for file in (0..=file).rev() { - let attack_square = square_to_bitboard(coords_to_square(target_rank, file)); - 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); attacks }