aboutsummaryrefslogtreecommitdiff
path: root/src/board.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/board.rs')
-rw-r--r--src/board.rs35
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);
}