This commit is contained in:
Eryn Wells 2025-05-08 17:37:51 -07:00
parent d5cdf273c8
commit 091cc99cb3
42 changed files with 805 additions and 1662 deletions

View file

@ -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,

View file

@ -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

View file

@ -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);

View file

@ -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 {

View file

@ -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));

View file

@ -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
]
);
}

View file

@ -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]
);
}
}