diff options
-rw-r--r-- | src/board/mod.rs | 94 | ||||
-rw-r--r-- | src/moves.rs | 3 |
2 files changed, 72 insertions, 25 deletions
diff --git a/src/board/mod.rs b/src/board/mod.rs index d8166c3..cce2ca7 100644 --- a/src/board/mod.rs +++ b/src/board/mod.rs @@ -246,8 +246,8 @@ impl Board { let available_targets = opponent_occupancy | empty; let player_pieces = self.pieces_by_color(color); - for (piece_type, piece) in player_pieces.iter().enumerate() { - match PieceType::from(piece_type) { + for (piece_id, piece) in player_pieces.iter().enumerate() { + match PieceType::from(piece_id) { PieceType::Pawn => { for source in serialize_bitboard(*piece) { let ep_bitboard = match self.ep_target { @@ -256,12 +256,30 @@ impl Board { }; for target in serialize_bitboard(self.attacks.pawn[color as usize][source as usize] & opponent_occupancy) { moves.push(Move { source, target, kind: MoveKind::Capture }); + if (target.rank() == 7) { + for promo_type in [PieceType::Bishop, PieceType::Knight, PieceType::Rook, PieceType::Queen] { + moves.push(Move { source, target, kind: MoveKind::Promotion(promo_type)}) + } + } else if (target.rank() == 0) { + for promo_type in [PieceType::BishopBlack, PieceType::KnightBlack, PieceType::RookBlack, PieceType::QueenBlack] { + moves.push(Move { source, target, kind: MoveKind::Promotion(promo_type)}) + } + } }; for target in serialize_bitboard(self.attacks.pawn[color as usize][source as usize] & ep_bitboard) { moves.push(Move { source, target, kind: MoveKind::EnPassant }); } for target in serialize_bitboard(self.attacks.pawn_pushes[color as usize][source as usize] & empty) { moves.push(Move { source, target, kind: MoveKind::Quiet }); + if (target.rank() == 7) { + for promo_type in [PieceType::Bishop, PieceType::Knight, PieceType::Rook, PieceType::Queen] { + moves.push(Move { source, target, kind: MoveKind::Promotion(promo_type)}) + } + } else if (target.rank() == 0) { + for promo_type in [PieceType::BishopBlack, PieceType::KnightBlack, PieceType::RookBlack, PieceType::QueenBlack] { + moves.push(Move { source, target, kind: MoveKind::Promotion(promo_type)}) + } + } }; } @@ -529,13 +547,27 @@ impl Board { let source_piece = match self.piece_by_square(mov.source) { Some(source_piece) => { let source_id = source_piece as usize; - self.pieces[source_id] ^= move_source_bb; - self.occupancy ^= move_source_bb; - self.hash ^= self.zobrist_seed[source_id * 64 + mov.source as usize]; + match mov.kind { + MoveKind::Promotion(promotion_piece) => { + let promo_id = promotion_piece as usize; + self.pieces[source_id] ^= move_source_bb; + self.occupancy ^= move_source_bb; + self.hash ^= self.zobrist_seed[source_id * 64 + mov.source as usize]; + + self.pieces[promo_id] |= move_target_bb; + self.occupancy |= move_target_bb; + self.hash ^= self.zobrist_seed[promo_id * 64 + mov.target as usize]; + }, + _ => { + self.pieces[source_id] ^= move_source_bb; + self.occupancy ^= move_source_bb; + self.hash ^= self.zobrist_seed[source_id * 64 + mov.source as usize]; - self.pieces[source_id] |= move_target_bb; - self.occupancy |= move_target_bb; - self.hash ^= self.zobrist_seed[source_id * 64 + mov.target as usize]; + self.pieces[source_id] |= move_target_bb; + self.occupancy |= move_target_bb; + self.hash ^= self.zobrist_seed[source_id * 64 + mov.target as usize]; + } + } PieceType::from(source_piece) }, None => { @@ -595,11 +627,11 @@ impl Board { PieceType::Rook => { match mov.source.file() { 0 => { - self.castling_rights[Color::from_piece(source_piece) as usize][CastlingSide::Queen as usize] = false; + self.castling_rights[source_color][CastlingSide::Queen as usize] = false; self.hash ^= self.zobrist_seed[64 * 12 + source_color * 2 + CastlingSide::Queen as usize]; } 7 => { - self.castling_rights[Color::from_piece(source_piece) as usize][CastlingSide::King as usize] = false; + self.castling_rights[source_color][CastlingSide::King as usize] = false; self.hash ^= self.zobrist_seed[64 * 12 + source_color * 2 + CastlingSide::King as usize]; } _ => {}, @@ -627,20 +659,34 @@ impl Board { let move_target_bb = mov.target.to_bitboard(); // Move a piece from target square back to source square - match self.pieces - .iter() - .enumerate() - .find(|(piece_type, bitboard)| *bitboard & mov.target.to_bitboard() > 0) - { - Some((source_piece, _)) => { - self.pieces[source_piece] ^= move_target_bb; - self.occupancy ^= move_target_bb; - - self.pieces[source_piece] |= move_source_bb; - self.occupancy |= move_source_bb; - }, - None => panic!("Trying to unmake move which was not made: no piece was found on target square"), - }; + match self.piece_by_square(mov.target) { + Some(source_piece) => { + match mov.kind { + MoveKind::Promotion(promotion_piece) => { + let promo_id = promotion_piece as usize; + self.pieces[promo_id] ^= move_target_bb; + self.occupancy ^= move_target_bb; + + let source_id = match Color::from_piece(promotion_piece) { + Color::White => PieceType::Pawn, + Color::Black => PieceType::PawnBlack, + } as usize; + + self.pieces[source_id] |= move_source_bb; + self.occupancy |= move_source_bb; + } + _ => { + let source_id = source_piece as usize; + self.pieces[source_id] ^= move_target_bb; + self.occupancy ^= move_target_bb; + + self.pieces[source_id] |= move_source_bb; + self.occupancy |= move_source_bb; + } + } + }, + None => panic!("Trying to unmake move which was not made: no piece was found on target square"), + }; // If unmaking castle, also return rook to its place if mov.kind == MoveKind::Castle { diff --git a/src/moves.rs b/src/moves.rs index 66a3be1..87b7c4b 100644 --- a/src/moves.rs +++ b/src/moves.rs @@ -1,4 +1,4 @@ -use crate::{square::Square, bitboard::print}; +use crate::{square::Square, bitboard::print, board::PieceType}; #[derive(Debug, Clone, PartialEq, Eq, Copy)] pub enum MoveKind { @@ -7,6 +7,7 @@ pub enum MoveKind { Castle, EnPassant, DoublePush, + Promotion(PieceType), } #[derive(Debug, Clone, Copy, PartialEq, Eq)] |