use chessframe::{
bitboard::{BitBoard, EMPTY},
board::*,
chess_move::ChessMove,
color::Color,
error::Error,
piece::Piece,
square::Square,
};
#[test]
fn test_square_to_bitboard() {
macro_rules! generate_assertions {
($($x:literal),+) => {
$(
assert_eq!(BitBoard::from_square(Square::new(&x)), BitBoard(1 << $x));
)+
};
($start:literal..$end:literal) => {
{
for i in $start..$end {
assert_eq!(BitBoard::from_square(Square::new(i)), BitBoard(1 << i));
}
}
}
}
generate_assertions!(0..64);
}
#[test]
#[rustfmt::skip]
fn test_from_fen_starting_position() {
let fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
let board = Board::from_fen(fen);
for file in 0..8 {
assert!(board.pieces_color(Piece::Pawn, Color::White).is_set(Square::new(8 + file)));
}
for file in 0..8 {
assert!(board.pieces_color(Piece::Pawn, Color::Black).is_set(Square::new(48 + file)));
}
assert!(board.pieces_color(Piece::Rook, Color::White).is_set(Square::A1)); assert!(board.pieces_color(Piece::Knight, Color::White).is_set(Square::B1)); assert!(board.pieces_color(Piece::Bishop, Color::White).is_set(Square::C1)); assert!(board.pieces_color(Piece::Queen, Color::White).is_set(Square::D1)); assert!(board.pieces_color(Piece::King, Color::White).is_set(Square::E1)); assert!(board.pieces_color(Piece::Bishop, Color::White).is_set(Square::F1)); assert!(board.pieces_color(Piece::Knight, Color::White).is_set(Square::G1)); assert!(board.pieces_color(Piece::Rook, Color::White).is_set(Square::H1));
assert!(board.pieces_color(Piece::Rook, Color::Black).is_set(Square::A8)); assert!(board.pieces_color(Piece::Knight, Color::Black).is_set(Square::B8)); assert!(board.pieces_color(Piece::Bishop, Color::Black).is_set(Square::C8)); assert!(board.pieces_color(Piece::Queen, Color::Black).is_set(Square::D8)); assert!(board.pieces_color(Piece::King, Color::Black).is_set(Square::E8)); assert!(board.pieces_color(Piece::Bishop, Color::Black).is_set(Square::F8)); assert!(board.pieces_color(Piece::Knight, Color::Black).is_set(Square::G8)); assert!(board.pieces_color(Piece::Rook, Color::Black).is_set(Square::H8));
assert_eq!(board.side_to_move, Color::White);
assert!(board.castling_rights.can_castle(Color::White, true)); assert!(board.castling_rights.can_castle(Color::White, false)); assert!(board.castling_rights.can_castle(Color::Black, true)); assert!(board.castling_rights.can_castle(Color::Black, false));
assert!(board.en_passant_square.is_none());
}
#[test]
fn test_infer_move() {
let fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
let mut board = Board::from_fen(fen);
let mv = "e2e4";
assert_eq!(
board.infer_move(mv).unwrap(),
ChessMove::new(Square::E2, Square::E4)
);
let mv = "b1c3";
assert_eq!(
board.infer_move(mv).unwrap(),
ChessMove::new(Square::B1, Square::C3)
);
}
#[test]
fn test_validate_move() {
let fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
let mut board = Board::from_fen(fen);
{
let mut board = board.clone();
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::Pawn, Color::White),
BitBoard(0x000000000000FF00)
);
assert_eq!(board.en_passant_square, None);
assert_eq!(
board.validate_move(&ChessMove::new(Square::E2, Square::E5)),
Err(Error::InvalidMove)
);
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::Pawn, Color::White),
BitBoard(0x000000000000FF00)
);
assert_eq!(board.en_passant_square, None);
}
{
let mut board = board.clone();
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::King, Color::White),
BitBoard(0x000000000000010)
);
assert_eq!(
board.validate_move(&ChessMove::new(Square::E1, Square::D1)),
Err(Error::InvalidMove)
);
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::King, Color::White),
BitBoard(0x000000000000010)
);
}
{
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::King, Color::White),
BitBoard(0x000000000000010)
);
assert_eq!(
board.validate_move(&ChessMove::new(Square::E1, Square::G1)),
Err(Error::InvalidMove)
);
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::King, Color::White),
BitBoard(0x000000000000010)
);
}
{
let fen = "r1bqk2r/ppp2ppp/2np1n2/4p3/1bB1P3/2NP1N2/PPP2PPP/R1BQK2R w KQkq - 0 6";
let mut board = Board::from_fen(fen);
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::Knight, Color::White),
BitBoard(0x000000000240000)
);
assert_eq!(
board.validate_move(&ChessMove::new(Square::C3, Square::D5)),
Err(Error::CannotMovePinned)
);
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::Knight, Color::White),
BitBoard(0x000000000240000)
);
}
}
#[test]
fn test_make_move() {
let fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
let board = Board::from_fen(fen);
{
let mut board = board.clone();
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::Pawn, Color::White),
BitBoard(0x000000000000FF00)
);
assert_eq!(board.en_passant_square, None);
assert_eq!(
board.make_move(&ChessMove::new(Square::E2, Square::E4)),
Ok(())
);
assert_eq!(board.side_to_move, Color::Black);
assert_eq!(
board.pieces_color(Piece::Pawn, Color::White),
BitBoard(0x00000001000EF00)
);
assert_eq!(board.en_passant_square, None);
}
}
#[test]
fn test_pinned_bitboard() {
let fen = "r1bqk2r/pppp1ppp/2n2n2/4p3/1bB1P3/3P1N2/PPP2PPP/RNBQK2R w KQkq - 1 5";
let mut board = Board::from_fen(fen);
assert_eq!(board.pinned, EMPTY);
board
.make_move(&ChessMove::new(Square::B1, Square::C3))
.unwrap();
board
.make_move(&ChessMove::new(Square::E8, Square::G8))
.unwrap();
assert_eq!(board.pinned, BitBoard(0x40000));
}
#[test]
fn test_hash() {
let fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
let mut board = Board::from_fen(fen);
assert_eq!(board.hash, 0x89FB87680071BBF1);
assert_eq!(board.hash(), 0x1D0D28B8BD0816CA);
board
.make_move(&ChessMove::new(Square::E2, Square::E4))
.unwrap();
assert_eq!(board.hash, 0xD392461D4BD9B816);
assert_eq!(board.hash(), 0xE4866C8BF44CB8F2);
}
#[test]
fn test_can_castle() {
let fen = "r1bqk2r/ppp2ppp/2np1n2/2b1p3/2B1P3/2PP1N2/PP3PPP/RNBQK2R w KQkq - 1 6";
let mut board = Board::from_fen(fen);
{
let board = board.clone();
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::King, Color::White),
BitBoard(0x000000000000010)
);
assert_eq!(board.can_castle(true), Ok(()));
assert_eq!(board.side_to_move, Color::White);
assert_eq!(
board.pieces_color(Piece::King, Color::White),
BitBoard(0x000000000000010)
);
}
assert_eq!(
board.make_move(&ChessMove::new(Square::E1, Square::G1)),
Ok(())
);
assert_eq!(
board.pieces_color(Piece::King, Color::White),
BitBoard(0x000000000000040)
);
assert_eq!(
board.pieces_color(Piece::Rook, Color::White),
BitBoard(0x000000000000021)
);
{
assert_eq!(board.side_to_move, Color::Black);
assert_eq!(
board.pieces_color(Piece::King, Color::Black),
BitBoard(0x1000000000000000)
);
assert_eq!(board.can_castle(true), Ok(()));
assert_eq!(board.side_to_move, Color::Black);
assert_eq!(
board.pieces_color(Piece::King, Color::Black),
BitBoard(0x1000000000000000)
);
}
}