pub struct Board { /* private fields */ }
Expand description
A representation of a chess board. That’s why you’re here, right?
Implementations
sourceimpl Board
impl Board
sourcepub fn from_fen(fen: String) -> Option<Board>
pub fn from_fen(fen: String) -> Option<Board>
Construct a board from a FEN string.
use chess::Board;
let init_position = Board::from_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1".to_owned()).expect("Valid FEN");
assert_eq!(init_position, Board::default());
sourcepub fn status(&self) -> BoardStatus
pub fn status(&self) -> BoardStatus
Is this game Ongoing, is it Stalemate, or is it Checkmate?
use chess::{Board, BoardStatus, Square, Rank, File, ChessMove};
let mut board = Board::default();
assert_eq!(board.status(), BoardStatus::Ongoing);
board = board.make_move_new(ChessMove::new(Square::make_square(Rank::Second, File::E),
Square::make_square(Rank::Fourth, File::E),
None));
assert_eq!(board.status(), BoardStatus::Ongoing);
board = board.make_move_new(ChessMove::new(Square::make_square(Rank::Seventh, File::F),
Square::make_square(Rank::Sixth, File::F),
None));
assert_eq!(board.status(), BoardStatus::Ongoing);
board = board.make_move_new(ChessMove::new(Square::make_square(Rank::Second, File::D),
Square::make_square(Rank::Fourth, File::D),
None));
assert_eq!(board.status(), BoardStatus::Ongoing);
board = board.make_move_new(ChessMove::new(Square::make_square(Rank::Seventh, File::G),
Square::make_square(Rank::Fifth, File::G),
None));
assert_eq!(board.status(), BoardStatus::Ongoing);
board = board.make_move_new(ChessMove::new(Square::make_square(Rank::First, File::D),
Square::make_square(Rank::Fifth, File::H),
None));
assert_eq!(board.status(), BoardStatus::Checkmate);
sourcepub fn combined(&self) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
pub fn combined(&self) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
Grab the “combined” BitBoard
. This is a BitBoard
with every piece.
use chess::{Board, BitBoard, Rank, get_rank};
let board = Board::default();
let combined_should_be = get_rank(Rank::First) |
get_rank(Rank::Second) |
get_rank(Rank::Seventh) |
get_rank(Rank::Eighth);
assert_eq!(board.combined(), combined_should_be);
sourcepub fn color_combined(&self, color: Color) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
pub fn color_combined(&self, color: Color) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
Grab the “color combined” BitBoard
. This is a BitBoard
with every piece of a particular
color.
use chess::{Board, BitBoard, Rank, get_rank, Color};
let board = Board::default();
let white_pieces = get_rank(Rank::First) |
get_rank(Rank::Second);
let black_pieces = get_rank(Rank::Seventh) |
get_rank(Rank::Eighth);
assert_eq!(board.color_combined(Color::White), white_pieces);
assert_eq!(board.color_combined(Color::Black), black_pieces);
sourcepub fn king_square(&self, color: Color) -> Square
pub fn king_square(&self, color: Color) -> Square
Give me the Square
the color
king is on.
use chess::{Board, Square, Color, Rank, File};
let board = Board::default();
assert_eq!(board.king_square(Color::White), Square::make_square(Rank::First, File::E));
assert_eq!(board.king_square(Color::Black), Square::make_square(Rank::Eighth, File::E));
sourcepub fn pieces(&self, piece: Piece) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
pub fn pieces(&self, piece: Piece) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
Grab the “pieces” BitBoard
. This is a BitBoard
with every piece of a particular type.
use chess::{Board, BitBoard, Piece, Square, Rank, File};
// The rooks should be in each corner of the board
let rooks = BitBoard::from_square(Square::make_square(Rank::First, File::A)) |
BitBoard::from_square(Square::make_square(Rank::First, File::H)) |
BitBoard::from_square(Square::make_square(Rank::Eighth, File::A)) |
BitBoard::from_square(Square::make_square(Rank::Eighth, File::H));
let board = Board::default();
assert_eq!(board.pieces(Piece::Rook), rooks);
sourcepub fn castle_rights(&self, color: Color) -> CastleRights
pub fn castle_rights(&self, color: Color) -> CastleRights
Grab the CastleRights
for a particular side.
use chess::{Board, Square, Rank, File, CastleRights, Color, ChessMove};
let move1 = ChessMove::new(Square::make_square(Rank::Second, File::A),
Square::make_square(Rank::Fourth, File::A),
None);
let move2 = ChessMove::new(Square::make_square(Rank::Seventh, File::E),
Square::make_square(Rank::Fifth, File::E),
None);
let move3 = ChessMove::new(Square::make_square(Rank::First, File::A),
Square::make_square(Rank::Second, File::A),
None);
let move4 = ChessMove::new(Square::make_square(Rank::Eighth, File::E),
Square::make_square(Rank::Seventh, File::E),
None);
let mut board = Board::default();
assert_eq!(board.castle_rights(Color::White), CastleRights::Both);
assert_eq!(board.castle_rights(Color::Black), CastleRights::Both);
board = board.make_move_new(move1)
.make_move_new(move2)
.make_move_new(move3)
.make_move_new(move4);
assert_eq!(board.castle_rights(Color::White), CastleRights::KingSide);
assert_eq!(board.castle_rights(Color::Black), CastleRights::NoRights);
sourcepub fn add_castle_rights(&mut self, color: Color, add: CastleRights)
pub fn add_castle_rights(&mut self, color: Color, add: CastleRights)
Add castle rights for a particular side. Note: this can create an invalid position.
sourcepub fn remove_castle_rights(&mut self, color: Color, remove: CastleRights)
pub fn remove_castle_rights(&mut self, color: Color, remove: CastleRights)
Remove castle rights for a particular side.
use chess::{Board, CastleRights, Color};
let mut board = Board::default();
assert_eq!(board.castle_rights(Color::White), CastleRights::Both);
board.remove_castle_rights(Color::White, CastleRights::KingSide);
assert_eq!(board.castle_rights(Color::White), CastleRights::QueenSide);
sourcepub fn side_to_move(&self) -> Color
pub fn side_to_move(&self) -> Color
Who’s turn is it?
use chess::{Board, Color};
let mut board = Board::default();
assert_eq!(board.side_to_move(), Color::White);
sourcepub fn my_castle_rights(&self) -> CastleRights
pub fn my_castle_rights(&self) -> CastleRights
Grab my CastleRights
.
use chess::{Board, Color, CastleRights};
let mut board = Board::default();
board.remove_castle_rights(Color::White, CastleRights::KingSide);
board.remove_castle_rights(Color::Black, CastleRights::QueenSide);
assert_eq!(board.my_castle_rights(), board.castle_rights(Color::White));
sourcepub fn add_my_castle_rights(&mut self, add: CastleRights)
pub fn add_my_castle_rights(&mut self, add: CastleRights)
Add to my CastleRights
. Note: This can make the position invalid.
sourcepub fn remove_my_castle_rights(&mut self, remove: CastleRights)
pub fn remove_my_castle_rights(&mut self, remove: CastleRights)
Remove some of my CastleRights
.
use chess::{Board, CastleRights};
let mut board = Board::default();
assert_eq!(board.my_castle_rights(), CastleRights::Both);
board.remove_my_castle_rights(CastleRights::KingSide);
assert_eq!(board.my_castle_rights(), CastleRights::QueenSide);
sourcepub fn their_castle_rights(&self) -> CastleRights
pub fn their_castle_rights(&self) -> CastleRights
My opponents CastleRights
.
use chess::{Board, Color, CastleRights};
let mut board = Board::default();
board.remove_castle_rights(Color::White, CastleRights::KingSide);
board.remove_castle_rights(Color::Black, CastleRights::QueenSide);
assert_eq!(board.their_castle_rights(), board.castle_rights(Color::Black));
sourcepub fn add_their_castle_rights(&mut self, add: CastleRights)
pub fn add_their_castle_rights(&mut self, add: CastleRights)
Add to my opponents CastleRights
. Note: This can make the position invalid.
sourcepub fn remove_their_castle_rights(&mut self, remove: CastleRights)
pub fn remove_their_castle_rights(&mut self, remove: CastleRights)
Remove some of my opponents CastleRights
.
use chess::{Board, CastleRights};
let mut board = Board::default();
assert_eq!(board.their_castle_rights(), CastleRights::Both);
board.remove_their_castle_rights(CastleRights::KingSide);
assert_eq!(board.their_castle_rights(), CastleRights::QueenSide);
sourcepub fn set_piece(
&self,
piece: Piece,
color: Color,
square: Square
) -> Option<Board>
pub fn set_piece(
&self,
piece: Piece,
color: Color,
square: Square
) -> Option<Board>
For a chess UI: set a piece on a particular square.
use chess::{Board, Piece, Color, Square, Rank, File};
let board = Board::default();
let new_board = board.set_piece(Piece::Queen,
Color::White,
Square::make_square(Rank::Fourth, File::E))
.expect("Valid Position");
assert_eq!(new_board.pieces(Piece::Queen).count(), 3);
sourcepub fn clear_square(&self, square: Square) -> Option<Board>
pub fn clear_square(&self, square: Square) -> Option<Board>
For a chess UI: clear a particular square.
use chess::{Board, Square, Rank, File, Piece};
let board = Board::default();
let new_board = board.clear_square(Square::make_square(Rank::First, File::A))
.expect("Valid Position");
assert_eq!(new_board.pieces(Piece::Rook).count(), 3);
sourcepub fn null_move(&self) -> Option<Board>
pub fn null_move(&self) -> Option<Board>
Switch the color of the player without actually making a move. Returns None if the current player is in check.
use chess::{Board, Color};
let board = Board::default();
assert_eq!(board.side_to_move(), Color::White);
let new_board = board.null_move().expect("Valid Position");
assert_eq!(new_board.side_to_move(), Color::Black);
sourcepub fn is_sane(&self) -> bool
pub fn is_sane(&self) -> bool
Does this board “make sense”? Do all the pieces make sense, do the bitboards combine correctly, etc? This is for sanity checking.
use chess::{Board, Color, Piece, Square, Rank, File};
let board = Board::default();
assert_eq!(board.is_sane(), true);
// Remove the king
let bad_board = board.clear_square(Square::make_square(Rank::First, File::E)).expect("Valid Position");
assert_eq!(bad_board.is_sane(), false);
sourcepub fn get_pawn_hash(&self) -> u64
pub fn get_pawn_hash(&self) -> u64
Get a pawn hash of the board (a hash that only changes on color change and pawn moves).
sourcepub fn piece_on(&self, square: Square) -> Option<Piece>
pub fn piece_on(&self, square: Square) -> Option<Piece>
What piece is on a particular Square
? Is there even one?
use chess::{Board, Piece, Square, Rank, File};
let board = Board::default();
let sq1 = Square::make_square(Rank::First, File::A);
let sq2 = Square::make_square(Rank::Fourth, File::D);
assert_eq!(board.piece_on(sq1), Some(Piece::Rook));
assert_eq!(board.piece_on(sq2), None);
sourcepub fn enumerate_moves(&self, moves: &mut [ChessMove; 256]) -> usize
pub fn enumerate_moves(&self, moves: &mut [ChessMove; 256]) -> usize
Give me all the legal moves for this board.
Note: You may want to build a MoveGen
structure to iterate over
the moves instead.
Additionally, you must allocate the move array yourself if you want to call this function. it massively helps with performance to reuse that array.
use chess::{Board, ChessMove};
let board = Board::default();
let mut moves = [ChessMove::default(); 256];
let count = board.enumerate_moves(&mut moves);
assert_eq!(count, 20);
sourcepub fn en_passant(self) -> Option<Square>
pub fn en_passant(self) -> Option<Square>
Give me the en_passant square, if it exists.
use chess::{Board, ChessMove, Square, Rank, File};
let move1 = ChessMove::new(Square::make_square(Rank::Second, File::D),
Square::make_square(Rank::Fourth, File::D),
None);
let move2 = ChessMove::new(Square::make_square(Rank::Seventh, File::H),
Square::make_square(Rank::Fifth, File::H),
None);
let move3 = ChessMove::new(Square::make_square(Rank::Fourth, File::D),
Square::make_square(Rank::Fifth, File::D),
None);
let move4 = ChessMove::new(Square::make_square(Rank::Seventh, File::E),
Square::make_square(Rank::Fifth, File::E),
None);
let board = Board::default().make_move_new(move1)
.make_move_new(move2)
.make_move_new(move3)
.make_move_new(move4);
assert_eq!(board.en_passant(), Some(Square::make_square(Rank::Fifth, File::E)));
sourcepub fn legal(&self, m: ChessMove) -> bool
pub fn legal(&self, m: ChessMove) -> bool
Is a particular move legal?
use chess::{Board, ChessMove, Square, Rank, File};
let move1 = ChessMove::new(Square::make_square(Rank::Second, File::E),
Square::make_square(Rank::Fourth, File::E),
None);
let move2 = ChessMove::new(Square::make_square(Rank::Second, File::E),
Square::make_square(Rank::Fifth, File::E),
None);
let board = Board::default();
assert_eq!(board.legal(move1), true);
assert_eq!(board.legal(move2), false);
sourcepub fn legal_quick(&self, chess_move: ChessMove) -> bool
pub fn legal_quick(&self, chess_move: ChessMove) -> bool
This function checks the legality only for moves generated by MoveGen
.
Calling this function for moves not generated by MoveGen
will result in possibly
incorrect results, and making that move on the Board
will result in undefined behavior.
This function may panic! if these rules are not followed.
If you are validating a move from a user, you should call the .legal() function.
sourcepub fn make_move_new(&self, m: ChessMove) -> Board
pub fn make_move_new(&self, m: ChessMove) -> Board
Make a chess move onto a new board.
panic!() if king is captured.
use chess::{Board, ChessMove, Square, Rank, File, Color};
let m = ChessMove::new(Square::make_square(Rank::Second, File::D),
Square::make_square(Rank::Fourth, File::D),
None);
let board = Board::default();
assert_eq!(board.make_move_new(m).side_to_move(), Color::Black);
sourcepub fn make_move(&self, m: ChessMove, result: &mut Board)
pub fn make_move(&self, m: ChessMove, result: &mut Board)
Make a chess move onto an already allocated Board
.
panic!() if king is captured.
use chess::{Board, ChessMove, Square, Rank, File, Color};
let m = ChessMove::new(Square::make_square(Rank::Second, File::D),
Square::make_square(Rank::Fourth, File::D),
None);
let board = Board::default();
let mut result = Board::default();
board.make_move(m, &mut result);
assert_eq!(result.side_to_move(), Color::Black);
sourcepub fn perft_brute_force(&self, depth: u64) -> u64
pub fn perft_brute_force(&self, depth: u64) -> u64
Run a perft-test using brute force move generation.
sourcepub fn perft_cache(&self, depth: u64, cache_size_per_depth: usize) -> u64
pub fn perft_cache(&self, depth: u64, cache_size_per_depth: usize) -> u64
Run a perft test with a cache table.
sourcepub fn pinned(&self) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
pub fn pinned(&self) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
Give me the BitBoard
of my pinned pieces.
sourcepub fn checkers(&self) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
pub fn checkers(&self) -> BitBoardⓘNotable traits for BitBoardimpl Iterator for BitBoard type Item = Square;
Give me the Bitboard
of the pieces putting me in check.
sourcepub fn legal_king_move(&self, dest: Square) -> bool
pub fn legal_king_move(&self, dest: Square) -> bool
Is a particular king move legal?
sourcepub fn legal_ep_move(&self, source: Square, dest: Square) -> bool
pub fn legal_ep_move(&self, source: Square, dest: Square) -> bool
Is a particular en-passant capture legal?
sourcepub fn perft_test(fen: String, depth: u64, result: u64)
pub fn perft_test(fen: String, depth: u64, result: u64)
Run every type of perft test, and panic! if the leaf-node count of any version is not equal
to result
.