Clean up duplicate code bishop/rook attacks using deltas for each direction

This commit is contained in:
2024-07-16 19:02:19 +03:00
parent 47561a8372
commit 8d779d69d0

View File

@@ -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<dyn Iterator<Item = usize>>, file_iter: Box<dyn Iterator<Item = usize>>| {
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<dyn Iterator<Item = usize>>,
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<dyn Iterator<Item = usize>>, file_iter: Box<dyn Iterator<Item = usize>>| {
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<dyn Iterator<Item = usize>>,
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
}