diff options
author | eug-vs <eugene@eug-vs.xyz> | 2023-01-23 07:46:17 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2023-01-23 07:46:17 +0300 |
commit | 06185b5b7f5d9f1d5d57627f86e286879be92e6e (patch) | |
tree | 84b392929fddf47ab919bae4f0badf44012c936c | |
parent | a54e9b4fbb44f0396a4e79d60b88043005012295 (diff) | |
download | chessnost-06185b5b7f5d9f1d5d57627f86e286879be92e6e.tar.gz |
refactor: update occupancy in an optimal way
-rw-r--r-- | src/board.rs | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/src/board.rs b/src/board.rs index ef8dde7..54efab9 100644 --- a/src/board.rs +++ b/src/board.rs @@ -201,6 +201,9 @@ impl Board { /// *Blindlessly* apply a move without any validation /// Move should be validated beforehand pub fn make_move(&mut self, mov: Move) -> Option<PieceType> { + let move_source_bb = mov.source.to_bitboard(); + let move_target_bb = mov.target.to_bitboard(); + // Remove existing piece (if any) from target square let captured_piece = match self.pieces .iter() @@ -208,7 +211,7 @@ impl Board { .find(|(piece_type, bitboard)| *bitboard & mov.target.to_bitboard() > 0) { Some((target_piece, _)) => { - self.pieces[target_piece] ^= mov.target.to_bitboard(); + self.pieces[target_piece] ^= move_target_bb; Some(PieceType::from(target_piece)) }, None => None, @@ -221,13 +224,15 @@ impl Board { .find(|(piece_type, bitboard)| *bitboard & mov.source.to_bitboard() > 0) { Some((source_piece, _)) => { - self.pieces[source_piece] ^= mov.source.to_bitboard(); - self.pieces[source_piece] |= mov.target.to_bitboard(); + self.pieces[source_piece] ^= move_source_bb; + self.occupancy ^= move_source_bb; + + self.pieces[source_piece] |= move_target_bb; + self.occupancy |= move_target_bb; }, None => panic!("Move is malformed: source piece not found"), }; - self.update_occupancy(); self.ply += 1; captured_piece @@ -235,15 +240,21 @@ impl Board { /// Completely reverse make_move as if it never happened pub fn unmake_move(&mut self, mov: Move, captured_piece: Option<PieceType>) { - // Remove source piece from target square + let move_source_bb = mov.source.to_bitboard(); + 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] ^= mov.target.to_bitboard(); - self.pieces[source_piece] |= mov.source.to_bitboard(); + 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"), }; @@ -251,12 +262,12 @@ impl Board { // Return captured piece to target square match captured_piece { Some(target_piece) => { - self.pieces[target_piece as usize] |= mov.target.to_bitboard(); + self.pieces[target_piece as usize] |= move_target_bb; + self.occupancy |= move_target_bb; }, None => {} } - self.update_occupancy(); self.ply -= 1; } } @@ -332,13 +343,14 @@ mod tests { fn test_make_move() { let fen = String::from("q1b2k2/5p1p/4p1pb/pPPp4/3N4/3nPB2/P2QKnR1/1R6 w - - 0 25"); let mut board = Board::from_FEN(fen); + let initial_board = board.clone(); board.print(); let black_move = Move { source: Square::F7, target: Square::F5 }; println!("\n{:?}", black_move); match board.make_move(black_move) { - Some(..) => panic!("No piece should have been captured"), + Some(..) => panic!("No piece should be captured"), None => {}, }; @@ -353,7 +365,7 @@ mod tests { match board.make_move(white_move) { Some(captured) => assert!(captured == PieceType::PawnBlack), - None => panic!("A piece should have been captured"), + None => panic!("A piece should be captured"), }; board.print(); @@ -361,6 +373,7 @@ mod tests { assert!(board.pieces[PieceType::PawnBlack as usize] & Square::A5.to_bitboard() == 0, "Target piece should be captured"); assert!(board.pieces[PieceType::Queen as usize] & Square::D2.to_bitboard() == 0); assert!(board.pieces[PieceType::Queen as usize] & Square::A5.to_bitboard() > 0); + assert_ne!(board.occupancy, initial_board.occupancy, "Occupancy should change after make_move"); assert!(board.ply == 2); } |