implement is_square_attacked and is_king_attacked
This commit is contained in:
parent
1ddc38165f
commit
e305a3556f
6 changed files with 463 additions and 12 deletions
89
helper_scripts/generate_attacking_pawns.py
Normal file
89
helper_scripts/generate_attacking_pawns.py
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
def generate_pawn_attacked_by():
|
||||
"""
|
||||
Generates a list of 64 u64 bitboards for each color (White, Black),
|
||||
where each bitboard represents the squares FROM WHICH a pawn
|
||||
can attack a given TARGET square.
|
||||
Uses Little-Endian File-Rank (LEFR) mapping: A1=0, H1=7, A2=8, ..., H8=63.
|
||||
|
||||
Returns:
|
||||
[[u64; 64]; 2] (represented as a list of two lists)
|
||||
Index 0: White attackers (squares where a White pawn attacks the target)
|
||||
Index 1: Black attackers (squares where a Black pawn attacks the target)
|
||||
"""
|
||||
|
||||
# all_attacks[0] = White, all_attacks[1] = Black
|
||||
all_attacks = [[], []]
|
||||
|
||||
for sq in range(64):
|
||||
rank = sq // 8
|
||||
file = sq % 8
|
||||
|
||||
white_attackers_bb = 0
|
||||
black_attackers_bb = 0
|
||||
|
||||
# --- White Attackers (Index 0) ---
|
||||
# A white pawn attacks "up" the board to reach the target square 'sq'.
|
||||
# This means the attacking pawn must be "below" 'sq'.
|
||||
# We only check if the target is not on the 1st rank
|
||||
if rank > 0:
|
||||
# Attacker from Down-Left (relative to target sq)
|
||||
# Not possible if target is on the A-file
|
||||
if file > 0:
|
||||
white_attackers_bb |= (1 << (sq - 9))
|
||||
|
||||
# Attacker from Down-Right (relative to target sq)
|
||||
# Not possible if target is on the H-file
|
||||
if file < 7:
|
||||
white_attackers_bb |= (1 << (sq - 7))
|
||||
|
||||
# --- Black Attackers (Index 1) ---
|
||||
# A black pawn attacks "down" the board to reach the target square 'sq'.
|
||||
# This means the attacking pawn must be "above" 'sq'.
|
||||
# We only check if the target is not on the 8th rank
|
||||
if rank < 7:
|
||||
# Attacker from Up-Left (relative to target sq)
|
||||
# Not possible if target is on the A-file
|
||||
if file > 0:
|
||||
black_attackers_bb |= (1 << (sq + 7))
|
||||
|
||||
# Attacker from Up-Right (relative to target sq)
|
||||
# Not possible if target is on the H-file
|
||||
if file < 7:
|
||||
black_attackers_bb |= (1 << (sq + 9))
|
||||
|
||||
all_attacks[0].append(white_attackers_bb)
|
||||
all_attacks[1].append(black_attackers_bb)
|
||||
|
||||
return all_attacks
|
||||
|
||||
def print_rust_array(attacks_by_color, const_name):
|
||||
"""
|
||||
Prints the list of attack bitboards as a nested Rust array.
|
||||
"""
|
||||
print(f"pub const {const_name}: [[u64; 64]; 2] = [")
|
||||
|
||||
# --- Print White Attacks ---
|
||||
print(" [ // Color 0: White (Squares a White pawn attacks FROM)")
|
||||
for i, attacks_bb in enumerate(attacks_by_color[0]):
|
||||
raw_binary_string = f"{attacks_bb:064b}"
|
||||
chunks = [raw_binary_string[i:i+8] for i in range(0, 64, 8)]
|
||||
binary_string = f"0b{'_'.join(chunks)}"
|
||||
print(f" {binary_string}, // Target Square {i} ({'ABCDEFGH'[i%8]}{i//8 + 1})")
|
||||
print(" ],")
|
||||
|
||||
# --- Print Black Attacks ---
|
||||
print(" [ // Color 1: Black (Squares a Black pawn attacks FROM)")
|
||||
for i, attacks_bb in enumerate(attacks_by_color[1]):
|
||||
raw_binary_string = f"{attacks_bb:064b}"
|
||||
chunks = [raw_binary_string[i:i+8] for i in range(0, 64, 8)]
|
||||
binary_string = f"0b{'_'.join(chunks)}"
|
||||
print(f" {binary_string}, // Target Square {i} ({'ABCDEFGH'[i%8]}{i//8 + 1})")
|
||||
print(" ]")
|
||||
|
||||
print("];")
|
||||
|
||||
if __name__ == "__main__":
|
||||
attacks = generate_pawn_attacked_by()
|
||||
print_rust_array(attacks, "ATTACKING_PAWNS")
|
||||
137
src/display.rs
137
src/display.rs
|
|
@ -1,6 +1,7 @@
|
|||
use std::fmt;
|
||||
use crate::board::{Board, Color, PieceType};
|
||||
use crate::r#move::{Move, MoveList, MOVE_FLAG_BK_CASTLE, MOVE_FLAG_BQ_CASTLE, MOVE_FLAG_PROMO_B, MOVE_FLAG_PROMO_B_CAP, MOVE_FLAG_PROMO_N, MOVE_FLAG_PROMO_N_CAP, MOVE_FLAG_PROMO_Q, MOVE_FLAG_PROMO_Q_CAP, MOVE_FLAG_PROMO_R, MOVE_FLAG_PROMO_R_CAP, MOVE_FLAG_WK_CASTLE, MOVE_FLAG_WQ_CASTLE, MOVE_FROM_MASK, MOVE_TO_MASK};
|
||||
use crate::r#move::MoveList;
|
||||
use crate::square::Square;
|
||||
use std::fmt;
|
||||
|
||||
impl Board {
|
||||
/// Prints the board as a human-readable ASCII grid.
|
||||
|
|
@ -12,7 +13,7 @@ impl Board {
|
|||
let sq = (rank * 8 + file) as u8;
|
||||
let mask = 1u64 << sq;
|
||||
|
||||
if let Some(piece) = self.get_piece_at(mask) {
|
||||
if let Some(piece) = self.get_piece_at_unicode(mask) {
|
||||
print!("{} ", piece);
|
||||
} else {
|
||||
print!(". ");
|
||||
|
|
@ -45,7 +46,7 @@ impl Board {
|
|||
println!();
|
||||
}
|
||||
|
||||
/// Helper function to find which piece (as a char) is on a given square mask.
|
||||
/// Helper function to find which piece (as a FEN char) is on a given square mask.
|
||||
pub fn get_piece_at(&self, sq_mask: u64) -> Option<char> {
|
||||
let white = Color::White as usize;
|
||||
let black = Color::Black as usize;
|
||||
|
|
@ -90,6 +91,51 @@ impl Board {
|
|||
None
|
||||
}
|
||||
|
||||
/// Helper function to find which piece (as a unicode char) is on a given square mask.
|
||||
pub fn get_piece_at_unicode(&self, sq_mask: u64) -> Option<char> {
|
||||
let white = Color::White as usize;
|
||||
let black = Color::Black as usize;
|
||||
|
||||
if (self.pieces[PieceType::Pawn as usize][white] & sq_mask) != 0 {
|
||||
return Some('♙');
|
||||
}
|
||||
if (self.pieces[PieceType::Pawn as usize][black] & sq_mask) != 0 {
|
||||
return Some('♟');
|
||||
}
|
||||
if (self.pieces[PieceType::Knight as usize][white] & sq_mask) != 0 {
|
||||
return Some('♘');
|
||||
}
|
||||
if (self.pieces[PieceType::Knight as usize][black] & sq_mask) != 0 {
|
||||
return Some('♞');
|
||||
}
|
||||
if (self.pieces[PieceType::Bishop as usize][white] & sq_mask) != 0 {
|
||||
return Some('♗');
|
||||
}
|
||||
if (self.pieces[PieceType::Bishop as usize][black] & sq_mask) != 0 {
|
||||
return Some('♝');
|
||||
}
|
||||
if (self.pieces[PieceType::Rook as usize][white] & sq_mask) != 0 {
|
||||
return Some('♖');
|
||||
}
|
||||
if (self.pieces[PieceType::Rook as usize][black] & sq_mask) != 0 {
|
||||
return Some('♜');
|
||||
}
|
||||
if (self.pieces[PieceType::Queen as usize][white] & sq_mask) != 0 {
|
||||
return Some('♕');
|
||||
}
|
||||
if (self.pieces[PieceType::Queen as usize][black] & sq_mask) != 0 {
|
||||
return Some('♛');
|
||||
}
|
||||
if (self.pieces[PieceType::King as usize][white] & sq_mask) != 0 {
|
||||
return Some('♔');
|
||||
}
|
||||
if (self.pieces[PieceType::King as usize][black] & sq_mask) != 0 {
|
||||
return Some('♚');
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Prints all internal bitboards for debugging purposes.
|
||||
pub fn pretty_print_internals(&self) {
|
||||
println!("\n========= BOARD INTERNAL BITBOARDS =========");
|
||||
|
|
@ -145,6 +191,85 @@ impl Board {
|
|||
|
||||
impl fmt::Display for MoveList {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", &self.iter().map(|mv| mv.to_algebraic()).collect::<Vec<String>>().join(" "))
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
&self
|
||||
.iter()
|
||||
.map(|mv| mv.to_algebraic())
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Square {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Square::A1 => write!(f, "A1"),
|
||||
Square::B1 => write!(f, "B1"),
|
||||
Square::C1 => write!(f, "C1"),
|
||||
Square::D1 => write!(f, "D1"),
|
||||
Square::E1 => write!(f, "E1"),
|
||||
Square::F1 => write!(f, "F1"),
|
||||
Square::G1 => write!(f, "G1"),
|
||||
Square::H1 => write!(f, "H1"),
|
||||
Square::A2 => write!(f, "A2"),
|
||||
Square::B2 => write!(f, "B2"),
|
||||
Square::C2 => write!(f, "C2"),
|
||||
Square::D2 => write!(f, "D2"),
|
||||
Square::E2 => write!(f, "E2"),
|
||||
Square::F2 => write!(f, "F2"),
|
||||
Square::G2 => write!(f, "G2"),
|
||||
Square::H2 => write!(f, "H2"),
|
||||
Square::A3 => write!(f, "A3"),
|
||||
Square::B3 => write!(f, "B3"),
|
||||
Square::C3 => write!(f, "C3"),
|
||||
Square::D3 => write!(f, "D3"),
|
||||
Square::E3 => write!(f, "E3"),
|
||||
Square::F3 => write!(f, "F3"),
|
||||
Square::G3 => write!(f, "G3"),
|
||||
Square::H3 => write!(f, "H3"),
|
||||
Square::A4 => write!(f, "A4"),
|
||||
Square::B4 => write!(f, "B4"),
|
||||
Square::C4 => write!(f, "C4"),
|
||||
Square::D4 => write!(f, "D4"),
|
||||
Square::E4 => write!(f, "E4"),
|
||||
Square::F4 => write!(f, "F4"),
|
||||
Square::G4 => write!(f, "G4"),
|
||||
Square::H4 => write!(f, "H4"),
|
||||
Square::A5 => write!(f, "A5"),
|
||||
Square::B5 => write!(f, "B5"),
|
||||
Square::C5 => write!(f, "C5"),
|
||||
Square::D5 => write!(f, "D5"),
|
||||
Square::E5 => write!(f, "E5"),
|
||||
Square::F5 => write!(f, "F5"),
|
||||
Square::G5 => write!(f, "G5"),
|
||||
Square::H5 => write!(f, "H5"),
|
||||
Square::A6 => write!(f, "A6"),
|
||||
Square::B6 => write!(f, "B6"),
|
||||
Square::C6 => write!(f, "C6"),
|
||||
Square::D6 => write!(f, "D6"),
|
||||
Square::E6 => write!(f, "E6"),
|
||||
Square::F6 => write!(f, "F6"),
|
||||
Square::G6 => write!(f, "G6"),
|
||||
Square::H6 => write!(f, "H6"),
|
||||
Square::A7 => write!(f, "A7"),
|
||||
Square::B7 => write!(f, "B7"),
|
||||
Square::C7 => write!(f, "C7"),
|
||||
Square::D7 => write!(f, "D7"),
|
||||
Square::E7 => write!(f, "E7"),
|
||||
Square::F7 => write!(f, "F7"),
|
||||
Square::G7 => write!(f, "G7"),
|
||||
Square::H7 => write!(f, "H7"),
|
||||
Square::A8 => write!(f, "A8"),
|
||||
Square::B8 => write!(f, "B8"),
|
||||
Square::C8 => write!(f, "C8"),
|
||||
Square::D8 => write!(f, "D8"),
|
||||
Square::E8 => write!(f, "E8"),
|
||||
Square::F8 => write!(f, "F8"),
|
||||
Square::G8 => write!(f, "G8"),
|
||||
Square::H8 => write!(f, "H8")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
74
src/movegen/legal_check.rs
Normal file
74
src/movegen/legal_check.rs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
use crate::board::{Board, Color, PieceType};
|
||||
use crate::movegen::tables::{get_bishop_attacks, get_rook_attacks, ATTACKING_PAWNS, KING_ATTACKS, KNIGHT_ATTACKS, MAGICS_BISHOP, MAGICS_ROOK, PREMASKS_BISHOP, PREMASKS_ROOK, RELEVANT_BITS_BISHOP, RELEVANT_BITS_ROOK};
|
||||
use crate::square::{Square, SQUARES};
|
||||
|
||||
/// Checks if the king of the side that is NOT to move is in check
|
||||
pub fn is_king_attacked(board: &Board) -> bool {
|
||||
let king = board.pieces[PieceType::King as usize][!board.side_to_move as usize];
|
||||
is_square_attacked(board, SQUARES[king.trailing_zeros() as usize], board.side_to_move)
|
||||
}
|
||||
|
||||
// TODO check if castle is legal (squares in between)
|
||||
|
||||
/// calculate if a square on the board is attacked by a color
|
||||
pub fn is_square_attacked(board: &Board, square: Square, color: Color) -> bool {
|
||||
// 1. Non sliding
|
||||
// 1.1 Pawn
|
||||
let pawns = board.pieces[PieceType::Pawn as usize][color as usize];
|
||||
if (pawns & ATTACKING_PAWNS[color as usize][square as usize]) != 0 {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 1.2 Knight
|
||||
let knights = board.pieces[PieceType::Knight as usize][color as usize];
|
||||
if (knights & KNIGHT_ATTACKS[square as usize]) != 0 {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 1.3 King
|
||||
let king = board.pieces[PieceType::King as usize][color as usize];
|
||||
if (king & KING_ATTACKS[square as usize]) != 0 {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. Sliding
|
||||
let blockers = board.all_occupied;
|
||||
|
||||
// 2.1 Bishop (and part of Queen)
|
||||
let premask_bishop = PREMASKS_BISHOP[square as usize];
|
||||
let magic_bishop = MAGICS_BISHOP[square as usize];
|
||||
let relevant_bits_bishop = RELEVANT_BITS_BISHOP[square as usize];
|
||||
let shift_bishop = 64 - relevant_bits_bishop;
|
||||
let attack_table_bishop = get_bishop_attacks();
|
||||
let magic_index_bishop = ((blockers & premask_bishop).wrapping_mul(magic_bishop)) >> shift_bishop;
|
||||
let bishop_attackable_squares = attack_table_bishop[square as usize][magic_index_bishop as usize];
|
||||
|
||||
let bishops = board.pieces[PieceType::Bishop as usize][color as usize];
|
||||
if (bishop_attackable_squares & bishops) != 0 {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2.2 Rooks (and part of Queen)
|
||||
let premask_rook = PREMASKS_ROOK[square as usize];
|
||||
let magic_rook = MAGICS_ROOK[square as usize];
|
||||
let relevant_bits_rook = RELEVANT_BITS_ROOK[square as usize];
|
||||
let shift_rook = 64 - relevant_bits_rook;
|
||||
let attack_table_rook = get_rook_attacks();
|
||||
let magic_index_rook = ((blockers & premask_rook).wrapping_mul(magic_rook)) >> shift_rook;
|
||||
let rook_attackable_squares = attack_table_rook[square as usize][magic_index_rook as usize];
|
||||
|
||||
let rooks = board.pieces[PieceType::Rook as usize][color as usize];
|
||||
if (rook_attackable_squares & rooks) != 0 {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2.3 Queens
|
||||
let queen_attackable_squares = bishop_attackable_squares | rook_attackable_squares;
|
||||
let queens = board.pieces[PieceType::Queen as usize][color as usize];
|
||||
if (queen_attackable_squares & queens) != 0 {
|
||||
return true;
|
||||
}
|
||||
|
||||
// No attackers found
|
||||
false
|
||||
}
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
use crate::board::Board;
|
||||
use crate::movegen::non_sliders::{generate_king_moves, generate_knight_moves};
|
||||
use crate::movegen::pawns::generate_pawn_moves;
|
||||
use crate::movegen::sliders::{generate_bishop_moves, generate_queen_moves, generate_rook_moves};
|
||||
use crate::r#move::MoveList;
|
||||
|
||||
pub mod non_sliders;
|
||||
pub mod sliders;
|
||||
pub mod pawns;
|
||||
pub mod tables;
|
||||
|
||||
use crate::board::Board;
|
||||
use crate::r#move::*;
|
||||
use non_sliders::*;
|
||||
use sliders::*;
|
||||
use pawns::*;
|
||||
pub mod legal_check;
|
||||
|
||||
pub fn generate_pseudo_legal_moves(board: &Board, list: &mut MoveList) {
|
||||
generate_pawn_moves(board, list);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,141 @@
|
|||
use std::sync::OnceLock;
|
||||
|
||||
|
||||
pub const ATTACKING_PAWNS: [[u64; 64]; 2] = [
|
||||
[ // Color 0: White (Squares a White pawn attacks FROM)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 0 (A1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 1 (B1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 2 (C1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 3 (D1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 4 (E1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 5 (F1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 6 (G1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 7 (H1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000010, // Target Square 8 (A2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000101, // Target Square 9 (B2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00001010, // Target Square 10 (C2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00010100, // Target Square 11 (D2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00101000, // Target Square 12 (E2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_01010000, // Target Square 13 (F2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_10100000, // Target Square 14 (G2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_01000000, // Target Square 15 (H2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000010_00000000, // Target Square 16 (A3)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000101_00000000, // Target Square 17 (B3)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00001010_00000000, // Target Square 18 (C3)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00010100_00000000, // Target Square 19 (D3)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00101000_00000000, // Target Square 20 (E3)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_01010000_00000000, // Target Square 21 (F3)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_10100000_00000000, // Target Square 22 (G3)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_01000000_00000000, // Target Square 23 (H3)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000010_00000000_00000000, // Target Square 24 (A4)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000101_00000000_00000000, // Target Square 25 (B4)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00001010_00000000_00000000, // Target Square 26 (C4)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00010100_00000000_00000000, // Target Square 27 (D4)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00101000_00000000_00000000, // Target Square 28 (E4)
|
||||
0b00000000_00000000_00000000_00000000_00000000_01010000_00000000_00000000, // Target Square 29 (F4)
|
||||
0b00000000_00000000_00000000_00000000_00000000_10100000_00000000_00000000, // Target Square 30 (G4)
|
||||
0b00000000_00000000_00000000_00000000_00000000_01000000_00000000_00000000, // Target Square 31 (H4)
|
||||
0b00000000_00000000_00000000_00000000_00000010_00000000_00000000_00000000, // Target Square 32 (A5)
|
||||
0b00000000_00000000_00000000_00000000_00000101_00000000_00000000_00000000, // Target Square 33 (B5)
|
||||
0b00000000_00000000_00000000_00000000_00001010_00000000_00000000_00000000, // Target Square 34 (C5)
|
||||
0b00000000_00000000_00000000_00000000_00010100_00000000_00000000_00000000, // Target Square 35 (D5)
|
||||
0b00000000_00000000_00000000_00000000_00101000_00000000_00000000_00000000, // Target Square 36 (E5)
|
||||
0b00000000_00000000_00000000_00000000_01010000_00000000_00000000_00000000, // Target Square 37 (F5)
|
||||
0b00000000_00000000_00000000_00000000_10100000_00000000_00000000_00000000, // Target Square 38 (G5)
|
||||
0b00000000_00000000_00000000_00000000_01000000_00000000_00000000_00000000, // Target Square 39 (H5)
|
||||
0b00000000_00000000_00000000_00000010_00000000_00000000_00000000_00000000, // Target Square 40 (A6)
|
||||
0b00000000_00000000_00000000_00000101_00000000_00000000_00000000_00000000, // Target Square 41 (B6)
|
||||
0b00000000_00000000_00000000_00001010_00000000_00000000_00000000_00000000, // Target Square 42 (C6)
|
||||
0b00000000_00000000_00000000_00010100_00000000_00000000_00000000_00000000, // Target Square 43 (D6)
|
||||
0b00000000_00000000_00000000_00101000_00000000_00000000_00000000_00000000, // Target Square 44 (E6)
|
||||
0b00000000_00000000_00000000_01010000_00000000_00000000_00000000_00000000, // Target Square 45 (F6)
|
||||
0b00000000_00000000_00000000_10100000_00000000_00000000_00000000_00000000, // Target Square 46 (G6)
|
||||
0b00000000_00000000_00000000_01000000_00000000_00000000_00000000_00000000, // Target Square 47 (H6)
|
||||
0b00000000_00000000_00000010_00000000_00000000_00000000_00000000_00000000, // Target Square 48 (A7)
|
||||
0b00000000_00000000_00000101_00000000_00000000_00000000_00000000_00000000, // Target Square 49 (B7)
|
||||
0b00000000_00000000_00001010_00000000_00000000_00000000_00000000_00000000, // Target Square 50 (C7)
|
||||
0b00000000_00000000_00010100_00000000_00000000_00000000_00000000_00000000, // Target Square 51 (D7)
|
||||
0b00000000_00000000_00101000_00000000_00000000_00000000_00000000_00000000, // Target Square 52 (E7)
|
||||
0b00000000_00000000_01010000_00000000_00000000_00000000_00000000_00000000, // Target Square 53 (F7)
|
||||
0b00000000_00000000_10100000_00000000_00000000_00000000_00000000_00000000, // Target Square 54 (G7)
|
||||
0b00000000_00000000_01000000_00000000_00000000_00000000_00000000_00000000, // Target Square 55 (H7)
|
||||
0b00000000_00000010_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 56 (A8)
|
||||
0b00000000_00000101_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 57 (B8)
|
||||
0b00000000_00001010_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 58 (C8)
|
||||
0b00000000_00010100_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 59 (D8)
|
||||
0b00000000_00101000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 60 (E8)
|
||||
0b00000000_01010000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 61 (F8)
|
||||
0b00000000_10100000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 62 (G8)
|
||||
0b00000000_01000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 63 (H8)
|
||||
],
|
||||
[ // Color 1: Black (Squares a Black pawn attacks FROM)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000010_00000000, // Target Square 0 (A1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000101_00000000, // Target Square 1 (B1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00001010_00000000, // Target Square 2 (C1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00010100_00000000, // Target Square 3 (D1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00101000_00000000, // Target Square 4 (E1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_01010000_00000000, // Target Square 5 (F1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_10100000_00000000, // Target Square 6 (G1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_01000000_00000000, // Target Square 7 (H1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000010_00000000_00000000, // Target Square 8 (A2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000101_00000000_00000000, // Target Square 9 (B2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00001010_00000000_00000000, // Target Square 10 (C2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00010100_00000000_00000000, // Target Square 11 (D2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00101000_00000000_00000000, // Target Square 12 (E2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_01010000_00000000_00000000, // Target Square 13 (F2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_10100000_00000000_00000000, // Target Square 14 (G2)
|
||||
0b00000000_00000000_00000000_00000000_00000000_01000000_00000000_00000000, // Target Square 15 (H2)
|
||||
0b00000000_00000000_00000000_00000000_00000010_00000000_00000000_00000000, // Target Square 16 (A3)
|
||||
0b00000000_00000000_00000000_00000000_00000101_00000000_00000000_00000000, // Target Square 17 (B3)
|
||||
0b00000000_00000000_00000000_00000000_00001010_00000000_00000000_00000000, // Target Square 18 (C3)
|
||||
0b00000000_00000000_00000000_00000000_00010100_00000000_00000000_00000000, // Target Square 19 (D3)
|
||||
0b00000000_00000000_00000000_00000000_00101000_00000000_00000000_00000000, // Target Square 20 (E3)
|
||||
0b00000000_00000000_00000000_00000000_01010000_00000000_00000000_00000000, // Target Square 21 (F3)
|
||||
0b00000000_00000000_00000000_00000000_10100000_00000000_00000000_00000000, // Target Square 22 (G3)
|
||||
0b00000000_00000000_00000000_00000000_01000000_00000000_00000000_00000000, // Target Square 23 (H3)
|
||||
0b00000000_00000000_00000000_00000010_00000000_00000000_00000000_00000000, // Target Square 24 (A4)
|
||||
0b00000000_00000000_00000000_00000101_00000000_00000000_00000000_00000000, // Target Square 25 (B4)
|
||||
0b00000000_00000000_00000000_00001010_00000000_00000000_00000000_00000000, // Target Square 26 (C4)
|
||||
0b00000000_00000000_00000000_00010100_00000000_00000000_00000000_00000000, // Target Square 27 (D4)
|
||||
0b00000000_00000000_00000000_00101000_00000000_00000000_00000000_00000000, // Target Square 28 (E4)
|
||||
0b00000000_00000000_00000000_01010000_00000000_00000000_00000000_00000000, // Target Square 29 (F4)
|
||||
0b00000000_00000000_00000000_10100000_00000000_00000000_00000000_00000000, // Target Square 30 (G4)
|
||||
0b00000000_00000000_00000000_01000000_00000000_00000000_00000000_00000000, // Target Square 31 (H4)
|
||||
0b00000000_00000000_00000010_00000000_00000000_00000000_00000000_00000000, // Target Square 32 (A5)
|
||||
0b00000000_00000000_00000101_00000000_00000000_00000000_00000000_00000000, // Target Square 33 (B5)
|
||||
0b00000000_00000000_00001010_00000000_00000000_00000000_00000000_00000000, // Target Square 34 (C5)
|
||||
0b00000000_00000000_00010100_00000000_00000000_00000000_00000000_00000000, // Target Square 35 (D5)
|
||||
0b00000000_00000000_00101000_00000000_00000000_00000000_00000000_00000000, // Target Square 36 (E5)
|
||||
0b00000000_00000000_01010000_00000000_00000000_00000000_00000000_00000000, // Target Square 37 (F5)
|
||||
0b00000000_00000000_10100000_00000000_00000000_00000000_00000000_00000000, // Target Square 38 (G5)
|
||||
0b00000000_00000000_01000000_00000000_00000000_00000000_00000000_00000000, // Target Square 39 (H5)
|
||||
0b00000000_00000010_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 40 (A6)
|
||||
0b00000000_00000101_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 41 (B6)
|
||||
0b00000000_00001010_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 42 (C6)
|
||||
0b00000000_00010100_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 43 (D6)
|
||||
0b00000000_00101000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 44 (E6)
|
||||
0b00000000_01010000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 45 (F6)
|
||||
0b00000000_10100000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 46 (G6)
|
||||
0b00000000_01000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 47 (H6)
|
||||
0b00000010_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 48 (A7)
|
||||
0b00000101_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 49 (B7)
|
||||
0b00001010_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 50 (C7)
|
||||
0b00010100_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 51 (D7)
|
||||
0b00101000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 52 (E7)
|
||||
0b01010000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 53 (F7)
|
||||
0b10100000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 54 (G7)
|
||||
0b01000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 55 (H7)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 56 (A8)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 57 (B8)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 58 (C8)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 59 (D8)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 60 (E8)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 61 (F8)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 62 (G8)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, // Target Square 63 (H8)
|
||||
]
|
||||
];
|
||||
|
||||
pub const KNIGHT_ATTACKS: [u64; 64] = [
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000010_00000100_00000000, // Square 0 (A1)
|
||||
0b00000000_00000000_00000000_00000000_00000000_00000101_00001000_00000000, // Square 1 (B1)
|
||||
|
|
|
|||
27
tests/is_square_attacked.rs
Normal file
27
tests/is_square_attacked.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use chess_engine::board::{Board, Color};
|
||||
use chess_engine::movegen::legal_check::is_square_attacked;
|
||||
use chess_engine::square::Square;
|
||||
|
||||
|
||||
fn assert_square_attacked(board: &mut Board, square: Square, white: bool, black: bool) {
|
||||
assert_eq!(is_square_attacked(board, square, Color::White), white, "{}", square);
|
||||
assert_eq!(is_square_attacked(board, square, Color::Black), black, "{}", square);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_attacked_kiwipete() {
|
||||
let mut board = Board::from_fen("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1");
|
||||
assert_square_attacked(&mut board, Square::B1, true, false);
|
||||
assert_square_attacked(&mut board, Square::C1, true, false);
|
||||
assert_square_attacked(&mut board, Square::D1, true, false);
|
||||
assert_square_attacked(&mut board, Square::F1, true, false);
|
||||
assert_square_attacked(&mut board, Square::G1, true, false);
|
||||
|
||||
assert_square_attacked(&mut board, Square::A3, true, true);
|
||||
assert_square_attacked(&mut board, Square::B3, true, false);
|
||||
assert_square_attacked(&mut board, Square::D3, true, true);
|
||||
assert_square_attacked(&mut board, Square::E3, true, false);
|
||||
assert_square_attacked(&mut board, Square::G3, true, false);
|
||||
|
||||
// TODO keep going with the rest
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue