Fix move generator bugs related to castling, enpassant, promotion
This commit is contained in:
54
src/board.rs
54
src/board.rs
@@ -4,7 +4,7 @@ use crate::attack::{
|
||||
get_bishop_attacks, get_king_attacks, get_knight_attacks, get_pawn_attacks, get_queen_attacks,
|
||||
get_rook_attacks,
|
||||
};
|
||||
use crate::game::State;
|
||||
use crate::game::{Castle, State};
|
||||
use crate::movegen::{
|
||||
bishop_pseudo_moves, king_pseudo_moves, knight_pseudo_moves, pawn_pseudo_moves,
|
||||
queen_pseudo_moves, rook_pseudo_moves,
|
||||
@@ -88,12 +88,12 @@ impl Board {
|
||||
|
||||
pub fn is_attacked(&self, sq: usize, opponent_color: Color) -> bool {
|
||||
let all_occupancies = self.get_all_occupancies();
|
||||
let enemy = match opponent_color {
|
||||
Color::Black => &self.black_pieces,
|
||||
Color::White => &self.white_pieces,
|
||||
let (enemy, own_color) = match opponent_color {
|
||||
Color::Black => (&self.black_pieces, Color::White),
|
||||
Color::White => (&self.white_pieces, Color::Black),
|
||||
};
|
||||
|
||||
enemy[Kind::Pawn.idx()].bitboard & get_pawn_attacks(sq, opponent_color) != 0
|
||||
enemy[Kind::Pawn.idx()].bitboard & get_pawn_attacks(sq, own_color) != 0
|
||||
|| enemy[Kind::Knight.idx()].bitboard & get_knight_attacks(sq) != 0
|
||||
|| enemy[Kind::Bishop.idx()].bitboard & get_bishop_attacks(all_occupancies, sq) != 0
|
||||
|| enemy[Kind::Rook.idx()].bitboard & get_rook_attacks(all_occupancies, sq) != 0
|
||||
@@ -156,14 +156,18 @@ impl Board {
|
||||
|
||||
pub fn make_move(&mut self, mv: Move, color: Color) -> bool {
|
||||
self.update_board_state(&mv, color);
|
||||
self.state.update_castling_state(mv.source as u8, color);
|
||||
self.state.change_side();
|
||||
|
||||
let pieces = match color {
|
||||
Color::White => &self.white_pieces,
|
||||
Color::Black => &self.black_pieces,
|
||||
};
|
||||
|
||||
self.state
|
||||
.update_castling_state_quiet(mv.source as u8, color);
|
||||
self.state
|
||||
.update_castling_state_capture(mv.target as u8, Color::opponent_color(color));
|
||||
self.state.change_side();
|
||||
|
||||
let own_king_square = pieces[Kind::King.idx()].bitboard.trailing_zeros() as usize;
|
||||
self.is_move_legit(own_king_square, Color::opponent_color(color))
|
||||
}
|
||||
@@ -191,7 +195,10 @@ impl Board {
|
||||
}
|
||||
MoveType::DoublePush => {
|
||||
Board::move_piece(mv.source as u8, mv.target as u8, own_pieces);
|
||||
let en_passant = Some(mv.source as u8 + 8);
|
||||
let en_passant = match color {
|
||||
Color::White => Some((mv.source + 8) as u8),
|
||||
Color::Black => Some((mv.source - 8) as u8),
|
||||
};
|
||||
self.state.set_en_passant_target_square(en_passant);
|
||||
}
|
||||
MoveType::Promotion(promote) => {
|
||||
@@ -209,6 +216,7 @@ impl Board {
|
||||
Board::move_piece(mv.source as u8, mv.target as u8, own_pieces);
|
||||
Board::move_rook_castle(mv.target as u8, own_pieces);
|
||||
self.state.set_en_passant_target_square(None);
|
||||
self.state.set_castling_ability(color, Castle::None)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,13 +238,7 @@ impl Board {
|
||||
_ => return,
|
||||
};
|
||||
|
||||
for p in pieces.iter_mut() {
|
||||
if p.bitboard & 1_u64 << rook_source != 0 {
|
||||
p.bitboard &= !(1_u64 << rook_source);
|
||||
p.bitboard |= 1_u64 << rook_target;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Board::move_piece(rook_source, rook_target, pieces);
|
||||
}
|
||||
|
||||
fn promote_piece(square: u8, pieces: &mut [Piece; 6], promote: Promote) {
|
||||
@@ -464,28 +466,6 @@ mod tests {
|
||||
let mv = Move::new_with_type(4, 6, MoveType::Castle);
|
||||
game.board.make_move(mv, Color::White);
|
||||
assert_eq!(game, from_fen(FEN_CASTLE[1])?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_perftree_snapshots() -> Result<(), String> {
|
||||
init_attacks();
|
||||
|
||||
let mut game = from_fen("rnbqkbnr/ppppp1pp/5p2/7Q/8/4P3/PPPP1PPP/RNB1KBNR w KQkq - 0 1")?;
|
||||
for mv in game.board.pseudo_moves_all(Color::Black) {
|
||||
if game.board.make_move_and_reset(mv, Color::Black) {
|
||||
println!("{:?}", mv)
|
||||
}
|
||||
}
|
||||
|
||||
let mut game = from_fen("rnbqkbnr/1ppppppp/p7/8/Q7/2P5/PP1PPPPP/RNB1KBNR w KQkq - 0 1")?;
|
||||
for mv in game.board.pseudo_moves_all(Color::Black) {
|
||||
if game.board.make_move_and_reset(mv, Color::Black) {
|
||||
println!("{:?}", mv)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user