aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-01-25 07:50:44 +0300
committereug-vs <eugene@eug-vs.xyz>2023-01-25 07:50:58 +0300
commit80b3283f4a2a09561abae1b7b981b7a3139f00e2 (patch)
tree0b631995ed898529c8af9d64d1a34e5b8ee7cddb /src
parent8dc121b0e08cd25fab3eacde9318d7adaac1f2a4 (diff)
downloadchessnost-80b3283f4a2a09561abae1b7b981b7a3139f00e2.tar.gz
refactor: implement piece_by_square
Diffstat (limited to 'src')
-rw-r--r--src/board/mod.rs129
1 files changed, 61 insertions, 68 deletions
diff --git a/src/board/mod.rs b/src/board/mod.rs
index 2b580b5..67f7264 100644
--- a/src/board/mod.rs
+++ b/src/board/mod.rs
@@ -490,6 +490,14 @@ impl Board {
mobility
}
+ fn piece_by_square(&self, square: Square) -> Option<PieceType> {
+ self.pieces
+ .iter()
+ .enumerate()
+ .find(|(piece_type, bitboard)| *bitboard & square.to_bitboard() > 0)
+ .and_then(|(pt, _)| Some(PieceType::from(pt)))
+ }
+
/// *Blindlessly* apply a move without any validation
/// Move should be validated beforehand
pub fn make_move(&mut self, mov: Move) -> Result<Option<PieceType>,MakeMoveError> {
@@ -497,65 +505,53 @@ impl Board {
let move_target_bb = mov.target.to_bitboard();
// Remove existing piece (if any) from target square
- let mut captured_piece = match self.pieces
- .iter()
- .enumerate()
- .find(|(piece_type, bitboard)| *bitboard & mov.target.to_bitboard() > 0)
- {
- Some((target_piece, _)) => {
- self.pieces[target_piece] ^= move_target_bb;
- self.hash ^= self.zobrist_seed[target_piece * 12 + mov.target as usize];
- Some(PieceType::from(target_piece))
- },
- None => None,
- };
+ let mut captured_piece = match self.piece_by_square(mov.target) {
+ Some(target_piece) => {
+ self.pieces[target_piece as usize] ^= move_target_bb;
+ self.hash ^= self.zobrist_seed[(target_piece as usize) * 12 + mov.target as usize];
+ Some(target_piece)
+ },
+ None => None,
+ };
// En Passant captures diffirently
if mov.kind == MoveKind::EnPassant {
debug_assert!(captured_piece.is_none(), "No capture should be found at this point");
let captured_square = Square::from_coords(mov.source.rank(), mov.target.file());
- let captured_bb = captured_square.to_bitboard();
- captured_piece = match self.pieces
- .iter()
- .enumerate()
- .find(|(piece_type, bitboard)| *bitboard & captured_bb > 0)
- {
- Some((pawn_type, _)) => {
- self.pieces[pawn_type] ^= captured_bb;
- self.hash ^= self.zobrist_seed[pawn_type * 12 + captured_square as usize];
- Some(PieceType::from(pawn_type))
- }
- None => {
- return Err(MakeMoveError::PieceNotFound(
- String::from("Pawn captured by En Passant was not found")
- ))
- }
+ captured_piece = match self.piece_by_square(captured_square) {
+ Some(pawn_type) => {
+ self.pieces[pawn_type as usize] ^= captured_square.to_bitboard();
+ self.hash ^= self.zobrist_seed[pawn_type as usize* 12 + captured_square as usize];
+ Some(pawn_type)
}
- }
-
- // Move a piece from source square to target
- let source_piece = match self.pieces
- .iter()
- .enumerate()
- .find(|(piece_type, bitboard)| *bitboard & mov.source.to_bitboard() > 0)
- {
- Some((source_piece, _)) => {
- self.pieces[source_piece] ^= move_source_bb;
- self.occupancy ^= move_source_bb;
- self.hash ^= self.zobrist_seed[source_piece * 12 + mov.source as usize];
-
- self.pieces[source_piece] |= move_target_bb;
- self.occupancy |= move_target_bb;
- self.hash ^= self.zobrist_seed[source_piece * 12 + mov.target as usize];
- PieceType::from(source_piece)
- },
None => {
- self.print();
return Err(MakeMoveError::PieceNotFound(
- String::from("Source piece not found")
- ))
+ String::from("Pawn captured by En Passant was not found")
+ ))
}
- };
+ }
+ }
+
+ // Move a piece from source square to target
+ 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 * 12 + mov.source as usize];
+
+ self.pieces[source_id] |= move_target_bb;
+ self.occupancy |= move_target_bb;
+ self.hash ^= self.zobrist_seed[source_id * 12 + mov.target as usize];
+ PieceType::from(source_piece)
+ },
+ None => {
+ self.print();
+ return Err(MakeMoveError::PieceNotFound(
+ String::from("Source piece not found")
+ ))
+ }
+ };
// When castling, also move a rook
if mov.kind == MoveKind::Castle {
@@ -571,22 +567,19 @@ impl Board {
let rook_target_square = Square::from_coords(mov.target.rank(), rook_target_file);
let rook_target_bb = rook_target_square.to_bitboard();
- match self.pieces
- .iter()
- .enumerate()
- .find(|(rook_type, bitboard)| *bitboard & rook_source_bb > 0)
- {
- Some((rook_type, _)) => {
- self.pieces[rook_type] ^= rook_source_bb;
- self.occupancy ^= rook_source_bb;
- self.hash ^= self.zobrist_seed[rook_type * 12 + rook_source_square as usize];
+ match self.piece_by_square(rook_source_square) {
+ Some(rook_type) => {
+ let rook_id = rook_type as usize;
+ self.pieces[rook_id] ^= rook_source_bb;
+ self.occupancy ^= rook_source_bb;
+ self.hash ^= self.zobrist_seed[rook_id * 12 + rook_source_square as usize];
- self.pieces[rook_type] |= rook_target_bb;
- self.occupancy |= rook_target_bb;
- self.hash ^= self.zobrist_seed[rook_type * 12 + rook_target_square as usize];
- },
- None => panic!("Rook was not found when castling"),
- }
+ self.pieces[rook_id] |= rook_target_bb;
+ self.occupancy |= rook_target_bb;
+ self.hash ^= self.zobrist_seed[rook_id * 12 + rook_target_square as usize];
+ },
+ None => panic!("Rook was not found when castling"),
+ }
}
// Double push should set En Passant target square
@@ -856,7 +849,7 @@ mod tests {
let black_move = Move { source: Square::F7, target: Square::F5, kind: MoveKind::Quiet };
println!("\n{:?}", black_move);
- match board.make_move(black_move) {
+ match board.make_move(black_move).unwrap() {
Some(..) => panic!("No piece should be captured"),
None => {},
};
@@ -870,7 +863,7 @@ mod tests {
let white_move = Move { source: Square::D2, target: Square::A5, kind: MoveKind::Capture };
println!("\n{:?}", white_move);
- match board.make_move(white_move) {
+ match board.make_move(white_move).unwrap() {
Some(captured) => assert!(captured == PieceType::PawnBlack),
None => panic!("A piece should be captured"),
};
@@ -894,7 +887,7 @@ mod tests {
board.print();
- let captured_piece = board.make_move(mov);
+ let captured_piece = board.make_move(mov).unwrap();
board.print();
board.unmake_move(mov, captured_piece, None, board.castling_rights, initial_board.hash);