Rework the Pawn move generator to correctly compute en passant moves
This commit is contained in:
parent
3b8b6b36e3
commit
c03a804c79
1 changed files with 84 additions and 9 deletions
|
@ -1,14 +1,22 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||
use crate::Position;
|
||||
use crate::{r#move::Move, MoveBuilder, Position};
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_core::{Color, PlacedPiece, Rank, Shape, Square};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MoveIterator(usize, usize);
|
||||
|
||||
move_generator_declaration!(PawnMoveGenerator);
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub(super) struct PawnMoveGenerator {
|
||||
color: chessfriend_core::Color,
|
||||
move_sets: BTreeMap<Square, MoveSet>,
|
||||
en_passant_captures: Vec<Move>,
|
||||
}
|
||||
|
||||
move_generator_declaration!(PawnMoveGenerator, getters);
|
||||
|
||||
impl MoveGeneratorInternal for PawnMoveGenerator {
|
||||
fn shape() -> Shape {
|
||||
|
@ -31,7 +39,50 @@ impl MoveGeneratorInternal for PawnMoveGenerator {
|
|||
}
|
||||
|
||||
impl PawnMoveGenerator {
|
||||
fn pushes(position: &Position, piece: PlacedPiece) -> BitBoard {
|
||||
pub(super) fn new(
|
||||
position: &Position,
|
||||
color: Color,
|
||||
capture_mask: BitBoard,
|
||||
push_mask: BitBoard,
|
||||
) -> Self {
|
||||
let move_sets = if !capture_mask.is_empty() && !push_mask.is_empty() {
|
||||
Self::move_sets(position, color, capture_mask, push_mask)
|
||||
} else {
|
||||
std::collections::BTreeMap::new()
|
||||
};
|
||||
|
||||
Self {
|
||||
color,
|
||||
move_sets,
|
||||
en_passant_captures: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn move_sets(
|
||||
position: &Position,
|
||||
color: Color,
|
||||
capture_mask: BitBoard,
|
||||
push_mask: BitBoard,
|
||||
) -> BTreeMap<Square, MoveSet> {
|
||||
let piece = Self::piece(color);
|
||||
let mut moves_for_pieces =
|
||||
BTreeMap::from_iter(position.bitboard_for_piece(piece).occupied_squares().map(
|
||||
|square| {
|
||||
let piece = PlacedPiece::new(piece, square);
|
||||
let move_set =
|
||||
Self::move_set_for_piece(position, &piece, capture_mask, push_mask);
|
||||
(square, move_set)
|
||||
},
|
||||
));
|
||||
|
||||
if position.has_en_passant_square() {
|
||||
|
||||
}
|
||||
|
||||
moves_for_pieces
|
||||
}
|
||||
|
||||
fn pushes(position: &Position, piece: &PlacedPiece) -> BitBoard {
|
||||
let color = piece.color();
|
||||
let square = piece.square();
|
||||
let bitboard: BitBoard = square.into();
|
||||
|
@ -59,16 +110,40 @@ impl PawnMoveGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
fn attacks(position: &Position, piece: PlacedPiece) -> BitBoard {
|
||||
fn attacks(position: &Position, piece: &PlacedPiece) -> BitBoard {
|
||||
let color = piece.color();
|
||||
|
||||
let opponent_pieces = position.bitboard_for_color(color.other());
|
||||
let en_passant_bitboard = match position.en_passant_square() {
|
||||
Some(square) => <Square as Into<BitBoard>>::into(square),
|
||||
None => BitBoard::empty(),
|
||||
};
|
||||
|
||||
BitBoard::pawn_attacks(piece.square(), color) & (opponent_pieces | en_passant_bitboard)
|
||||
BitBoard::pawn_attacks(piece.square(), color) & opponent_pieces
|
||||
}
|
||||
|
||||
fn en_passant_attack(position: &Position, piece: &PlacedPiece) -> Option<Move> {
|
||||
match position.en_passant() {
|
||||
Some(en_passant) => {
|
||||
let en_passant_bitboard: BitBoard = en_passant.target_square().into();
|
||||
let capture =
|
||||
BitBoard::pawn_attacks(piece.square(), piece.color()) & en_passant_bitboard;
|
||||
|
||||
if capture.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
match position.piece_on_square(en_passant.capture_square()) {
|
||||
Some(captured_piece) => Some(
|
||||
MoveBuilder::new(
|
||||
*piece.piece(),
|
||||
piece.square(),
|
||||
en_passant.target_square(),
|
||||
)
|
||||
.capturing_en_passant(captured_piece)
|
||||
.build(),
|
||||
),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue