Add 'Direction::move_board'
Encapsulates the way to move a piece on a board, avoiding the need to mask and shift by hand.
This commit is contained in:
parent
b840bfc570
commit
924689ec02
|
@ -1,3 +1,5 @@
|
|||
use super::{Bitboard, Rank};
|
||||
|
||||
/// A direction on the board. Either along the rook, bishop, or knight directions
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum Direction {
|
||||
|
@ -20,3 +22,525 @@ pub enum Direction {
|
|||
NorthEastEast,
|
||||
NorthNorthEast,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
/// Move every piece on a board along the given direction. Do not wrap around the board.
|
||||
#[inline(always)]
|
||||
pub fn move_board(self, board: Bitboard) -> Bitboard {
|
||||
// No need to filter for A/H ranks thanks to wrapping
|
||||
match self {
|
||||
Self::North => (board - Rank::Eighth.into_bitboard()) << 1,
|
||||
Self::West => board >> 8,
|
||||
Self::South => (board - Rank::First.into_bitboard()) >> 1,
|
||||
Self::East => board << 8,
|
||||
|
||||
Self::NorthWest => (board - Rank::Eighth.into_bitboard()) >> 7,
|
||||
Self::SouthWest => (board - Rank::First.into_bitboard()) >> 9,
|
||||
Self::SouthEast => (board - Rank::First.into_bitboard()) << 7,
|
||||
Self::NorthEast => (board - Rank::Eighth.into_bitboard()) << 9,
|
||||
|
||||
Self::NorthNorthWest => {
|
||||
(board - Rank::Eighth.into_bitboard() - Rank::Seventh.into_bitboard()) >> 6
|
||||
}
|
||||
Self::NorthWestWest => (board - Rank::Eighth.into_bitboard()) >> 15,
|
||||
Self::SouthWestWest => (board - Rank::First.into_bitboard()) >> 17,
|
||||
Self::SouthSouthWest => {
|
||||
(board - Rank::First.into_bitboard() - Rank::Second.into_bitboard()) >> 10
|
||||
}
|
||||
Self::SouthSouthEast => {
|
||||
(board - Rank::First.into_bitboard() - Rank::Second.into_bitboard()) << 6
|
||||
}
|
||||
Self::SouthEastEast => (board - Rank::First.into_bitboard()) << 15,
|
||||
Self::NorthEastEast => (board - Rank::Eighth.into_bitboard()) << 17,
|
||||
Self::NorthNorthEast => {
|
||||
(board - Rank::Eighth.into_bitboard() - Rank::Seventh.into_bitboard()) << 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::board::Square;
|
||||
|
||||
#[test]
|
||||
fn north() {
|
||||
assert_eq!(
|
||||
Direction::North.move_board(Square::A1.into_bitboard()),
|
||||
Square::A2.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::North.move_board(Square::A2.into_bitboard()),
|
||||
Square::A3.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::North.move_board(Square::A7.into_bitboard()),
|
||||
Square::A8.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::North.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn west() {
|
||||
assert_eq!(
|
||||
Direction::West.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::West.move_board(Square::B1.into_bitboard()),
|
||||
Square::A1.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::West.move_board(Square::G1.into_bitboard()),
|
||||
Square::F1.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::West.move_board(Square::H1.into_bitboard()),
|
||||
Square::G1.into_bitboard()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn south() {
|
||||
assert_eq!(
|
||||
Direction::South.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::South.move_board(Square::A2.into_bitboard()),
|
||||
Square::A1.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::South.move_board(Square::A7.into_bitboard()),
|
||||
Square::A6.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::South.move_board(Square::A8.into_bitboard()),
|
||||
Square::A7.into_bitboard()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn east() {
|
||||
assert_eq!(
|
||||
Direction::East.move_board(Square::A1.into_bitboard()),
|
||||
Square::B1.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::East.move_board(Square::B1.into_bitboard()),
|
||||
Square::C1.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::East.move_board(Square::G1.into_bitboard()),
|
||||
Square::H1.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::East.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn north_west() {
|
||||
assert_eq!(
|
||||
Direction::NorthWest.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWest.move_board(Square::B1.into_bitboard()),
|
||||
Square::A2.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWest.move_board(Square::H1.into_bitboard()),
|
||||
Square::G2.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWest.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWest.move_board(Square::B8.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWest.move_board(Square::H8.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn south_west() {
|
||||
assert_eq!(
|
||||
Direction::SouthWest.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWest.move_board(Square::B1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWest.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWest.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWest.move_board(Square::B8.into_bitboard()),
|
||||
Square::A7.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWest.move_board(Square::H8.into_bitboard()),
|
||||
Square::G7.into_bitboard()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn south_east() {
|
||||
assert_eq!(
|
||||
Direction::SouthEast.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEast.move_board(Square::B1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEast.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEast.move_board(Square::A8.into_bitboard()),
|
||||
Square::B7.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEast.move_board(Square::B8.into_bitboard()),
|
||||
Square::C7.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEast.move_board(Square::H8.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn north_east() {
|
||||
assert_eq!(
|
||||
Direction::NorthEast.move_board(Square::A1.into_bitboard()),
|
||||
Square::B2.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEast.move_board(Square::B1.into_bitboard()),
|
||||
Square::C2.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEast.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEast.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEast.move_board(Square::B8.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEast.move_board(Square::H8.into_bitboard()),
|
||||
Bitboard::EMPTY
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn north_north_west() {
|
||||
assert_eq!(
|
||||
Direction::NorthNorthWest.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthWest.move_board(Square::B2.into_bitboard()),
|
||||
Square::A4.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthWest.move_board(Square::H1.into_bitboard()),
|
||||
Square::G3.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthWest.move_board(Square::G2.into_bitboard()),
|
||||
Square::F4.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthWest.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthWest.move_board(Square::B7.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthWest.move_board(Square::H8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthWest.move_board(Square::G7.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn north_west_west() {
|
||||
assert_eq!(
|
||||
Direction::NorthWestWest.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWestWest.move_board(Square::B2.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWestWest.move_board(Square::H1.into_bitboard()),
|
||||
Square::F2.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWestWest.move_board(Square::G2.into_bitboard()),
|
||||
Square::E3.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWestWest.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWestWest.move_board(Square::B7.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWestWest.move_board(Square::H8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthWestWest.move_board(Square::G7.into_bitboard()),
|
||||
Square::E8.into_bitboard()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn south_west_west() {
|
||||
assert_eq!(
|
||||
Direction::SouthWestWest.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWestWest.move_board(Square::B2.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWestWest.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWestWest.move_board(Square::G2.into_bitboard()),
|
||||
Square::E1.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWestWest.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWestWest.move_board(Square::B7.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWestWest.move_board(Square::H8.into_bitboard()),
|
||||
Square::F7.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthWestWest.move_board(Square::G7.into_bitboard()),
|
||||
Square::E6.into_bitboard()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn south_south_west() {
|
||||
assert_eq!(
|
||||
Direction::SouthSouthWest.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthWest.move_board(Square::B2.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthWest.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthWest.move_board(Square::G2.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthWest.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthWest.move_board(Square::B7.into_bitboard()),
|
||||
Square::A5.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthWest.move_board(Square::H8.into_bitboard()),
|
||||
Square::G6.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthWest.move_board(Square::G7.into_bitboard()),
|
||||
Square::F5.into_bitboard()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn south_south_east() {
|
||||
assert_eq!(
|
||||
Direction::SouthSouthEast.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthEast.move_board(Square::B2.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthEast.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthEast.move_board(Square::G2.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthEast.move_board(Square::A8.into_bitboard()),
|
||||
Square::B6.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthEast.move_board(Square::B7.into_bitboard()),
|
||||
Square::C5.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthEast.move_board(Square::H8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthSouthEast.move_board(Square::G7.into_bitboard()),
|
||||
Square::H5.into_bitboard()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn south_east_east() {
|
||||
assert_eq!(
|
||||
Direction::SouthEastEast.move_board(Square::A1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEastEast.move_board(Square::B2.into_bitboard()),
|
||||
Square::D1.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEastEast.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEastEast.move_board(Square::G2.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEastEast.move_board(Square::A8.into_bitboard()),
|
||||
Square::C7.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEastEast.move_board(Square::B7.into_bitboard()),
|
||||
Square::D6.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEastEast.move_board(Square::H8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::SouthEastEast.move_board(Square::G7.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn north_east_east() {
|
||||
assert_eq!(
|
||||
Direction::NorthEastEast.move_board(Square::A1.into_bitboard()),
|
||||
Square::C2.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEastEast.move_board(Square::B2.into_bitboard()),
|
||||
Square::D3.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEastEast.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEastEast.move_board(Square::G2.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEastEast.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEastEast.move_board(Square::B7.into_bitboard()),
|
||||
Square::D8.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEastEast.move_board(Square::H8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthEastEast.move_board(Square::G7.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn north_north_east() {
|
||||
assert_eq!(
|
||||
Direction::NorthNorthEast.move_board(Square::A1.into_bitboard()),
|
||||
Square::B3.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthEast.move_board(Square::B2.into_bitboard()),
|
||||
Square::C4.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthEast.move_board(Square::H1.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthEast.move_board(Square::G2.into_bitboard()),
|
||||
Square::H4.into_bitboard()
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthEast.move_board(Square::A8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthEast.move_board(Square::B7.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthEast.move_board(Square::H8.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
assert_eq!(
|
||||
Direction::NorthNorthEast.move_board(Square::G7.into_bitboard()),
|
||||
Bitboard::EMPTY,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue