Rename Kind to PieceType for clarity
This commit is contained in:
@@ -316,31 +316,31 @@ pub fn init_attacks() {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::board::{Color, Kind, Piece};
|
use crate::board::{Color, Piece, PieceType};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_pawn_attacks() -> Result<(), String> {
|
fn test_pawn_attacks() -> Result<(), String> {
|
||||||
let white_pawn_a_file = Piece::new(0x100, Kind::Pawn, Color::White);
|
let white_pawn_a_file = Piece::new(0x100, PieceType::Pawn, Color::White);
|
||||||
let attacks = pawn_attacks(white_pawn_a_file.bitboard, white_pawn_a_file.color);
|
let attacks = pawn_attacks(white_pawn_a_file.bitboard, white_pawn_a_file.color);
|
||||||
assert_eq!(attacks, 0x20000);
|
assert_eq!(attacks, 0x20000);
|
||||||
|
|
||||||
let white_pawn_b_file = Piece::new(0x200, Kind::Pawn, Color::White);
|
let white_pawn_b_file = Piece::new(0x200, PieceType::Pawn, Color::White);
|
||||||
let attacks = pawn_attacks(white_pawn_b_file.bitboard, white_pawn_b_file.color);
|
let attacks = pawn_attacks(white_pawn_b_file.bitboard, white_pawn_b_file.color);
|
||||||
assert_eq!(attacks, 0x50000);
|
assert_eq!(attacks, 0x50000);
|
||||||
|
|
||||||
let white_pawn_h_file = Piece::new(0x8000, Kind::Pawn, Color::White);
|
let white_pawn_h_file = Piece::new(0x8000, PieceType::Pawn, Color::White);
|
||||||
let attacks = pawn_attacks(white_pawn_h_file.bitboard, white_pawn_h_file.color);
|
let attacks = pawn_attacks(white_pawn_h_file.bitboard, white_pawn_h_file.color);
|
||||||
assert_eq!(attacks, 0x400000);
|
assert_eq!(attacks, 0x400000);
|
||||||
|
|
||||||
let black_pawn_a_file = Piece::new(0x1000000000000, Kind::Pawn, Color::Black);
|
let black_pawn_a_file = Piece::new(0x1000000000000, PieceType::Pawn, Color::Black);
|
||||||
let attacks = pawn_attacks(black_pawn_a_file.bitboard, black_pawn_a_file.color);
|
let attacks = pawn_attacks(black_pawn_a_file.bitboard, black_pawn_a_file.color);
|
||||||
assert_eq!(attacks, 0x20000000000);
|
assert_eq!(attacks, 0x20000000000);
|
||||||
|
|
||||||
let black_pawn_b_file = Piece::new(0x2000000000000, Kind::Pawn, Color::Black);
|
let black_pawn_b_file = Piece::new(0x2000000000000, PieceType::Pawn, Color::Black);
|
||||||
let attacks = pawn_attacks(black_pawn_b_file.bitboard, black_pawn_b_file.color);
|
let attacks = pawn_attacks(black_pawn_b_file.bitboard, black_pawn_b_file.color);
|
||||||
assert_eq!(attacks, 0x50000000000);
|
assert_eq!(attacks, 0x50000000000);
|
||||||
|
|
||||||
let black_pawn_h_file = Piece::new(0x80000000000000, Kind::Pawn, Color::Black);
|
let black_pawn_h_file = Piece::new(0x80000000000000, PieceType::Pawn, Color::Black);
|
||||||
let attacks = pawn_attacks(black_pawn_h_file.bitboard, black_pawn_h_file.color);
|
let attacks = pawn_attacks(black_pawn_h_file.bitboard, black_pawn_h_file.color);
|
||||||
assert_eq!(attacks, 0x400000000000);
|
assert_eq!(attacks, 0x400000000000);
|
||||||
|
|
||||||
@@ -349,23 +349,23 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_knight_attacks() -> Result<(), String> {
|
fn test_knight_attacks() -> Result<(), String> {
|
||||||
let knight_two_attacks = Piece::new(0x1, Kind::Knight, Color::White);
|
let knight_two_attacks = Piece::new(0x1, PieceType::Knight, Color::White);
|
||||||
let attacks = knight_attacks(knight_two_attacks.bitboard);
|
let attacks = knight_attacks(knight_two_attacks.bitboard);
|
||||||
assert_eq!(attacks, 0x20400);
|
assert_eq!(attacks, 0x20400);
|
||||||
|
|
||||||
let knight_three_attacks = Piece::new(0x2, Kind::Knight, Color::White);
|
let knight_three_attacks = Piece::new(0x2, PieceType::Knight, Color::White);
|
||||||
let attacks = knight_attacks(knight_three_attacks.bitboard);
|
let attacks = knight_attacks(knight_three_attacks.bitboard);
|
||||||
assert_eq!(attacks, 0x50800);
|
assert_eq!(attacks, 0x50800);
|
||||||
|
|
||||||
let knight_three_attacks = Piece::new(0x4, Kind::Knight, Color::White);
|
let knight_three_attacks = Piece::new(0x4, PieceType::Knight, Color::White);
|
||||||
let attacks = knight_attacks(knight_three_attacks.bitboard);
|
let attacks = knight_attacks(knight_three_attacks.bitboard);
|
||||||
assert_eq!(attacks, 0xa1100);
|
assert_eq!(attacks, 0xa1100);
|
||||||
|
|
||||||
let knight_six_attacks = Piece::new(0x400, Kind::Knight, Color::White);
|
let knight_six_attacks = Piece::new(0x400, PieceType::Knight, Color::White);
|
||||||
let attacks = knight_attacks(knight_six_attacks.bitboard);
|
let attacks = knight_attacks(knight_six_attacks.bitboard);
|
||||||
assert_eq!(attacks, 0xa110011);
|
assert_eq!(attacks, 0xa110011);
|
||||||
|
|
||||||
let knight_eight_attacks = Piece::new(0x40000, Kind::Knight, Color::White);
|
let knight_eight_attacks = Piece::new(0x40000, PieceType::Knight, Color::White);
|
||||||
let attacks = knight_attacks(knight_eight_attacks.bitboard);
|
let attacks = knight_attacks(knight_eight_attacks.bitboard);
|
||||||
assert_eq!(attacks, 0xa1100110a);
|
assert_eq!(attacks, 0xa1100110a);
|
||||||
|
|
||||||
@@ -374,15 +374,15 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_king_attacks() -> Result<(), String> {
|
fn test_king_attacks() -> Result<(), String> {
|
||||||
let king_three_attacks = Piece::new(0x1, Kind::King, Color::White);
|
let king_three_attacks = Piece::new(0x1, PieceType::King, Color::White);
|
||||||
let attacks = king_attacks(king_three_attacks.bitboard);
|
let attacks = king_attacks(king_three_attacks.bitboard);
|
||||||
assert_eq!(attacks, 0x302);
|
assert_eq!(attacks, 0x302);
|
||||||
|
|
||||||
let king_five_attacks = Piece::new(0x2, Kind::King, Color::White);
|
let king_five_attacks = Piece::new(0x2, PieceType::King, Color::White);
|
||||||
let attacks = king_attacks(king_five_attacks.bitboard);
|
let attacks = king_attacks(king_five_attacks.bitboard);
|
||||||
assert_eq!(attacks, 0x705);
|
assert_eq!(attacks, 0x705);
|
||||||
|
|
||||||
let king_eight_attacks = Piece::new(0x200, Kind::King, Color::White);
|
let king_eight_attacks = Piece::new(0x200, PieceType::King, Color::White);
|
||||||
let attacks = king_attacks(king_eight_attacks.bitboard);
|
let attacks = king_attacks(king_eight_attacks.bitboard);
|
||||||
assert_eq!(attacks, 0x70507);
|
assert_eq!(attacks, 0x70507);
|
||||||
|
|
||||||
@@ -391,7 +391,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mask_bishop_attacks() -> Result<(), String> {
|
fn test_mask_bishop_attacks() -> Result<(), String> {
|
||||||
let bishop_d4 = Piece::new(0x8000000, Kind::Bishop, Color::White);
|
let bishop_d4 = Piece::new(0x8000000, PieceType::Bishop, Color::White);
|
||||||
let all_directions_mask = mask_bishop_attacks(bishop_d4.bitboard);
|
let all_directions_mask = mask_bishop_attacks(bishop_d4.bitboard);
|
||||||
assert_eq!(all_directions_mask, 0x40221400142200);
|
assert_eq!(all_directions_mask, 0x40221400142200);
|
||||||
|
|
||||||
@@ -400,12 +400,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bishop_attacks_on_the_fly() -> Result<(), String> {
|
fn test_bishop_attacks_on_the_fly() -> Result<(), String> {
|
||||||
let bishop_d4 = Piece::new(0x8000000, Kind::Bishop, Color::White);
|
let bishop_d4 = Piece::new(0x8000000, PieceType::Bishop, Color::White);
|
||||||
let blocker_c5 = 0x400000000_u64;
|
let blocker_c5 = 0x400000000_u64;
|
||||||
let attacks = bishop_attacks_on_the_fly(bishop_d4.bitboard, blocker_c5);
|
let attacks = bishop_attacks_on_the_fly(bishop_d4.bitboard, blocker_c5);
|
||||||
assert_eq!(attacks, 0x8040201400142241);
|
assert_eq!(attacks, 0x8040201400142241);
|
||||||
|
|
||||||
let bishop_a1 = Piece::new(0x0, Kind::Bishop, Color::White);
|
let bishop_a1 = Piece::new(0x0, PieceType::Bishop, Color::White);
|
||||||
let blocker_none = 0x0_u64;
|
let blocker_none = 0x0_u64;
|
||||||
let attacks = bishop_attacks_on_the_fly(bishop_a1.bitboard, blocker_none);
|
let attacks = bishop_attacks_on_the_fly(bishop_a1.bitboard, blocker_none);
|
||||||
assert_eq!(attacks, 0x8040201008040200);
|
assert_eq!(attacks, 0x8040201008040200);
|
||||||
@@ -415,7 +415,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mask_rook_attacks() -> Result<(), String> {
|
fn test_mask_rook_attacks() -> Result<(), String> {
|
||||||
let rook_d4 = Piece::new(0x8000000, Kind::Rook, Color::White);
|
let rook_d4 = Piece::new(0x8000000, PieceType::Rook, Color::White);
|
||||||
let all_directions_mask = mask_rook_attacks(rook_d4.bitboard);
|
let all_directions_mask = mask_rook_attacks(rook_d4.bitboard);
|
||||||
assert_eq!(all_directions_mask, 0x8080876080800);
|
assert_eq!(all_directions_mask, 0x8080876080800);
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rook_attacks_on_the_fly() -> Result<(), String> {
|
fn test_rook_attacks_on_the_fly() -> Result<(), String> {
|
||||||
let rook_d4 = Piece::new(0x8000000, Kind::Rook, Color::White);
|
let rook_d4 = Piece::new(0x8000000, PieceType::Rook, Color::White);
|
||||||
let blocker_c4 = 0x4000000_u64;
|
let blocker_c4 = 0x4000000_u64;
|
||||||
let attacks = rook_attacks_on_the_fly(rook_d4.bitboard, blocker_c4);
|
let attacks = rook_attacks_on_the_fly(rook_d4.bitboard, blocker_c4);
|
||||||
assert_eq!(attacks, 0x8080808f4080808);
|
assert_eq!(attacks, 0x8080808f4080808);
|
||||||
|
|||||||
127
src/board.rs
127
src/board.rs
@@ -23,20 +23,20 @@ impl Board {
|
|||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
white_pieces: [
|
white_pieces: [
|
||||||
Piece::new(0xff00, Kind::Pawn, Color::White),
|
Piece::new(0xff00, PieceType::Pawn, Color::White),
|
||||||
Piece::new(0x42, Kind::Knight, Color::White),
|
Piece::new(0x42, PieceType::Knight, Color::White),
|
||||||
Piece::new(0x24, Kind::Bishop, Color::White),
|
Piece::new(0x24, PieceType::Bishop, Color::White),
|
||||||
Piece::new(0x81, Kind::Rook, Color::White),
|
Piece::new(0x81, PieceType::Rook, Color::White),
|
||||||
Piece::new(0x8, Kind::Queen, Color::White),
|
Piece::new(0x8, PieceType::Queen, Color::White),
|
||||||
Piece::new(0x10, Kind::King, Color::White),
|
Piece::new(0x10, PieceType::King, Color::White),
|
||||||
],
|
],
|
||||||
black_pieces: [
|
black_pieces: [
|
||||||
Piece::new(0xff000000000000, Kind::Pawn, Color::Black),
|
Piece::new(0xff000000000000, PieceType::Pawn, Color::Black),
|
||||||
Piece::new(0x4200000000000000, Kind::Knight, Color::Black),
|
Piece::new(0x4200000000000000, PieceType::Knight, Color::Black),
|
||||||
Piece::new(0x2400000000000000, Kind::Bishop, Color::Black),
|
Piece::new(0x2400000000000000, PieceType::Bishop, Color::Black),
|
||||||
Piece::new(0x8100000000000000, Kind::Rook, Color::Black),
|
Piece::new(0x8100000000000000, PieceType::Rook, Color::Black),
|
||||||
Piece::new(0x800000000000000, Kind::Queen, Color::Black),
|
Piece::new(0x800000000000000, PieceType::Queen, Color::Black),
|
||||||
Piece::new(0x1000000000000000, Kind::King, Color::Black),
|
Piece::new(0x1000000000000000, PieceType::King, Color::Black),
|
||||||
],
|
],
|
||||||
state: State::new(),
|
state: State::new(),
|
||||||
}
|
}
|
||||||
@@ -45,20 +45,20 @@ impl Board {
|
|||||||
pub const fn empty_board() -> Self {
|
pub const fn empty_board() -> Self {
|
||||||
Self {
|
Self {
|
||||||
white_pieces: [
|
white_pieces: [
|
||||||
Piece::new(0x0, Kind::Pawn, Color::White),
|
Piece::new(0x0, PieceType::Pawn, Color::White),
|
||||||
Piece::new(0x0, Kind::Knight, Color::White),
|
Piece::new(0x0, PieceType::Knight, Color::White),
|
||||||
Piece::new(0x0, Kind::Bishop, Color::White),
|
Piece::new(0x0, PieceType::Bishop, Color::White),
|
||||||
Piece::new(0x0, Kind::Rook, Color::White),
|
Piece::new(0x0, PieceType::Rook, Color::White),
|
||||||
Piece::new(0x0, Kind::Queen, Color::White),
|
Piece::new(0x0, PieceType::Queen, Color::White),
|
||||||
Piece::new(0x0, Kind::King, Color::White),
|
Piece::new(0x0, PieceType::King, Color::White),
|
||||||
],
|
],
|
||||||
black_pieces: [
|
black_pieces: [
|
||||||
Piece::new(0x0, Kind::Pawn, Color::Black),
|
Piece::new(0x0, PieceType::Pawn, Color::Black),
|
||||||
Piece::new(0x0, Kind::Knight, Color::Black),
|
Piece::new(0x0, PieceType::Knight, Color::Black),
|
||||||
Piece::new(0x0, Kind::Bishop, Color::Black),
|
Piece::new(0x0, PieceType::Bishop, Color::Black),
|
||||||
Piece::new(0x0, Kind::Rook, Color::Black),
|
Piece::new(0x0, PieceType::Rook, Color::Black),
|
||||||
Piece::new(0x0, Kind::Queen, Color::Black),
|
Piece::new(0x0, PieceType::Queen, Color::Black),
|
||||||
Piece::new(0x0, Kind::King, Color::Black),
|
Piece::new(0x0, PieceType::King, Color::Black),
|
||||||
],
|
],
|
||||||
state: State::new(),
|
state: State::new(),
|
||||||
}
|
}
|
||||||
@@ -84,27 +84,30 @@ impl Board {
|
|||||||
};
|
};
|
||||||
|
|
||||||
have_common_bit(
|
have_common_bit(
|
||||||
opponent[Kind::Pawn].bitboard,
|
opponent[PieceType::Pawn].bitboard,
|
||||||
fetch_pawn_attacks(square, own_color),
|
fetch_pawn_attacks(square, own_color),
|
||||||
) || have_common_bit(
|
) || have_common_bit(
|
||||||
opponent[Kind::Knight].bitboard,
|
opponent[PieceType::Knight].bitboard,
|
||||||
fetch_knight_attacks(square),
|
fetch_knight_attacks(square),
|
||||||
) || have_common_bit(
|
) || have_common_bit(
|
||||||
opponent[Kind::Bishop].bitboard,
|
opponent[PieceType::Bishop].bitboard,
|
||||||
fetch_bishop_attacks(all_occupancies, square),
|
fetch_bishop_attacks(all_occupancies, square),
|
||||||
) || have_common_bit(
|
) || have_common_bit(
|
||||||
opponent[Kind::Rook].bitboard,
|
opponent[PieceType::Rook].bitboard,
|
||||||
fetch_rook_attacks(all_occupancies, square),
|
fetch_rook_attacks(all_occupancies, square),
|
||||||
) || have_common_bit(
|
) || have_common_bit(
|
||||||
opponent[Kind::Queen].bitboard,
|
opponent[PieceType::Queen].bitboard,
|
||||||
fetch_queen_attacks(all_occupancies, square),
|
fetch_queen_attacks(all_occupancies, square),
|
||||||
) || have_common_bit(opponent[Kind::King].bitboard, fetch_king_attacks(square))
|
) || have_common_bit(
|
||||||
|
opponent[PieceType::King].bitboard,
|
||||||
|
fetch_king_attacks(square),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn king_under_check(&self, color: Color) -> bool {
|
pub fn king_under_check(&self, color: Color) -> bool {
|
||||||
let own_king_square = match color {
|
let own_king_square = match color {
|
||||||
Color::White => lsb(self.white_pieces[Kind::King].bitboard),
|
Color::White => lsb(self.white_pieces[PieceType::King].bitboard),
|
||||||
Color::Black => lsb(self.black_pieces[Kind::King].bitboard),
|
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_color(color))
|
||||||
@@ -112,50 +115,52 @@ impl Board {
|
|||||||
|
|
||||||
pub fn pseudo_moves_all(&self, color: Color) -> Vec<Move> {
|
pub fn pseudo_moves_all(&self, color: Color) -> Vec<Move> {
|
||||||
let mut moves = vec![];
|
let mut moves = vec![];
|
||||||
moves.extend(self.pseudo_moves(color, Kind::Pawn));
|
moves.extend(self.pseudo_moves(color, PieceType::Pawn));
|
||||||
moves.extend(self.pseudo_moves(color, Kind::Knight));
|
moves.extend(self.pseudo_moves(color, PieceType::Knight));
|
||||||
moves.extend(self.pseudo_moves(color, Kind::Bishop));
|
moves.extend(self.pseudo_moves(color, PieceType::Bishop));
|
||||||
moves.extend(self.pseudo_moves(color, Kind::Rook));
|
moves.extend(self.pseudo_moves(color, PieceType::Rook));
|
||||||
moves.extend(self.pseudo_moves(color, Kind::Queen));
|
moves.extend(self.pseudo_moves(color, PieceType::Queen));
|
||||||
moves.extend(self.pseudo_moves(color, Kind::King));
|
moves.extend(self.pseudo_moves(color, PieceType::King));
|
||||||
moves
|
moves
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pseudo_moves(&self, color: Color, kind: Kind) -> Vec<Move> {
|
pub fn pseudo_moves(&self, color: Color, piece_type: PieceType) -> Vec<Move> {
|
||||||
let all_occupancies = self.all_occupancies();
|
let all_occupancies = self.all_occupancies();
|
||||||
let (pieces, opponent_occupancies, own_occupancies) = match color {
|
let (pieces, opponent_occupancies, own_occupancies) = match color {
|
||||||
Color::White => (
|
Color::White => (
|
||||||
self.white_pieces[kind].bitboard,
|
self.white_pieces[piece_type].bitboard,
|
||||||
self.black_occupancies(),
|
self.black_occupancies(),
|
||||||
self.white_occupancies(),
|
self.white_occupancies(),
|
||||||
),
|
),
|
||||||
Color::Black => (
|
Color::Black => (
|
||||||
self.black_pieces[kind].bitboard,
|
self.black_pieces[piece_type].bitboard,
|
||||||
self.white_occupancies(),
|
self.white_occupancies(),
|
||||||
self.black_occupancies(),
|
self.black_occupancies(),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
match kind {
|
match piece_type {
|
||||||
Kind::Pawn => pawn_pseudo_moves(
|
PieceType::Pawn => pawn_pseudo_moves(
|
||||||
pieces,
|
pieces,
|
||||||
all_occupancies,
|
all_occupancies,
|
||||||
opponent_occupancies,
|
opponent_occupancies,
|
||||||
self.state.en_passant_target_square(),
|
self.state.en_passant_target_square(),
|
||||||
color,
|
color,
|
||||||
),
|
),
|
||||||
Kind::Knight => knight_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
PieceType::Knight => knight_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
||||||
Kind::Bishop => bishop_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
PieceType::Bishop => bishop_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
||||||
Kind::Rook => rook_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
PieceType::Rook => rook_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
||||||
Kind::Queen => queen_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
PieceType::Queen => queen_pseudo_moves(pieces, all_occupancies, own_occupancies),
|
||||||
Kind::King => king_pseudo_moves(pieces, all_occupancies, own_occupancies, self, color),
|
PieceType::King => {
|
||||||
|
king_pseudo_moves(pieces, all_occupancies, own_occupancies, self, color)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_piece(&mut self, piece: Piece) {
|
pub fn set_piece(&mut self, piece: Piece) {
|
||||||
match piece.color {
|
match piece.color {
|
||||||
Color::Black => self.black_pieces[piece.kind].bitboard |= piece.bitboard,
|
Color::Black => self.black_pieces[piece.piece_type].bitboard |= piece.bitboard,
|
||||||
Color::White => self.white_pieces[piece.kind].bitboard |= piece.bitboard,
|
Color::White => self.white_pieces[piece.piece_type].bitboard |= piece.bitboard,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,22 +178,22 @@ impl Default for Board {
|
|||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct Piece {
|
pub struct Piece {
|
||||||
pub bitboard: Bitboard,
|
pub bitboard: Bitboard,
|
||||||
pub kind: Kind,
|
pub piece_type: PieceType,
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Piece {
|
impl Piece {
|
||||||
pub const fn new(bitboard: Bitboard, kind: Kind, color: Color) -> Self {
|
pub const fn new(bitboard: Bitboard, piece_type: PieceType, color: Color) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bitboard,
|
bitboard,
|
||||||
kind,
|
piece_type,
|
||||||
color,
|
color,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum Kind {
|
pub enum PieceType {
|
||||||
Pawn,
|
Pawn,
|
||||||
Knight,
|
Knight,
|
||||||
Bishop,
|
Bishop,
|
||||||
@@ -197,7 +202,7 @@ pub enum Kind {
|
|||||||
King,
|
King,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Kind {
|
impl PieceType {
|
||||||
const fn idx(&self) -> usize {
|
const fn idx(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
Self::Pawn => 0,
|
Self::Pawn => 0,
|
||||||
@@ -211,17 +216,17 @@ impl Kind {
|
|||||||
}
|
}
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
impl Index<Kind> for [Piece] {
|
impl Index<PieceType> for [Piece] {
|
||||||
type Output = Piece;
|
type Output = Piece;
|
||||||
|
|
||||||
fn index(&self, kind: Kind) -> &Self::Output {
|
fn index(&self, piece_type: PieceType) -> &Self::Output {
|
||||||
&self[kind.idx()]
|
&self[piece_type.idx()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndexMut<Kind> for [Piece] {
|
impl IndexMut<PieceType> for [Piece] {
|
||||||
fn index_mut(&mut self, kind: Kind) -> &mut Self::Output {
|
fn index_mut(&mut self, piece_type: PieceType) -> &mut Self::Output {
|
||||||
&mut self[kind.idx()]
|
&mut self[piece_type.idx()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,18 +2,18 @@ use u64 as Bitboard;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bitboard::lsb,
|
bitboard::lsb,
|
||||||
board::{Board, Color, Kind},
|
board::{Board, Color, PieceType},
|
||||||
psqt::{mirror_index, piece_square_score},
|
psqt::{mirror_index, piece_square_score},
|
||||||
};
|
};
|
||||||
|
|
||||||
const fn piece_score(kind: Kind) -> i32 {
|
const fn piece_score(piece_type: PieceType) -> i32 {
|
||||||
match kind {
|
match piece_type {
|
||||||
Kind::Pawn => 100,
|
PieceType::Pawn => 100,
|
||||||
Kind::Knight => 320,
|
PieceType::Knight => 320,
|
||||||
Kind::Bishop => 330,
|
PieceType::Bishop => 330,
|
||||||
Kind::Rook => 500,
|
PieceType::Rook => 500,
|
||||||
Kind::Queen => 900,
|
PieceType::Queen => 900,
|
||||||
Kind::King => 20000,
|
PieceType::King => 20000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ fn evaluate_side(board: &Board, color: Color) -> i32 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for piece in pieces {
|
for piece in pieces {
|
||||||
let (kind, mut bitboard): (Kind, Bitboard) = (piece.kind, piece.bitboard);
|
let (piece_type, mut bitboard): (PieceType, Bitboard) = (piece.piece_type, piece.bitboard);
|
||||||
let mut score = 0;
|
let mut score = 0;
|
||||||
while bitboard != 0 {
|
while bitboard != 0 {
|
||||||
let psqt_index = match color {
|
let psqt_index = match color {
|
||||||
@@ -33,8 +33,8 @@ fn evaluate_side(board: &Board, color: Color) -> i32 {
|
|||||||
Color::Black => mirror_index(lsb(bitboard)),
|
Color::Black => mirror_index(lsb(bitboard)),
|
||||||
};
|
};
|
||||||
|
|
||||||
score += piece_score(kind);
|
score += piece_score(piece_type);
|
||||||
score += piece_square_score(kind, psqt_index);
|
score += piece_square_score(piece_type, psqt_index);
|
||||||
bitboard &= bitboard - 1;
|
bitboard &= bitboard - 1;
|
||||||
}
|
}
|
||||||
total_score += score;
|
total_score += score;
|
||||||
@@ -56,7 +56,7 @@ pub fn evaluate_position(board: &Board, color: Color) -> i32 {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
board::{Color, Kind},
|
board::{Color, PieceType},
|
||||||
evaluation::{evaluate_position, evaluate_side, piece_score},
|
evaluation::{evaluate_position, evaluate_side, piece_score},
|
||||||
fen::from_fen,
|
fen::from_fen,
|
||||||
};
|
};
|
||||||
@@ -68,12 +68,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_piece_score() -> Result<(), String> {
|
fn test_piece_score() -> Result<(), String> {
|
||||||
assert_eq!(100, piece_score(Kind::Pawn));
|
assert_eq!(100, piece_score(PieceType::Pawn));
|
||||||
assert_eq!(320, piece_score(Kind::Knight));
|
assert_eq!(320, piece_score(PieceType::Knight));
|
||||||
assert_eq!(330, piece_score(Kind::Bishop));
|
assert_eq!(330, piece_score(PieceType::Bishop));
|
||||||
assert_eq!(500, piece_score(Kind::Rook));
|
assert_eq!(500, piece_score(PieceType::Rook));
|
||||||
assert_eq!(900, piece_score(Kind::Queen));
|
assert_eq!(900, piece_score(PieceType::Queen));
|
||||||
assert_eq!(20000, piece_score(Kind::King));
|
assert_eq!(20000, piece_score(PieceType::King));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/fen.rs
18
src/fen.rs
@@ -1,4 +1,4 @@
|
|||||||
use crate::board::{Board, Color, Kind, Piece};
|
use crate::board::{Board, Color, Piece, PieceType};
|
||||||
use crate::game::Game;
|
use crate::game::Game;
|
||||||
use crate::state::{Castle, State};
|
use crate::state::{Castle, State};
|
||||||
use String as FenError;
|
use String as FenError;
|
||||||
@@ -40,13 +40,13 @@ pub fn piece_placement(pieces: &str) -> Result<Board, FenError> {
|
|||||||
Color::White
|
Color::White
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(kind) = match c.to_ascii_lowercase() {
|
if let Some(piece_type) = match c.to_ascii_lowercase() {
|
||||||
'r' => Some(Kind::Rook),
|
'r' => Some(PieceType::Rook),
|
||||||
'n' => Some(Kind::Knight),
|
'n' => Some(PieceType::Knight),
|
||||||
'b' => Some(Kind::Bishop),
|
'b' => Some(PieceType::Bishop),
|
||||||
'q' => Some(Kind::Queen),
|
'q' => Some(PieceType::Queen),
|
||||||
'k' => Some(Kind::King),
|
'k' => Some(PieceType::King),
|
||||||
'p' => Some(Kind::Pawn),
|
'p' => Some(PieceType::Pawn),
|
||||||
'/' => {
|
'/' => {
|
||||||
file = 0;
|
file = 0;
|
||||||
rank = rank.saturating_sub(1);
|
rank = rank.saturating_sub(1);
|
||||||
@@ -62,7 +62,7 @@ pub fn piece_placement(pieces: &str) -> Result<Board, FenError> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
} {
|
} {
|
||||||
board.set_piece(Piece::new(1 << square, kind, color));
|
board.set_piece(Piece::new(1 << square, piece_type, color));
|
||||||
file += 1;
|
file += 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/move.rs
14
src/move.rs
@@ -2,7 +2,7 @@ use core::fmt;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bitboard::{have_common_bit, square_to_bitboard},
|
bitboard::{have_common_bit, square_to_bitboard},
|
||||||
board::{Board, Color, Kind, Piece},
|
board::{Board, Color, Piece, PieceType},
|
||||||
square::{coords_to_square, square_to_algebraic, Square},
|
square::{coords_to_square, square_to_algebraic, Square},
|
||||||
state::{Castle, State},
|
state::{Castle, State},
|
||||||
};
|
};
|
||||||
@@ -112,6 +112,8 @@ impl Board {
|
|||||||
self.update_board_state(mv, color);
|
self.update_board_state(mv, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unmake_move(&mut self) {}
|
||||||
|
|
||||||
pub fn update_board_state(&mut self, mv: &Move, color: Color) {
|
pub fn update_board_state(&mut self, mv: &Move, color: Color) {
|
||||||
let (own_pieces, opponent_pieces, en_passant_square) = match color {
|
let (own_pieces, opponent_pieces, en_passant_square) = match color {
|
||||||
Color::White => (
|
Color::White => (
|
||||||
@@ -125,7 +127,7 @@ impl Board {
|
|||||||
Some(mv.src - 8),
|
Some(mv.src - 8),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let pawn_move = Self::is_pawn_move(mv.src, &own_pieces[Kind::Pawn]);
|
let pawn_move = Self::is_pawn_move(mv.src, &own_pieces[PieceType::Pawn]);
|
||||||
|
|
||||||
Self::update_game_state(&mut self.state, mv, color, pawn_move);
|
Self::update_game_state(&mut self.state, mv, color, pawn_move);
|
||||||
|
|
||||||
@@ -193,10 +195,10 @@ impl Board {
|
|||||||
|
|
||||||
fn promote_piece(square: usize, pieces: &mut [Piece; 6], promote: &Promote) {
|
fn promote_piece(square: usize, pieces: &mut [Piece; 6], promote: &Promote) {
|
||||||
match promote {
|
match promote {
|
||||||
Promote::Knight => pieces[Kind::Knight].bitboard |= square_to_bitboard(square),
|
Promote::Knight => pieces[PieceType::Knight].bitboard |= square_to_bitboard(square),
|
||||||
Promote::Bishop => pieces[Kind::Bishop].bitboard |= square_to_bitboard(square),
|
Promote::Bishop => pieces[PieceType::Bishop].bitboard |= square_to_bitboard(square),
|
||||||
Promote::Rook => pieces[Kind::Rook].bitboard |= square_to_bitboard(square),
|
Promote::Rook => pieces[PieceType::Rook].bitboard |= square_to_bitboard(square),
|
||||||
Promote::Queen => pieces[Kind::Queen].bitboard |= square_to_bitboard(square),
|
Promote::Queen => pieces[PieceType::Queen].bitboard |= square_to_bitboard(square),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ mod tests {
|
|||||||
use crate::{attack::init_attacks, fen::from_fen};
|
use crate::{attack::init_attacks, fen::from_fen};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::board::Kind;
|
use crate::board::PieceType;
|
||||||
|
|
||||||
const FEN_PAWN_MOVES: &str = "r1bqk2r/p4pbp/1pnp1np1/P3P1B1/3NNP2/8/1PP3PP/R2QKB1R w - - 0 1";
|
const FEN_PAWN_MOVES: &str = "r1bqk2r/p4pbp/1pnp1np1/P3P1B1/3NNP2/8/1PP3PP/R2QKB1R w - - 0 1";
|
||||||
|
|
||||||
@@ -427,7 +427,7 @@ mod tests {
|
|||||||
Move::new_with_type(36, 45, MoveType::Capture),
|
Move::new_with_type(36, 45, MoveType::Capture),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut actual = new_game.board.pseudo_moves(Color::White, Kind::Pawn);
|
let mut actual = new_game.board.pseudo_moves(Color::White, PieceType::Pawn);
|
||||||
actual.sort();
|
actual.sort();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
@@ -440,7 +440,7 @@ mod tests {
|
|||||||
Move::new_with_type(55, 39, MoveType::DoublePush),
|
Move::new_with_type(55, 39, MoveType::DoublePush),
|
||||||
Move::new(55, 47),
|
Move::new(55, 47),
|
||||||
];
|
];
|
||||||
let mut actual = new_game.board.pseudo_moves(Color::Black, Kind::Pawn);
|
let mut actual = new_game.board.pseudo_moves(Color::Black, PieceType::Pawn);
|
||||||
actual.sort();
|
actual.sort();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
@@ -463,7 +463,7 @@ mod tests {
|
|||||||
Move::new(21, 36),
|
Move::new(21, 36),
|
||||||
Move::new_with_type(21, 38, MoveType::Capture),
|
Move::new_with_type(21, 38, MoveType::Capture),
|
||||||
];
|
];
|
||||||
let mut actual = new_game.board.pseudo_moves(Color::White, Kind::Knight);
|
let mut actual = new_game.board.pseudo_moves(Color::White, PieceType::Knight);
|
||||||
actual.sort();
|
actual.sort();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
@@ -486,7 +486,7 @@ mod tests {
|
|||||||
Move::new(26, 44),
|
Move::new(26, 44),
|
||||||
Move::new_with_type(26, 53, MoveType::Capture),
|
Move::new_with_type(26, 53, MoveType::Capture),
|
||||||
];
|
];
|
||||||
let mut actual = new_game.board.pseudo_moves(Color::White, Kind::Bishop);
|
let mut actual = new_game.board.pseudo_moves(Color::White, PieceType::Bishop);
|
||||||
actual.sort();
|
actual.sort();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
@@ -514,7 +514,7 @@ mod tests {
|
|||||||
Move::new(12, 36),
|
Move::new(12, 36),
|
||||||
Move::new_with_type(12, 44, MoveType::Capture),
|
Move::new_with_type(12, 44, MoveType::Capture),
|
||||||
];
|
];
|
||||||
let mut actual = new_game.board.pseudo_moves(Color::White, Kind::Rook);
|
let mut actual = new_game.board.pseudo_moves(Color::White, PieceType::Rook);
|
||||||
actual.sort();
|
actual.sort();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
@@ -537,7 +537,7 @@ mod tests {
|
|||||||
Move::new(17, 41),
|
Move::new(17, 41),
|
||||||
Move::new_with_type(17, 49, MoveType::Capture),
|
Move::new_with_type(17, 49, MoveType::Capture),
|
||||||
];
|
];
|
||||||
let mut actual = new_game.board.pseudo_moves(Color::White, Kind::Queen);
|
let mut actual = new_game.board.pseudo_moves(Color::White, PieceType::Queen);
|
||||||
actual.sort();
|
actual.sort();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
@@ -563,13 +563,13 @@ mod tests {
|
|||||||
Move::new(22, 29),
|
Move::new(22, 29),
|
||||||
Move::new(22, 30),
|
Move::new(22, 30),
|
||||||
];
|
];
|
||||||
let mut actual = new_game.board.pseudo_moves(Color::White, Kind::King);
|
let mut actual = new_game.board.pseudo_moves(Color::White, PieceType::King);
|
||||||
actual.sort();
|
actual.sort();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
let new_game_2 = from_fen(FEN_KING_MOVES[1])?;
|
let new_game_2 = from_fen(FEN_KING_MOVES[1])?;
|
||||||
let expected = vec![Move::new_with_type(4, 2, MoveType::Castle), Move::new(4, 3)];
|
let expected = vec![Move::new_with_type(4, 2, MoveType::Castle), Move::new(4, 3)];
|
||||||
let mut actual = new_game_2.board.pseudo_moves(Color::White, Kind::King);
|
let mut actual = new_game_2.board.pseudo_moves(Color::White, PieceType::King);
|
||||||
actual.sort();
|
actual.sort();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
@@ -581,7 +581,7 @@ mod tests {
|
|||||||
Move::new(60, 61),
|
Move::new(60, 61),
|
||||||
Move::new_with_type(60, 62, MoveType::Castle),
|
Move::new_with_type(60, 62, MoveType::Castle),
|
||||||
];
|
];
|
||||||
let mut actual = new_game_3.board.pseudo_moves(Color::Black, Kind::King);
|
let mut actual = new_game_3.board.pseudo_moves(Color::Black, PieceType::King);
|
||||||
actual.sort();
|
actual.sort();
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
|
|||||||
48
src/psqt.rs
48
src/psqt.rs
@@ -1,24 +1,24 @@
|
|||||||
use crate::board::Kind;
|
use crate::board::PieceType;
|
||||||
|
|
||||||
pub const fn piece_square_score(kind: Kind, index: usize) -> i32 {
|
pub const fn piece_square_score(piece_type: PieceType, index: usize) -> i32 {
|
||||||
match kind {
|
match piece_type {
|
||||||
Kind::Pawn => PAWN_PSQT[index],
|
PieceType::Pawn => PAWN_PSQT[index],
|
||||||
Kind::Knight => KNIGHT_PSQT[index],
|
PieceType::Knight => KNIGHT_PSQT[index],
|
||||||
Kind::Bishop => BISHOP_PSQT[index],
|
PieceType::Bishop => BISHOP_PSQT[index],
|
||||||
Kind::Rook => ROOK_PSQT[index],
|
PieceType::Rook => ROOK_PSQT[index],
|
||||||
Kind::Queen => QUEEN_PSQT[index],
|
PieceType::Queen => QUEEN_PSQT[index],
|
||||||
Kind::King => KING_MIDGAME_PSQT[index],
|
PieceType::King => KING_MIDGAME_PSQT[index],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn piece_square_score_endgame(kind: Kind, index: usize) -> i32 {
|
pub const fn piece_square_score_endgame(piece_type: PieceType, index: usize) -> i32 {
|
||||||
match kind {
|
match piece_type {
|
||||||
Kind::Pawn => PAWN_PSQT[index],
|
PieceType::Pawn => PAWN_PSQT[index],
|
||||||
Kind::Knight => KNIGHT_PSQT[index],
|
PieceType::Knight => KNIGHT_PSQT[index],
|
||||||
Kind::Bishop => BISHOP_PSQT[index],
|
PieceType::Bishop => BISHOP_PSQT[index],
|
||||||
Kind::Rook => ROOK_PSQT[index],
|
PieceType::Rook => ROOK_PSQT[index],
|
||||||
Kind::Queen => QUEEN_PSQT[index],
|
PieceType::Queen => QUEEN_PSQT[index],
|
||||||
Kind::King => KING_ENDGAME_PSQT[index],
|
PieceType::King => KING_ENDGAME_PSQT[index],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,19 +113,19 @@ const KING_ENDGAME_PSQT: [i32; 64] = [
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
board::Kind,
|
board::PieceType,
|
||||||
psqt::{mirror_index, piece_square_score},
|
psqt::{mirror_index, piece_square_score},
|
||||||
square::Square,
|
square::Square,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_piece_square_score() -> Result<(), String> {
|
fn test_piece_square_score() -> Result<(), String> {
|
||||||
assert_eq!(50, piece_square_score(Kind::Pawn, Square::A7));
|
assert_eq!(50, piece_square_score(PieceType::Pawn, Square::A7));
|
||||||
assert_eq!(-40, piece_square_score(Kind::Knight, Square::B1));
|
assert_eq!(-40, piece_square_score(PieceType::Knight, Square::B1));
|
||||||
assert_eq!(0, piece_square_score(Kind::Bishop, Square::D2));
|
assert_eq!(0, piece_square_score(PieceType::Bishop, Square::D2));
|
||||||
assert_eq!(-5, piece_square_score(Kind::Rook, Square::A2));
|
assert_eq!(-5, piece_square_score(PieceType::Rook, Square::A2));
|
||||||
assert_eq!(5, piece_square_score(Kind::Queen, Square::D3));
|
assert_eq!(5, piece_square_score(PieceType::Queen, Square::D3));
|
||||||
assert_eq!(30, piece_square_score(Kind::King, Square::G1));
|
assert_eq!(30, piece_square_score(PieceType::King, Square::G1));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user