Skip to content

A chess library written in Rust, oriented to creating and solving chess compositions with especial emphasis on retrograde analysis.

License

Notifications You must be signed in to change notification settings

miguel-ambrona/sherlock

Repository files navigation

Sherlock Holmes

Build Status Documentation Examples

Sherlock

A chess library written in Rust, oriented to creating and solving chess compositions with especial emphasis on retrograde analysis.

This library's name is inspired by "The Chess Mysteries of Sherlock Holmes", a master piece on retrograde analysis by the great Raymond M. Smullyan.

We rely on jordanbray/chess, an amazing Rust chess library, by Jordan Bray, for very efficient move generation. The images in this README and our documentation are rendered with web-boardimage, an HTTP service developed and offered by Niklas Fiekas. Thank you both! ❤️

Examples

Check the legality of a position

A position is legal iff it can be achieved in an actual game.

Consider the following position where en-passant is possible on d3 and all castling rights are still available:

Example

It turns out to be illegal!

Click here for an explanation.

First, realize that only knights and pawns can have moved in this game. Then, observe that for the black F-pawn to reach c4, it must have captured white knights on e6 and d5, and also the white A-pawn on c4 (who reached this square by capturing black knights on b3 and c4).

This makes it possible to determine the parity of the number of moves performed by each side.

  • White made an even number of moves: 3 pawn moves and an odd number of knight moves, since the white knights finished the game on squares of the same color.

  • Black also made an even number of moves: 3 pawn moves and again, an odd number of knight moves.

Since both players made an even number of moves, they must have moved the same number of times and it should be White's turn, but it is not!

Sherlock can realize this.

use chess::Board;
use std::str::FromStr;

let board = Board::from_str("r1bqkb1r/ppppp1pp/8/8/2pP4/8/1PP1PPPP/R1BQKB1R b KQkq d3").unwrap();
assert_eq!(sherlock::is_legal(&board), false);

// the same position with en-passant disabled would be legal
let board = Board::from_str("r1bqkb1r/ppppp1pp/8/8/2pP4/8/1PP1PPPP/R1BQKB1R b KQkq -").unwrap();
assert_eq!(sherlock::is_legal(&board), true);

The Mystery of the Missing Piece

This is a composition by Raymond M. Smullyan from the above-mentioned book. On h4 rests a shilling instead of a chess piece. The challenge is to determine what piece it is.

Example

Sherlock can realize that the shilling must be a white bishop (refer to the book for an explanation):

use chess::{Board, Color::White, Piece::Bishop, Square};
use std::str::FromStr;
use sherlock::{is_legal, ALL_COLORED_PIECES};

let board = Board::from_str("2nR3K/pk1Rp1p1/p2p4/P1p5/1Pp5/2PP2P1/4P2P/n7 b - -").unwrap();

// all the pieces that lead to a legal position when placed on h4
let valid_pieces_on_h4: Vec<_> = ALL_COLORED_PIECES
    .into_iter()
    .filter(|&(color, piece)| {
        board.set_piece(piece, color, Square::H4).as_ref().map_or(false, is_legal)
    })
    .collect();

assert_eq!(valid_pieces_on_h4, vec![(White, Bishop)]);

About

A chess library written in Rust, oriented to creating and solving chess compositions with especial emphasis on retrograde analysis.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages