WIP
This commit is contained in:
parent
d5cdf273c8
commit
091cc99cb3
42 changed files with 805 additions and 1662 deletions
|
@ -1,8 +1,8 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||
use crate::Position;
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_board::Board;
|
||||
use chessfriend_core::{Direction, PlacedPiece, Shape};
|
||||
|
||||
move_generator_declaration!(ClassicalMoveGenerator);
|
||||
|
@ -13,16 +13,16 @@ impl MoveGeneratorInternal for ClassicalMoveGenerator {
|
|||
}
|
||||
|
||||
fn move_set_for_piece(
|
||||
position: &Position,
|
||||
board: &Board,
|
||||
piece: &PlacedPiece,
|
||||
capture_mask: BitBoard,
|
||||
push_mask: BitBoard,
|
||||
) -> MoveSet {
|
||||
let square = piece.square();
|
||||
|
||||
let blockers = position.occupied_squares();
|
||||
let blockers = board.occupied_squares();
|
||||
let empty_squares = !blockers;
|
||||
let (friendly_pieces, opposing_pieces) = position.all_pieces();
|
||||
let (friendly_pieces, opposing_pieces) = board.all_pieces();
|
||||
|
||||
let mut all_moves = BitBoard::empty();
|
||||
|
||||
|
@ -58,7 +58,7 @@ impl MoveGeneratorInternal for ClassicalMoveGenerator {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{position, position::DiagramFormatter};
|
||||
use crate::position;
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_core::Color;
|
||||
|
||||
|
@ -69,7 +69,7 @@ mod tests {
|
|||
];
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
|
@ -87,10 +87,10 @@ mod tests {
|
|||
White Knight on E5,
|
||||
];
|
||||
|
||||
println!("{}", DiagramFormatter::new(&pos));
|
||||
println!("{}", pos.display());
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
|
@ -109,7 +109,7 @@ mod tests {
|
|||
];
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
|
@ -125,10 +125,10 @@ mod tests {
|
|||
White Bishop on E4,
|
||||
];
|
||||
|
||||
println!("{}", DiagramFormatter::new(&pos));
|
||||
println!("{}", pos.display());
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let bitboard = generator._test_bitboard();
|
||||
let expected = BitBoard::new(
|
||||
0b00000001_10000010_01000100_00101000_00000000_00101000_01000100_10000010,
|
||||
|
|
|
@ -4,10 +4,9 @@
|
|||
//! generating the possible moves for the king in the given position.
|
||||
|
||||
use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||
use crate::Position;
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_board::{castle::Castle, Board};
|
||||
use chessfriend_core::{PlacedPiece, Shape};
|
||||
use chessfriend_moves::Castle;
|
||||
|
||||
move_generator_declaration!(KingMoveGenerator, struct);
|
||||
move_generator_declaration!(KingMoveGenerator, new);
|
||||
|
@ -19,7 +18,7 @@ impl MoveGeneratorInternal for KingMoveGenerator {
|
|||
}
|
||||
|
||||
fn move_set_for_piece(
|
||||
position: &Position,
|
||||
board: &Board,
|
||||
placed_piece: &PlacedPiece,
|
||||
_capture_mask: BitBoard,
|
||||
_push_mask: BitBoard,
|
||||
|
@ -28,13 +27,13 @@ impl MoveGeneratorInternal for KingMoveGenerator {
|
|||
let color = piece.color();
|
||||
let square = placed_piece.square();
|
||||
|
||||
let safe_squares = !position.king_danger(color);
|
||||
let safe_squares = BitBoard::FULL;
|
||||
let all_king_moves = BitBoard::king_moves(square);
|
||||
|
||||
let empty_squares = position.empty_squares();
|
||||
let empty_squares = board.empty_squares();
|
||||
let safe_empty_squares = empty_squares & safe_squares;
|
||||
|
||||
let opposing_pieces = position.bitboard_for_color(color.other());
|
||||
let opposing_pieces = board.bitboard_for_color(color.other());
|
||||
let opposing_pieces_on_safe_squares = opposing_pieces & safe_squares;
|
||||
|
||||
let quiet_moves = all_king_moves & safe_empty_squares;
|
||||
|
@ -44,10 +43,10 @@ impl MoveGeneratorInternal for KingMoveGenerator {
|
|||
.quiet_moves(quiet_moves)
|
||||
.capture_moves(capture_moves);
|
||||
|
||||
if position.player_can_castle(color, Castle::KingSide) {
|
||||
if board.player_can_castle(color, Castle::KingSide) {
|
||||
move_set.kingside_castle();
|
||||
}
|
||||
if position.player_can_castle(color, Castle::QueenSide) {
|
||||
if board.player_can_castle(color, Castle::QueenSide) {
|
||||
move_set.queenside_castle();
|
||||
}
|
||||
|
||||
|
@ -58,21 +57,23 @@ impl MoveGeneratorInternal for KingMoveGenerator {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{assert_move_list, position, test_position, testing::*, PositionBuilder};
|
||||
use crate::{assert_move_list, test_position, testing::*};
|
||||
use chessfriend_bitboard::bitboard;
|
||||
use chessfriend_board::castle::Castle;
|
||||
use chessfriend_core::{piece, Color, Square};
|
||||
use chessfriend_moves::{Builder as MoveBuilder, Castle, Move};
|
||||
use chessfriend_moves::{Builder as MoveBuilder, Move};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
fn one_king() -> TestResult {
|
||||
let pos = position![White King on E4];
|
||||
let pos = test_position![White King on E4];
|
||||
|
||||
let generator = KingMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
KingMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
bitboard![E5, F5, F4, F3, E3, D3, D4, D5]
|
||||
bitboard![E5 F5 F4 F3 E3 D3 D4 D5]
|
||||
);
|
||||
|
||||
let builder = MoveBuilder::push(&piece!(White King on E4));
|
||||
|
@ -96,15 +97,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn one_king_corner() -> TestResult {
|
||||
let pos = position![White King on A1];
|
||||
let pos = test_position![White King on A1];
|
||||
|
||||
let generator = KingMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
KingMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
let generated_bitboard = generator._test_bitboard();
|
||||
let expected_bitboard = bitboard![A2, B2, B1];
|
||||
let expected_bitboard = bitboard![A2 B2 B1];
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
bitboard![A2, B2, B1],
|
||||
bitboard![A2 B2 B1],
|
||||
"Generated:\n{generated_bitboard}\nExpected:\n{expected_bitboard}"
|
||||
);
|
||||
|
||||
|
@ -136,19 +138,19 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn black_king_in_check_by_rook() {
|
||||
let pos = PositionBuilder::new()
|
||||
.place_piece(piece!(White King on E1))
|
||||
.place_piece(piece!(White Rook on E4))
|
||||
.place_piece(piece!(Black King on E7))
|
||||
.to_move(Color::Black)
|
||||
.build();
|
||||
let pos = test_position!(Black, [
|
||||
White King on E1,
|
||||
White Rook on E4,
|
||||
Black King on E7,
|
||||
]);
|
||||
|
||||
assert!(pos.is_king_in_check());
|
||||
|
||||
let generator = KingMoveGenerator::new(&pos, Color::Black, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
KingMoveGenerator::new(&pos.board, Color::Black, BitBoard::FULL, BitBoard::FULL);
|
||||
let generated_moves = generator._test_bitboard();
|
||||
|
||||
let expected_moves = bitboard![F8, F7, F6, D6, D7, D8];
|
||||
let expected_moves = bitboard![F8 F7 F6 D6 D7 D8];
|
||||
|
||||
assert_eq!(generated_moves, expected_moves);
|
||||
}
|
||||
|
@ -164,7 +166,8 @@ mod tests {
|
|||
assert!(pos.player_can_castle(Color::White, Castle::KingSide));
|
||||
assert!(pos.player_can_castle(Color::White, Castle::QueenSide));
|
||||
|
||||
let generator = KingMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
KingMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generated_moves: HashSet<Move> = generator.iter().collect();
|
||||
|
||||
assert!(generated_moves
|
||||
|
@ -187,7 +190,8 @@ mod tests {
|
|||
assert!(pos.player_can_castle(Color::White, Castle::KingSide));
|
||||
assert!(!pos.player_can_castle(Color::White, Castle::QueenSide));
|
||||
|
||||
let generator = KingMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
KingMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generated_moves: HashSet<Move> = generator.iter().collect();
|
||||
|
||||
assert!(generated_moves
|
||||
|
@ -210,7 +214,8 @@ mod tests {
|
|||
assert!(!pos.player_can_castle(Color::White, Castle::KingSide));
|
||||
assert!(pos.player_can_castle(Color::White, Castle::QueenSide));
|
||||
|
||||
let generator = KingMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
KingMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generated_moves: HashSet<Move> = generator.iter().collect();
|
||||
|
||||
assert!(!generated_moves
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||
use crate::Position;
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_board::Board;
|
||||
use chessfriend_core::{PlacedPiece, Shape};
|
||||
|
||||
move_generator_declaration!(KnightMoveGenerator);
|
||||
|
@ -13,13 +13,13 @@ impl MoveGeneratorInternal for KnightMoveGenerator {
|
|||
}
|
||||
|
||||
fn move_set_for_piece(
|
||||
position: &Position,
|
||||
board: &Board,
|
||||
placed_piece: &PlacedPiece,
|
||||
capture_mask: BitBoard,
|
||||
push_mask: BitBoard,
|
||||
) -> MoveSet {
|
||||
let opposing_pieces = position.bitboard_for_color(placed_piece.piece().color().other());
|
||||
let empty_squares = position.empty_squares();
|
||||
let opposing_pieces = board.bitboard_for_color(placed_piece.piece().color().other());
|
||||
let empty_squares = board.empty_squares();
|
||||
let knight_moves = BitBoard::knight_moves(placed_piece.square());
|
||||
|
||||
let quiet_moves = knight_moves & empty_squares & push_mask;
|
||||
|
@ -46,7 +46,7 @@ mod tests {
|
|||
];
|
||||
|
||||
let generator =
|
||||
KnightMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
KnightMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generated_moves: HashSet<_> = generator.iter().collect();
|
||||
|
||||
let piece = piece!(White Knight on E4);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_board::{castle::Castle, en_passant::EnPassant};
|
||||
use chessfriend_core::{PlacedPiece, Square};
|
||||
use chessfriend_moves::{Builder as MoveBuilder, Castle, EnPassant, Move};
|
||||
use chessfriend_moves::{Builder as MoveBuilder, Move};
|
||||
|
||||
/// A set of bitboards defining the moves for a single piece on the board.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
|
@ -63,7 +64,7 @@ impl MoveSet {
|
|||
None => {}
|
||||
}
|
||||
|
||||
self.bitboard().is_set(target_square)
|
||||
self.bitboard().contains(target_square)
|
||||
}
|
||||
|
||||
pub(crate) fn can_castle(&self, castle: Castle) -> bool {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||
use crate::Position;
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_board::{en_passant::EnPassant, Board};
|
||||
use chessfriend_core::{Color, PlacedPiece, Rank, Shape, Square};
|
||||
use chessfriend_moves::{EnPassant, Move};
|
||||
use chessfriend_moves::Move;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -25,21 +25,19 @@ impl MoveGeneratorInternal for PawnMoveGenerator {
|
|||
}
|
||||
|
||||
fn move_set_for_piece(
|
||||
position: &Position,
|
||||
board: &Board,
|
||||
placed_piece: &PlacedPiece,
|
||||
capture_mask: BitBoard,
|
||||
push_mask: BitBoard,
|
||||
) -> MoveSet {
|
||||
let capture_moves = Self::attacks(position, &placed_piece) & capture_mask;
|
||||
let quiet_moves = Self::pushes(position, &placed_piece) & push_mask;
|
||||
let capture_moves = Self::attacks(board, &placed_piece) & capture_mask;
|
||||
let quiet_moves = Self::pushes(board, &placed_piece) & push_mask;
|
||||
|
||||
let mut move_set = MoveSet::new(*placed_piece)
|
||||
.quiet_moves(quiet_moves)
|
||||
.capture_moves(capture_moves);
|
||||
|
||||
if let Some(en_passant) =
|
||||
Self::en_passant(position, placed_piece, &push_mask, &capture_mask)
|
||||
{
|
||||
if let Some(en_passant) = Self::en_passant(board, placed_piece, &push_mask, &capture_mask) {
|
||||
move_set.en_passant(en_passant);
|
||||
}
|
||||
|
||||
|
@ -49,13 +47,13 @@ impl MoveGeneratorInternal for PawnMoveGenerator {
|
|||
|
||||
impl PawnMoveGenerator {
|
||||
pub(super) fn new(
|
||||
position: &Position,
|
||||
board: &Board,
|
||||
player_to_move: Color,
|
||||
capture_mask: BitBoard,
|
||||
push_mask: BitBoard,
|
||||
) -> Self {
|
||||
let move_sets = if !(capture_mask.is_empty() && push_mask.is_empty()) {
|
||||
Self::move_sets(position, player_to_move, capture_mask, push_mask)
|
||||
Self::move_sets(board, player_to_move, capture_mask, push_mask)
|
||||
} else {
|
||||
std::collections::BTreeMap::new()
|
||||
};
|
||||
|
@ -68,32 +66,33 @@ impl PawnMoveGenerator {
|
|||
}
|
||||
|
||||
fn move_sets(
|
||||
position: &Position,
|
||||
board: &Board,
|
||||
color: Color,
|
||||
capture_mask: BitBoard,
|
||||
push_mask: BitBoard,
|
||||
) -> BTreeMap<Square, MoveSet> {
|
||||
let piece = Self::piece(color);
|
||||
let moves_for_pieces =
|
||||
BTreeMap::from_iter(position.bitboard_for_piece(piece).occupied_squares().map(
|
||||
|square| {
|
||||
let moves_for_pieces = BTreeMap::from_iter(
|
||||
board
|
||||
.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);
|
||||
let move_set = Self::move_set_for_piece(board, &piece, capture_mask, push_mask);
|
||||
(square, move_set)
|
||||
},
|
||||
));
|
||||
}),
|
||||
);
|
||||
|
||||
moves_for_pieces
|
||||
}
|
||||
|
||||
fn pushes(position: &Position, piece: &PlacedPiece) -> BitBoard {
|
||||
fn pushes(board: &Board, piece: &PlacedPiece) -> BitBoard {
|
||||
let color = piece.color();
|
||||
let square = piece.square();
|
||||
let bitboard: BitBoard = square.into();
|
||||
|
||||
let starting_rank = Rank::PAWN_STARTING_RANKS[color as usize];
|
||||
let empty_squares = position.empty_squares();
|
||||
let empty_squares = board.empty_squares();
|
||||
|
||||
match color {
|
||||
Color::White => {
|
||||
|
@ -115,21 +114,21 @@ impl PawnMoveGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
fn attacks(position: &Position, piece: &PlacedPiece) -> BitBoard {
|
||||
fn attacks(board: &Board, piece: &PlacedPiece) -> BitBoard {
|
||||
let color = piece.color();
|
||||
|
||||
let opponent_pieces = position.bitboard_for_color(color.other());
|
||||
let opponent_pieces = board.bitboard_for_color(color.other());
|
||||
|
||||
BitBoard::pawn_attacks(piece.square(), color) & opponent_pieces
|
||||
}
|
||||
|
||||
fn en_passant(
|
||||
position: &Position,
|
||||
board: &Board,
|
||||
piece: &PlacedPiece,
|
||||
push_mask: &BitBoard,
|
||||
capture_mask: &BitBoard,
|
||||
) -> Option<EnPassant> {
|
||||
match position.en_passant() {
|
||||
match board.en_passant() {
|
||||
Some(en_passant) => {
|
||||
let target_square: BitBoard = en_passant.target_square().into();
|
||||
let capture_square: BitBoard = en_passant.capture_square().into();
|
||||
|
@ -147,7 +146,7 @@ impl PawnMoveGenerator {
|
|||
return None;
|
||||
}
|
||||
|
||||
match position.piece_on_square(en_passant.capture_square()) {
|
||||
match board.piece_on_square(en_passant.capture_square()) {
|
||||
Some(_) => Some(en_passant),
|
||||
None => None,
|
||||
}
|
||||
|
@ -173,10 +172,7 @@ impl PawnMoveGenerator {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
assert_move_list, formatted_move_list, position::DiagramFormatter, test_position,
|
||||
testing::*,
|
||||
};
|
||||
use crate::{assert_move_list, formatted_move_list, test_position, testing::*};
|
||||
use chessfriend_core::{piece, Color, Square};
|
||||
use chessfriend_moves::{Builder as MoveBuilder, Move};
|
||||
use std::collections::HashSet;
|
||||
|
@ -185,7 +181,8 @@ mod tests {
|
|||
fn one_double_push() -> TestResult {
|
||||
let pos = test_position![White Pawn on E2];
|
||||
|
||||
let generator = PawnMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
PawnMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
let pawn = piece!(White Pawn on E2);
|
||||
let expected_moves = HashSet::from_iter([
|
||||
|
@ -204,7 +201,8 @@ mod tests {
|
|||
fn one_single_push() -> TestResult {
|
||||
let pos = test_position![White Pawn on E3];
|
||||
|
||||
let generator = PawnMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
PawnMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generated_moves: HashSet<_> = generator.iter().collect();
|
||||
|
||||
let expected_moves = HashSet::from_iter([MoveBuilder::push(&piece!(White Pawn on E3))
|
||||
|
@ -223,9 +221,8 @@ mod tests {
|
|||
White Knight on E4,
|
||||
];
|
||||
|
||||
println!("{}", DiagramFormatter::new(&pos));
|
||||
|
||||
let generator = PawnMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
PawnMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
let expected_moves = HashSet::from_iter([MoveBuilder::push(&piece!(White Pawn on E2))
|
||||
.to(Square::E3)
|
||||
|
@ -245,7 +242,8 @@ mod tests {
|
|||
White Knight on E3,
|
||||
];
|
||||
|
||||
let generator = PawnMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
PawnMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
let generated_moves: HashSet<_> = generator.iter().collect();
|
||||
let expected_moves: HashSet<_> = HashSet::new();
|
||||
|
@ -261,7 +259,8 @@ mod tests {
|
|||
Black Knight on D5,
|
||||
];
|
||||
|
||||
let generator = PawnMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
PawnMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
let expected_moves = HashSet::from_iter([MoveBuilder::push(&piece!(White Pawn on E4))
|
||||
.capturing_on(Square::D5)
|
||||
|
@ -283,7 +282,8 @@ mod tests {
|
|||
Black Queen on F5,
|
||||
];
|
||||
|
||||
let generator = PawnMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
PawnMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
let builder = MoveBuilder::push(&piece!(White Pawn on E4));
|
||||
let expected_moves = HashSet::from_iter([
|
||||
|
@ -309,7 +309,8 @@ mod tests {
|
|||
Black Pawn on E4,
|
||||
], D3);
|
||||
|
||||
let generator = PawnMoveGenerator::new(&pos, Color::Black, BitBoard::FULL, BitBoard::FULL);
|
||||
let generator =
|
||||
PawnMoveGenerator::new(&pos.board, Color::Black, BitBoard::FULL, BitBoard::FULL);
|
||||
let generated_moves: HashSet<Move> = generator.iter().collect();
|
||||
|
||||
let builder = MoveBuilder::push(&piece!(Black Pawn on E4));
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||
use crate::Position;
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_board::Board;
|
||||
use chessfriend_core::{Direction, PlacedPiece, Shape};
|
||||
|
||||
move_generator_declaration!(ClassicalMoveGenerator);
|
||||
|
@ -13,7 +13,7 @@ impl MoveGeneratorInternal for ClassicalMoveGenerator {
|
|||
}
|
||||
|
||||
fn move_set_for_piece(
|
||||
position: &Position,
|
||||
board: &Board,
|
||||
placed_piece: &PlacedPiece,
|
||||
capture_mask: BitBoard,
|
||||
push_mask: BitBoard,
|
||||
|
@ -22,10 +22,10 @@ impl MoveGeneratorInternal for ClassicalMoveGenerator {
|
|||
let color = piece.color();
|
||||
let square = placed_piece.square();
|
||||
|
||||
let blockers = position.occupied_squares();
|
||||
let blockers = board.occupied_squares();
|
||||
let empty_squares = !blockers;
|
||||
let friendly_pieces = position.bitboard_for_color(color);
|
||||
let opposing_pieces = position.bitboard_for_color(color.other());
|
||||
let friendly_pieces = board.bitboard_for_color(color);
|
||||
let opposing_pieces = board.bitboard_for_color(color.other());
|
||||
|
||||
let mut all_moves = BitBoard::empty();
|
||||
|
||||
|
@ -65,22 +65,22 @@ impl MoveGeneratorInternal for ClassicalMoveGenerator {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{position, position::DiagramFormatter};
|
||||
use crate::test_position;
|
||||
use chessfriend_bitboard::{bitboard, BitBoard};
|
||||
use chessfriend_core::Color;
|
||||
|
||||
#[test]
|
||||
fn classical_single_queen_bitboard() {
|
||||
let pos = position![White Queen on B2];
|
||||
let pos = test_position![White Queen on B2];
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let bitboard = generator._test_bitboard();
|
||||
let expected = bitboard![
|
||||
A2, C2, D2, E2, F2, G2, H2, // Rank
|
||||
B1, B3, B4, B5, B6, B7, B8, // File
|
||||
A1, C3, D4, E5, F6, G7, H8, // Diagonal
|
||||
C1, A3 // Anti-diagonal
|
||||
A2 C2 D2 E2 F2 G2 H2 // Rank
|
||||
B1 B3 B4 B5 B6 B7 B8 // File
|
||||
A1 C3 D4 E5 F6 G7 H8 // Diagonal
|
||||
C1 A3 // Anti-diagonal
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
|
@ -93,15 +93,13 @@ mod tests {
|
|||
/// Test that a rook can move up to, but not onto, a friendly piece.
|
||||
#[test]
|
||||
fn classical_single_queen_with_same_color_blocker_bitboard() {
|
||||
let pos = position![
|
||||
let pos = test_position![
|
||||
White Queen on A1,
|
||||
White Knight on E1,
|
||||
];
|
||||
|
||||
println!("{}", DiagramFormatter::new(&pos));
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
let bitboard = generator._test_bitboard();
|
||||
let expected = BitBoard::new(
|
||||
0b10000001_01000001_00100001_00010001_00001001_00000101_00000011_00001110,
|
||||
|
@ -117,41 +115,39 @@ mod tests {
|
|||
/// Test that a rook can move up to, and then capture, an enemy piece.
|
||||
#[test]
|
||||
fn classical_single_queen_with_opposing_color_blocker_bitboard() {
|
||||
let pos = position![
|
||||
let pos = test_position![
|
||||
White Queen on B2,
|
||||
Black Knight on E5,
|
||||
];
|
||||
println!("{}", DiagramFormatter::new(&pos));
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
bitboard![
|
||||
A2, C2, D2, E2, F2, G2, H2, // Rank
|
||||
B1, B3, B4, B5, B6, B7, B8, // File
|
||||
A1, C3, D4, E5, // Diagonal
|
||||
C1, A3 // Anti-diagonal
|
||||
A2 C2 D2 E2 F2 G2 H2 // Rank
|
||||
B1 B3 B4 B5 B6 B7 B8 // File
|
||||
A1 C3 D4 E5 // Diagonal
|
||||
C1 A3 // Anti-diagonal
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classical_single_queen_in_center() {
|
||||
let pos = position![White Queen on D3];
|
||||
println!("{}", DiagramFormatter::new(&pos));
|
||||
let pos = test_position![White Queen on D3];
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
bitboard![
|
||||
A3, B3, C3, E3, F3, G3, H3, // Rank
|
||||
D1, D2, D4, D5, D6, D7, D8, // File
|
||||
B1, C2, E4, F5, G6, H7, // Diagonal
|
||||
F1, E2, C4, B5, A6, // Anti-diagonal
|
||||
A3 B3 C3 E3 F3 G3 H3 // Rank
|
||||
D1 D2 D4 D5 D6 D7 D8 // File
|
||||
B1 C2 E4 F5 G6 H7 // Diagonal
|
||||
F1 E2 C4 B5 A6 // Anti-diagonal
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||
use crate::Position;
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
use chessfriend_board::Board;
|
||||
use chessfriend_core::{Direction, PlacedPiece, Shape};
|
||||
|
||||
move_generator_declaration!(ClassicalMoveGenerator);
|
||||
|
@ -13,7 +13,7 @@ impl MoveGeneratorInternal for ClassicalMoveGenerator {
|
|||
}
|
||||
|
||||
fn move_set_for_piece(
|
||||
position: &Position,
|
||||
board: &Board,
|
||||
placed_piece: &PlacedPiece,
|
||||
capture_mask: BitBoard,
|
||||
push_mask: BitBoard,
|
||||
|
@ -22,10 +22,10 @@ impl MoveGeneratorInternal for ClassicalMoveGenerator {
|
|||
let color = piece.color();
|
||||
let square = placed_piece.square();
|
||||
|
||||
let blockers = position.occupied_squares();
|
||||
let blockers = board.occupied_squares();
|
||||
let empty_squares = !blockers;
|
||||
let friendly_pieces = position.bitboard_for_color(color);
|
||||
let opposing_pieces = position.bitboard_for_color(color.other());
|
||||
let friendly_pieces = board.bitboard_for_color(color);
|
||||
let opposing_pieces = board.bitboard_for_color(color.other());
|
||||
|
||||
let mut all_moves = BitBoard::empty();
|
||||
|
||||
|
@ -61,7 +61,7 @@ impl MoveGeneratorInternal for ClassicalMoveGenerator {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{position::DiagramFormatter, test_position};
|
||||
use crate::test_position;
|
||||
use chessfriend_bitboard::{bitboard, BitBoard};
|
||||
use chessfriend_core::Color;
|
||||
|
||||
|
@ -70,11 +70,11 @@ mod tests {
|
|||
let pos = test_position![White Rook on A2];
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
bitboard![A1, A3, A4, A5, A6, A7, A8, B2, C2, D2, E2, F2, G2, H2]
|
||||
bitboard![A1 A3 A4 A5 A6 A7 A8 B2 C2 D2 E2 F2 G2 H2]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -86,10 +86,10 @@ mod tests {
|
|||
White Knight on E1,
|
||||
];
|
||||
|
||||
println!("{}", DiagramFormatter::new(&pos));
|
||||
println!("{}", pos.display());
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
|
@ -108,11 +108,11 @@ mod tests {
|
|||
];
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
bitboard![A2, A3, A4, A5, A6, A7, A8, B1, C1, D1, E1]
|
||||
bitboard![A2 A3 A4 A5 A6 A7 A8 B1 C1 D1 E1]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -121,11 +121,11 @@ mod tests {
|
|||
let pos = test_position![White Rook on D4];
|
||||
|
||||
let generator =
|
||||
ClassicalMoveGenerator::new(&pos, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
ClassicalMoveGenerator::new(&pos.board, Color::White, BitBoard::FULL, BitBoard::FULL);
|
||||
|
||||
assert_eq!(
|
||||
generator._test_bitboard(),
|
||||
bitboard![A4, B4, C4, E4, F4, G4, H4, D1, D2, D3, D5, D6, D7, D8]
|
||||
bitboard![A4 B4 C4 E4 F4 G4 H4 D1 D2 D3 D5 D6 D7 D8]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue