[board] Update all the move generator submodules to use MoveBuilder instead of Move
Along the way update "manual" piece creation to use the macros instead.
This commit is contained in:
parent
ca9ff94d2a
commit
2174bcf009
7 changed files with 79 additions and 73 deletions
|
@ -4,7 +4,7 @@ use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||||
use crate::{
|
use crate::{
|
||||||
piece::{Color, Piece, PlacedPiece},
|
piece::{Color, Piece, PlacedPiece},
|
||||||
square::Direction,
|
square::Direction,
|
||||||
BitBoard, Move, Position,
|
BitBoard, MoveBuilder, Position,
|
||||||
};
|
};
|
||||||
|
|
||||||
move_generator_declaration!(ClassicalMoveGenerator);
|
move_generator_declaration!(ClassicalMoveGenerator);
|
||||||
|
@ -49,7 +49,7 @@ impl<'pos> MoveGeneratorInternal for ClassicalMoveGenerator<'pos> {
|
||||||
let quiet_moves_bb = all_moves & (empty_squares | !friendly_pieces);
|
let quiet_moves_bb = all_moves & (empty_squares | !friendly_pieces);
|
||||||
let capture_moves_bb = all_moves & opposing_pieces;
|
let capture_moves_bb = all_moves & opposing_pieces;
|
||||||
|
|
||||||
let map_to_move = |sq| Move::new(piece, square, sq);
|
let map_to_move = |sq| MoveBuilder::new(piece, square, sq).build();
|
||||||
let quiet_moves = quiet_moves_bb.occupied_squares().map(map_to_move);
|
let quiet_moves = quiet_moves_bb.occupied_squares().map(map_to_move);
|
||||||
let capture_moves = capture_moves_bb.occupied_squares().map(map_to_move);
|
let capture_moves = capture_moves_bb.occupied_squares().map(map_to_move);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||||
use crate::{
|
use crate::{
|
||||||
piece::{Color, Piece, PlacedPiece},
|
piece::{Color, Piece, PlacedPiece},
|
||||||
position::BoardSide,
|
position::BoardSide,
|
||||||
BitBoard, Move, Position,
|
BitBoard, Move, MoveBuilder, Position,
|
||||||
};
|
};
|
||||||
|
|
||||||
move_generator_declaration!(KingMoveGenerator, struct);
|
move_generator_declaration!(KingMoveGenerator, struct);
|
||||||
|
@ -56,7 +56,7 @@ impl<'pos> MoveGeneratorInternal for KingMoveGenerator<'pos> {
|
||||||
// TODO: Handle checks. Prevent moving a king to a square attacked by a
|
// TODO: Handle checks. Prevent moving a king to a square attacked by a
|
||||||
// piece of the opposite color.
|
// piece of the opposite color.
|
||||||
|
|
||||||
let map_to_move = |sq| Move::new(piece, square, sq);
|
let map_to_move = |sq| MoveBuilder::new(piece, square, sq).build();
|
||||||
|
|
||||||
let king_side_castle = Self::king_side_castle(position, color);
|
let king_side_castle = Self::king_side_castle(position, color);
|
||||||
let queen_side_castle = Self::queen_side_castle(position, color);
|
let queen_side_castle = Self::queen_side_castle(position, color);
|
||||||
|
@ -76,7 +76,7 @@ impl<'pos> MoveGeneratorInternal for KingMoveGenerator<'pos> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{piece::Piece, Position, Square};
|
use crate::{piece, piece::Piece, Position, Square};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -96,14 +96,14 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let expected_moves = [
|
let expected_moves = [
|
||||||
Move::new(Piece::king(Color::White), Square::E4, Square::D5),
|
MoveBuilder::new(piece!(White King), Square::E4, Square::D5).build(),
|
||||||
Move::new(Piece::king(Color::White), Square::E4, Square::E5),
|
MoveBuilder::new(piece!(White King), Square::E4, Square::E5).build(),
|
||||||
Move::new(Piece::king(Color::White), Square::E4, Square::F5),
|
MoveBuilder::new(piece!(White King), Square::E4, Square::F5).build(),
|
||||||
Move::new(Piece::king(Color::White), Square::E4, Square::F4),
|
MoveBuilder::new(piece!(White King), Square::E4, Square::F4).build(),
|
||||||
Move::new(Piece::king(Color::White), Square::E4, Square::F3),
|
MoveBuilder::new(piece!(White King), Square::E4, Square::F3).build(),
|
||||||
Move::new(Piece::king(Color::White), Square::E4, Square::E3),
|
MoveBuilder::new(piece!(White King), Square::E4, Square::E3).build(),
|
||||||
Move::new(Piece::king(Color::White), Square::E4, Square::D3),
|
MoveBuilder::new(piece!(White King), Square::E4, Square::D3).build(),
|
||||||
Move::new(Piece::king(Color::White), Square::E4, Square::D4),
|
MoveBuilder::new(piece!(White King), Square::E4, Square::D4).build(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut generated_moves: HashSet<Move> = generator.iter().cloned().collect();
|
let mut generated_moves: HashSet<Move> = generator.iter().cloned().collect();
|
||||||
|
@ -140,9 +140,9 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let expected_moves = [
|
let expected_moves = [
|
||||||
Move::new(Piece::king(Color::White), Square::A1, Square::A2),
|
MoveBuilder::new(piece!(White King), Square::A1, Square::A2).build(),
|
||||||
Move::new(Piece::king(Color::White), Square::A1, Square::B1),
|
MoveBuilder::new(piece!(White King), Square::A1, Square::B1).build(),
|
||||||
Move::new(Piece::king(Color::White), Square::A1, Square::B2),
|
MoveBuilder::new(piece!(White King), Square::A1, Square::B2).build(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut generated_moves: HashSet<Move> = generator.iter().cloned().collect();
|
let mut generated_moves: HashSet<Move> = generator.iter().cloned().collect();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||||
use crate::{
|
use crate::{
|
||||||
piece::{Color, Piece, PlacedPiece},
|
piece::{Color, Piece, PlacedPiece},
|
||||||
BitBoard, Move, Position,
|
BitBoard, MoveBuilder, Position,
|
||||||
};
|
};
|
||||||
|
|
||||||
move_generator_declaration!(KnightMoveGenerator);
|
move_generator_declaration!(KnightMoveGenerator);
|
||||||
|
@ -21,12 +21,14 @@ impl<'pos> MoveGeneratorInternal for KnightMoveGenerator<'pos> {
|
||||||
let quiet_moves_bb = knight_moves & empty_squares;
|
let quiet_moves_bb = knight_moves & empty_squares;
|
||||||
let capture_moves_bb = knight_moves & opposing_pieces;
|
let capture_moves_bb = knight_moves & opposing_pieces;
|
||||||
|
|
||||||
let quiet_moves = quiet_moves_bb
|
let quiet_moves = quiet_moves_bb.occupied_squares().map(|to_sq| {
|
||||||
.occupied_squares()
|
MoveBuilder::new(placed_piece.piece(), placed_piece.square(), to_sq).build()
|
||||||
.map(|to_sq| Move::new(placed_piece.piece(), placed_piece.square(), to_sq));
|
});
|
||||||
let capture_moves = capture_moves_bb.occupied_squares().map(|to_sq| {
|
let capture_moves = capture_moves_bb.occupied_squares().map(|to_sq| {
|
||||||
let captured_piece = position.piece_on_square(to_sq).unwrap();
|
let captured_piece = position.piece_on_square(to_sq).unwrap();
|
||||||
Move::new(placed_piece.piece(), placed_piece.square(), to_sq).capturing(captured_piece)
|
MoveBuilder::new(placed_piece.piece(), placed_piece.square(), to_sq)
|
||||||
|
.capturing(captured_piece)
|
||||||
|
.build()
|
||||||
});
|
});
|
||||||
|
|
||||||
MoveSet::new(placed_piece)
|
MoveSet::new(placed_piece)
|
||||||
|
@ -38,7 +40,7 @@ impl<'pos> MoveGeneratorInternal for KnightMoveGenerator<'pos> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::Square;
|
use crate::{piece, Move, Square};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -60,14 +62,14 @@ mod tests {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let expected_moves = [
|
let expected_moves = [
|
||||||
Move::new(Piece::knight(Color::White), Square::E4, Square::C3),
|
MoveBuilder::new(piece!(White Knight), Square::E4, Square::C3).build(),
|
||||||
Move::new(Piece::knight(Color::White), Square::E4, Square::D2),
|
MoveBuilder::new(piece!(White Knight), Square::E4, Square::D2).build(),
|
||||||
Move::new(Piece::knight(Color::White), Square::E4, Square::F2),
|
MoveBuilder::new(piece!(White Knight), Square::E4, Square::F2).build(),
|
||||||
Move::new(Piece::knight(Color::White), Square::E4, Square::G3),
|
MoveBuilder::new(piece!(White Knight), Square::E4, Square::G3).build(),
|
||||||
Move::new(Piece::knight(Color::White), Square::E4, Square::C5),
|
MoveBuilder::new(piece!(White Knight), Square::E4, Square::C5).build(),
|
||||||
Move::new(Piece::knight(Color::White), Square::E4, Square::D6),
|
MoveBuilder::new(piece!(White Knight), Square::E4, Square::D6).build(),
|
||||||
Move::new(Piece::knight(Color::White), Square::E4, Square::G5),
|
MoveBuilder::new(piece!(White Knight), Square::E4, Square::G5).build(),
|
||||||
Move::new(Piece::knight(Color::White), Square::E4, Square::F6),
|
MoveBuilder::new(piece!(White Knight), Square::E4, Square::F6).build(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut generated_moves: HashSet<Move> = generator.iter().cloned().collect();
|
let mut generated_moves: HashSet<Move> = generator.iter().cloned().collect();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
piece::{Color, Piece, Shape},
|
piece::{Color, Piece, Shape},
|
||||||
BitBoard, Move, Position,
|
BitBoard, Move, MoveBuilder, Position,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MoveList {
|
enum MoveList {
|
||||||
|
@ -150,14 +150,14 @@ impl<'pos> PawnMoveGenerator<'pos> {
|
||||||
if !(push & empty_squares).is_empty() {
|
if !(push & empty_squares).is_empty() {
|
||||||
let to_sq = push.occupied_squares().next().unwrap();
|
let to_sq = push.occupied_squares().next().unwrap();
|
||||||
|
|
||||||
let r#move = Move::new(piece, from_sq, to_sq);
|
let builder = MoveBuilder::new(piece, from_sq, to_sq);
|
||||||
if !(push & parameters.promotion_rank).is_empty() {
|
if !(push & parameters.promotion_rank).is_empty() {
|
||||||
for shape in Shape::promotable() {
|
for shape in Shape::promotable() {
|
||||||
self.promotion_move_list()
|
self.promotion_move_list()
|
||||||
.push(r#move.clone().promoting_to(*shape));
|
.push(builder.clone().promoting_to(*shape).build());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.quiet_move_list().push(r#move);
|
self.quiet_move_list().push(builder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(pawn & parameters.starting_rank).is_empty() {
|
if !(pawn & parameters.starting_rank).is_empty() {
|
||||||
|
@ -165,7 +165,7 @@ impl<'pos> PawnMoveGenerator<'pos> {
|
||||||
if !(push & empty_squares).is_empty() {
|
if !(push & empty_squares).is_empty() {
|
||||||
let to_sq = push.occupied_squares().next().unwrap();
|
let to_sq = push.occupied_squares().next().unwrap();
|
||||||
self.quiet_move_list()
|
self.quiet_move_list()
|
||||||
.push(Move::new(piece, from_sq, to_sq));
|
.push(MoveBuilder::new(piece, from_sq, to_sq).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,14 +178,14 @@ impl<'pos> PawnMoveGenerator<'pos> {
|
||||||
let to_sq = attack.occupied_squares().next().unwrap();
|
let to_sq = attack.occupied_squares().next().unwrap();
|
||||||
let captured_piece = self.position.piece_on_square(to_sq).unwrap();
|
let captured_piece = self.position.piece_on_square(to_sq).unwrap();
|
||||||
|
|
||||||
let r#move = Move::new(piece, from_sq, to_sq).capturing(captured_piece);
|
let builder = MoveBuilder::new(piece, from_sq, to_sq).capturing(captured_piece);
|
||||||
if !(attack & parameters.promotion_rank).is_empty() {
|
if !(attack & parameters.promotion_rank).is_empty() {
|
||||||
for shape in Shape::promotable() {
|
for shape in Shape::promotable() {
|
||||||
self.capture_move_list()
|
self.capture_move_list()
|
||||||
.push(r#move.clone().promoting_to(*shape));
|
.push(builder.clone().promoting_to(*shape).build());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.capture_move_list().push(r#move);
|
self.capture_move_list().push(builder.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,25 +247,22 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::piece::PlacedPiece;
|
use crate::piece::PlacedPiece;
|
||||||
use crate::position::DiagramFormatter;
|
use crate::position::DiagramFormatter;
|
||||||
use crate::{Position, Square};
|
use crate::{piece, Position, Square};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn one_2square_push() {
|
fn one_2square_push() {
|
||||||
let mut pos = Position::empty();
|
let mut pos = Position::empty();
|
||||||
|
|
||||||
pos.place_piece(Piece::pawn(Color::White), Square::E2)
|
pos.place_piece(piece!(White Pawn), Square::E2)
|
||||||
.expect("Failed to place pawn on e2");
|
.expect("Failed to place pawn on e2");
|
||||||
|
|
||||||
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
||||||
|
|
||||||
let expected_moves = HashSet::from_iter(
|
let expected_moves = HashSet::from_iter([
|
||||||
[
|
MoveBuilder::new(piece!(White Pawn), Square::E2, Square::E3).build(),
|
||||||
Move::new(Piece::pawn(Color::White), Square::E2, Square::E3),
|
MoveBuilder::new(piece!(White Pawn), Square::E2, Square::E4).build(),
|
||||||
Move::new(Piece::pawn(Color::White), Square::E2, Square::E4),
|
]);
|
||||||
]
|
|
||||||
.into_iter(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let generated_moves: HashSet<Move> = generator.collect();
|
let generated_moves: HashSet<Move> = generator.collect();
|
||||||
|
|
||||||
|
@ -281,9 +278,12 @@ mod tests {
|
||||||
|
|
||||||
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
||||||
|
|
||||||
let expected_moves = HashSet::from_iter(
|
let expected_moves = HashSet::from_iter([MoveBuilder::new(
|
||||||
[Move::new(Piece::pawn(Color::White), Square::E3, Square::E4)].into_iter(),
|
Piece::pawn(Color::White),
|
||||||
);
|
Square::E3,
|
||||||
|
Square::E4,
|
||||||
|
)
|
||||||
|
.build()]);
|
||||||
|
|
||||||
let generated_moves: HashSet<Move> = generator.collect();
|
let generated_moves: HashSet<Move> = generator.collect();
|
||||||
|
|
||||||
|
@ -303,9 +303,12 @@ mod tests {
|
||||||
|
|
||||||
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
||||||
|
|
||||||
let expected_moves = HashSet::from_iter(
|
let expected_moves = HashSet::from_iter([MoveBuilder::new(
|
||||||
[Move::new(Piece::pawn(Color::White), Square::E2, Square::E3)].into_iter(),
|
Piece::pawn(Color::White),
|
||||||
);
|
Square::E2,
|
||||||
|
Square::E3,
|
||||||
|
)
|
||||||
|
.build()]);
|
||||||
|
|
||||||
let generated_moves: HashSet<Move> = generator.collect();
|
let generated_moves: HashSet<Move> = generator.collect();
|
||||||
|
|
||||||
|
@ -344,11 +347,13 @@ mod tests {
|
||||||
|
|
||||||
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
||||||
|
|
||||||
let expected_moves = HashSet::from_iter(
|
let expected_moves = HashSet::from_iter([MoveBuilder::new(
|
||||||
[Move::new(Piece::pawn(Color::White), Square::E4, Square::D5)
|
Piece::pawn(Color::White),
|
||||||
.capturing(PlacedPiece::new(Piece::knight(Color::Black), Square::D5))]
|
Square::E4,
|
||||||
.into_iter(),
|
Square::D5,
|
||||||
);
|
)
|
||||||
|
.capturing(piece!(Black Knight on D5))
|
||||||
|
.build()]);
|
||||||
|
|
||||||
let generated_moves: HashSet<Move> = generator.collect();
|
let generated_moves: HashSet<Move> = generator.collect();
|
||||||
|
|
||||||
|
@ -371,15 +376,14 @@ mod tests {
|
||||||
|
|
||||||
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
let generator = PawnMoveGenerator::new(&pos, Color::White);
|
||||||
|
|
||||||
let expected_moves = HashSet::from_iter(
|
let expected_moves = HashSet::from_iter([
|
||||||
[
|
MoveBuilder::new(piece!(White Pawn), Square::E4, Square::D5)
|
||||||
Move::new(Piece::pawn(Color::White), Square::E4, Square::D5)
|
.capturing(piece!(Black Knight on D5))
|
||||||
.capturing(PlacedPiece::new(Piece::knight(Color::Black), Square::D5)),
|
.build(),
|
||||||
Move::new(Piece::pawn(Color::White), Square::E4, Square::F5)
|
MoveBuilder::new(piece!(White Pawn), Square::E4, Square::F5)
|
||||||
.capturing(PlacedPiece::new(Piece::queen(Color::Black), Square::F5)),
|
.capturing(piece!(Black Queen on F5))
|
||||||
]
|
.build(),
|
||||||
.into_iter(),
|
]);
|
||||||
);
|
|
||||||
|
|
||||||
let generated_moves: HashSet<Move> = generator.collect();
|
let generated_moves: HashSet<Move> = generator.collect();
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||||
use crate::{
|
use crate::{
|
||||||
piece::{Color, Piece, PlacedPiece},
|
piece::{Color, Piece, PlacedPiece},
|
||||||
square::Direction,
|
square::Direction,
|
||||||
BitBoard, Move, Position,
|
BitBoard, MoveBuilder, Position,
|
||||||
};
|
};
|
||||||
|
|
||||||
move_generator_declaration!(ClassicalMoveGenerator);
|
move_generator_declaration!(ClassicalMoveGenerator);
|
||||||
|
@ -53,7 +53,7 @@ impl<'pos> MoveGeneratorInternal for ClassicalMoveGenerator<'pos> {
|
||||||
let quiet_moves_bb = all_moves & (empty_squares | !friendly_pieces);
|
let quiet_moves_bb = all_moves & (empty_squares | !friendly_pieces);
|
||||||
let capture_moves_bb = all_moves & opposing_pieces;
|
let capture_moves_bb = all_moves & opposing_pieces;
|
||||||
|
|
||||||
let map_to_move = |sq| Move::new(piece, square, sq);
|
let map_to_move = |sq| MoveBuilder::new(piece, square, sq).build();
|
||||||
let quiet_moves = quiet_moves_bb.occupied_squares().map(map_to_move);
|
let quiet_moves = quiet_moves_bb.occupied_squares().map(map_to_move);
|
||||||
let capture_moves = capture_moves_bb.occupied_squares().map(map_to_move);
|
let capture_moves = capture_moves_bb.occupied_squares().map(map_to_move);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use super::{move_generator_declaration, MoveGeneratorInternal, MoveSet};
|
||||||
use crate::{
|
use crate::{
|
||||||
piece::{Color, Piece, PlacedPiece},
|
piece::{Color, Piece, PlacedPiece},
|
||||||
square::Direction,
|
square::Direction,
|
||||||
BitBoard, Move, Position,
|
BitBoard, MoveBuilder, Position,
|
||||||
};
|
};
|
||||||
|
|
||||||
move_generator_declaration!(ClassicalMoveGenerator);
|
move_generator_declaration!(ClassicalMoveGenerator);
|
||||||
|
@ -49,7 +49,7 @@ impl<'pos> MoveGeneratorInternal for ClassicalMoveGenerator<'pos> {
|
||||||
let quiet_moves_bb = all_moves & (empty_squares | !friendly_pieces);
|
let quiet_moves_bb = all_moves & (empty_squares | !friendly_pieces);
|
||||||
let capture_moves_bb = all_moves & opposing_pieces;
|
let capture_moves_bb = all_moves & opposing_pieces;
|
||||||
|
|
||||||
let map_to_move = |sq| Move::new(piece, square, sq);
|
let map_to_move = |sq| MoveBuilder::new(piece, square, sq).build();
|
||||||
let quiet_moves = quiet_moves_bb.occupied_squares().map(map_to_move);
|
let quiet_moves = quiet_moves_bb.occupied_squares().map(map_to_move);
|
||||||
let capture_moves = capture_moves_bb.occupied_squares().map(map_to_move);
|
let capture_moves = capture_moves_bb.occupied_squares().map(map_to_move);
|
||||||
|
|
||||||
|
|
|
@ -155,8 +155,8 @@ impl Position {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_generator(&self, color: Color) -> Moves {
|
pub fn moves(&self) -> Moves {
|
||||||
Moves::new(self, color)
|
Moves::new(self, self.color_to_move)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a BitBoard representing the set of squares containing a piece.
|
/// Return a BitBoard representing the set of squares containing a piece.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue