aboutsummaryrefslogtreecommitdiff
path: root/src/board.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/board.rs')
-rw-r--r--src/board.rs72
1 files changed, 53 insertions, 19 deletions
diff --git a/src/board.rs b/src/board.rs
index 7295b5f..186e569 100644
--- a/src/board.rs
+++ b/src/board.rs
@@ -1,4 +1,4 @@
-use crate::{bitboard::{Bitboard, serialize_bitboard, bitscan}, moves::Move, attacks::Attacks, square::Square};
+use crate::{bitboard::{Bitboard, serialize_bitboard, bitscan}, moves::{Move, MoveKind}, attacks::Attacks, square::Square};
pub static DEFAULT_FEN: &str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
@@ -9,6 +9,9 @@ pub struct Board {
pub occupancy: Bitboard,
pub ply: u16,
+ /// En passsant target square
+ pub ep_target: Option<Square>,
+
attacks: Attacks,
}
@@ -85,7 +88,13 @@ impl Board {
}
}
- let mut board = Self { pieces, occupancy: 0, ply: 0, attacks: Attacks::new() };
+ let mut board = Self {
+ pieces,
+ occupancy: 0,
+ ply: 0,
+ attacks: Attacks::new(),
+ ep_target: None,
+ };
board.update_occupancy();
board
}
@@ -153,57 +162,82 @@ impl Board {
match PieceType::from(piece_type) {
PieceType::Pawn => {
for source in serialize_bitboard(*piece) {
+ let ep_bitboard = match self.ep_target {
+ Some(square) => square.to_bitboard(),
+ None => 0,
+ };
for target in serialize_bitboard(self.attacks.pawn[color as usize][source as usize] & opponent_occupancy) {
- moves.push(Move { source, target });
+ moves.push(Move { source, target, kind: MoveKind::Capture });
};
+ 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 });
+ moves.push(Move { source, target, kind: MoveKind::Quiet });
};
}
- // Make sure no blocking piece is standing in front of the pawn
+ // Make sure no blocking piece is standing in front of the pawns
+ // that are potential double-push sources
let able_to_double_push_mask = match color {
Color::White => empty >> 8,
Color::Black => empty << 8,
};
for source in serialize_bitboard(*piece & able_to_double_push_mask) {
for target in serialize_bitboard(self.attacks.pawn_double_pushes[color as usize][source as usize] & empty) {
- moves.push(Move { source, target });
+ moves.push(Move { source, target, kind: MoveKind::Quiet });
};
}
}
PieceType::King => {
for source in serialize_bitboard(*piece) {
- for target in serialize_bitboard(self.attacks.king[source as usize] & available_targets) {
- moves.push(Move { source, target });
+ for target in serialize_bitboard(self.attacks.king[source as usize] & empty) {
+ moves.push(Move { source, target, kind: MoveKind::Quiet });
+ };
+ for target in serialize_bitboard(self.attacks.king[source as usize] & opponent_occupancy) {
+ moves.push(Move { source, target, kind: MoveKind::Capture });
};
}
}
PieceType::Knight => {
for source in serialize_bitboard(*piece) {
- for target in serialize_bitboard(self.attacks.knight[source as usize] & available_targets) {
- moves.push(Move { source, target });
+ for target in serialize_bitboard(self.attacks.knight[source as usize] & empty) {
+ moves.push(Move { source, target, kind: MoveKind::Quiet });
+ };
+ for target in serialize_bitboard(self.attacks.knight[source as usize] & opponent_occupancy) {
+ moves.push(Move { source, target, kind: MoveKind::Capture });
};
}
}
PieceType::Bishop => {
for source in serialize_bitboard(*piece) {
- for target in serialize_bitboard(self.attacks.bishop(self.occupancy, source) & available_targets) {
- moves.push(Move { source, target });
+ for target in serialize_bitboard(self.attacks.bishop(self.occupancy, source) & empty) {
+ moves.push(Move { source, target, kind: MoveKind::Quiet });
+ };
+ for target in serialize_bitboard(self.attacks.bishop(self.occupancy, source) & opponent_occupancy) {
+ moves.push(Move { source, target, kind: MoveKind::Capture });
};
}
}
PieceType::Rook => {
for source in serialize_bitboard(*piece) {
- for target in serialize_bitboard(self.attacks.rook(self.occupancy, source) & available_targets) {
- moves.push(Move { source, target });
+ for target in serialize_bitboard(self.attacks.rook(self.occupancy, source) & empty) {
+ moves.push(Move { source, target, kind: MoveKind::Quiet });
+ };
+ }
+ for source in serialize_bitboard(*piece) {
+ for target in serialize_bitboard(self.attacks.rook(self.occupancy, source) & opponent_occupancy) {
+ moves.push(Move { source, target, kind: MoveKind::Capture });
};
}
}
PieceType::Queen => {
for source in serialize_bitboard(*piece) {
- for target in serialize_bitboard(self.attacks.queen(self.occupancy, source) & available_targets) {
- moves.push(Move { source, target });
+ for target in serialize_bitboard(self.attacks.queen(self.occupancy, source) & empty) {
+ moves.push(Move { source, target, kind: MoveKind::Quiet });
+ };
+ for target in serialize_bitboard(self.attacks.queen(self.occupancy, source) & opponent_occupancy) {
+ moves.push(Move { source, target, kind: MoveKind::Capture });
};
}
}
@@ -461,7 +495,7 @@ mod tests {
let initial_board = board.clone();
board.print();
- let black_move = Move { source: Square::F7, target: Square::F5 };
+ let black_move = Move { source: Square::F7, target: Square::F5, kind: MoveKind::Quiet };
println!("\n{:?}", black_move);
match board.make_move(black_move) {
@@ -475,7 +509,7 @@ mod tests {
assert!(board.pieces[PieceType::PawnBlack as usize] & Square::F5.to_bitboard() > 0);
assert!(board.ply == 1);
- let white_move = Move { source: Square::D2, target: Square::A5 };
+ let white_move = Move { source: Square::D2, target: Square::A5, kind: MoveKind::Capture };
println!("\n{:?}", white_move);
match board.make_move(white_move) {
@@ -498,7 +532,7 @@ mod tests {
let mut board = Board::from_FEN(fen);
let initial_board = board.clone();
- let mov = Move { source: Square::D2, target: Square::A5 };
+ let mov = Move { source: Square::D2, target: Square::A5, kind: MoveKind::Capture };
board.print();