Replace loops with mailbox lookups and move make/unmake tests to game.rs

This commit is contained in:
stefiosif
2024-09-21 17:51:39 +03:00
parent 8a40186f8b
commit 70ba30ba1a
4 changed files with 270 additions and 278 deletions

View File

@@ -164,66 +164,6 @@ impl Board {
self.state = state;
}
pub fn update_game_state(
state: &mut State,
mv: &Move,
color: Color,
pawn_move: bool,
en_passant_square: Option<usize>,
) {
state.set_en_passant_square(en_passant_square);
state.update_castling_state_quiet(mv.src, 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();
}
pub fn move_piece(&mut self, src: usize, dst: usize) {
let pieces = self.own_pieces();
pieces
.iter_mut()
.filter(|p| have_common_bit(p.bitboard, square_to_bitboard(src)))
.for_each(|p| {
p.bitboard &= !square_to_bitboard(src);
p.bitboard |= square_to_bitboard(dst);
});
//TODO:
// pieces[piece_type].bitboard &= !square_to_bitboard(src);
// pieces[piece_type].bitboard |= square_to_bitboard(dst);
}
pub fn remove_own_piece(&mut self, square: usize) {
let pieces = self.own_pieces();
pieces
.iter_mut()
.filter(|p| have_common_bit(p.bitboard, square_to_bitboard(square)))
.for_each(|p| {
p.bitboard &= !square_to_bitboard(square);
});
}
pub fn remove_opponent_piece(&mut self, square: usize) {
let pieces = self.opponent_pieces();
pieces
.iter_mut()
.filter(|p| have_common_bit(p.bitboard, square_to_bitboard(square)))
.for_each(|p| {
p.bitboard &= !square_to_bitboard(square);
});
}
pub fn promote_piece(&mut self, square: usize, promote: &Promote) {
let pieces = self.own_pieces();
match promote {
Promote::Knight => pieces[PieceType::Knight].bitboard |= square_to_bitboard(square),
Promote::Bishop => pieces[PieceType::Bishop].bitboard |= square_to_bitboard(square),
Promote::Rook => pieces[PieceType::Rook].bitboard |= square_to_bitboard(square),
Promote::Queen => pieces[PieceType::Queen].bitboard |= square_to_bitboard(square),
};
}
pub fn is_pawn_move(&mut self, square: usize) -> bool {
let pieces = self.own_pieces();
have_common_bit(square_to_bitboard(square), pieces[PieceType::Pawn].bitboard)
@@ -249,6 +189,42 @@ impl Board {
Color::Black => (&mut self.black_pieces, &mut self.white_pieces),
}
}
pub fn move_piece(&mut self, src: usize, dst: usize, piece_type: PieceType) {
let pieces = self.own_pieces();
pieces[piece_type].bitboard &= !square_to_bitboard(src);
pieces[piece_type].bitboard |= square_to_bitboard(dst);
}
pub fn insert_own_piece(&mut self, square: usize, piece_type: PieceType) {
let pieces = self.own_pieces();
pieces[piece_type].bitboard |= square_to_bitboard(square);
}
pub fn insert_opponent_piece(&mut self, square: usize, piece_type: PieceType) {
let pieces = self.opponent_pieces();
pieces[piece_type].bitboard |= square_to_bitboard(square);
}
pub fn remove_own_piece(&mut self, square: usize, piece_type: PieceType) {
let pieces = self.own_pieces();
pieces[piece_type].bitboard &= !square_to_bitboard(square);
}
pub fn remove_opponent_piece(&mut self, square: usize, piece_type: PieceType) {
let pieces = self.opponent_pieces();
pieces[piece_type].bitboard &= !square_to_bitboard(square);
}
pub fn promote_piece(&mut self, square: usize, promote: &Promote) {
let pieces = self.own_pieces();
match promote {
Promote::Knight => pieces[PieceType::Knight].bitboard |= square_to_bitboard(square),
Promote::Bishop => pieces[PieceType::Bishop].bitboard |= square_to_bitboard(square),
Promote::Rook => pieces[PieceType::Rook].bitboard |= square_to_bitboard(square),
Promote::Queen => pieces[PieceType::Queen].bitboard |= square_to_bitboard(square),
};
}
}
impl Default for Board {
@@ -324,10 +300,7 @@ impl Color {
#[cfg(test)]
mod tests {
use crate::{
board::{fen::from_fen, square::Square},
movegen::{attack_generator::init_attacks, r#move::MoveType},
};
use crate::{board::fen::from_fen, movegen::attack_generator::init_attacks};
use super::*;
@@ -353,98 +326,4 @@ mod tests {
Ok(())
}
const FEN: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R w KQk g6 0 1";
const FEN_QUIET: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2BQ3/1P1PNPP1/R3K2R b KQk - 1 1";
#[test]
fn test_make_move_quiet() -> Result<(), String> {
let mut game = from_fen(FEN)?;
let b1c3 = Move::new(Square::F3, Square::E3);
game.make_move(&b1c3);
assert_eq!(game, from_fen(FEN_QUIET)?);
Ok(())
}
const FEN_CAPTURE: &str = "1r2k2r/2P1pq1p/2npb3/1p3QpP/p3P3/P2B4/1P1PNPP1/R3K2R b KQk - 0 1";
#[test]
fn test_make_move_capture() -> Result<(), String> {
let mut game = from_fen(FEN)?;
let f3f5 = Move::new_with_type(Square::F3, Square::F5, MoveType::Capture);
game.make_move(&f3f5);
assert_eq!(game, from_fen(FEN_CAPTURE)?);
Ok(())
}
const FEN_EN_PASSANT: &str =
"1r2k2r/2P1pq1p/2npb1P1/1p3p2/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1";
#[test]
fn test_make_move_en_passant() -> Result<(), String> {
let mut game = from_fen(FEN)?;
let h5g6 = Move::new_with_type(Square::H5, Square::G6, MoveType::EnPassant);
game.make_move(&h5g6);
assert_eq!(game, from_fen(FEN_EN_PASSANT)?);
Ok(())
}
const FEN_DOUBLE_PUSH: &str =
"1r2k2r/2P1pq1p/2npb3/1p3ppP/pP2P3/P2B1Q2/3PNPP1/R3K2R b KQk b3 0 1";
#[test]
fn test_make_move_double_push() -> Result<(), String> {
let mut game = from_fen(FEN)?;
let b2b4 = Move::new_with_type(Square::B2, Square::B4, MoveType::DoublePush);
game.make_move(&b2b4);
assert_eq!(game, from_fen(FEN_DOUBLE_PUSH)?);
Ok(())
}
const FEN_PROMOTION: &str = "1rQ1k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1";
#[test]
fn test_make_move_promotion() -> Result<(), String> {
let mut game = from_fen(FEN)?;
let c7c8 = Move::new_with_type(Square::C7, Square::C8, MoveType::Promotion(Promote::Queen));
game.make_move(&c7c8);
assert_eq!(game, from_fen(FEN_PROMOTION)?);
Ok(())
}
const FEN_PROMOTION_CAPTURE: &str =
"1Q2k2r/4pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R3K2R b KQk - 0 1";
#[test]
fn test_make_move_promotion_capture() -> Result<(), String> {
let mut game = from_fen(FEN)?;
let c7b8 = Move::new_with_type(
Square::C7,
Square::B8,
MoveType::PromotionCapture(Promote::Queen),
);
game.make_move(&c7b8);
assert_eq!(game, from_fen(FEN_PROMOTION_CAPTURE)?);
Ok(())
}
const FEN_CASTLE: &str = "1r2k2r/2P1pq1p/2npb3/1p3ppP/p3P3/P2B1Q2/1P1PNPP1/R4RK1 b k - 1 1";
#[test]
fn test_make_move_castle() -> Result<(), String> {
let mut game = from_fen(FEN)?;
let e1g1 = Move::new_with_type(Square::E1, Square::G1, MoveType::Castle);
game.make_move(&e1g1);
assert_eq!(game, from_fen(FEN_CASTLE)?);
Ok(())
}
}