shakmaty 0.20.0

Chess and chess variant rules and operations
Documentation
# shakmaty

A Rust library for chess move generation

[![Build Status](https://travis-ci.org/niklasf/shakmaty.svg?branch=master)](https://travis-ci.org/niklasf/shakmaty)
[![crates.io](https://img.shields.io/crates/v/shakmaty.svg)](https://crates.io/crates/shakmaty)
[![docs.rs](https://docs.rs/shakmaty/badge.svg)](https://docs.rs/shakmaty)

## Features

- Generate legal moves:

  ```rust
  use shakmaty::{Chess, Position};

  let pos = Chess::default();
  let legals = pos.legal_moves();
  assert_eq!(legals.len(), 20);
  ```

- Play moves:

  ```rust
  use shakmaty::{Square, Move, Role};

  // 1. e4
  let pos = pos.play(&Move::Normal {
      role: Role::Pawn,
      from: Square::E2,
      to: Square::E4,
      capture: None,
      promotion: None,
  })?;
  ```

- Detect game end conditions: `pos.is_checkmate()`, `pos.is_stalemate()`,
  `pos.is_insufficient_material()`, `pos.outcome()`.

- Read and write FENs, SANs and UCIs.

- Supports all Lichess variants: Standard chess, Chess960, Antichess, Atomic,
  King of the Hill, Three-Check, Crazyhouse, Racing Kings and Horde. Provides
  vocabulary to implement other variants.

- Bitboards and compact fixed shift magic attack tables.

- Probe Syzygy tablebases with [shakmaty-syzygy]https://crates.io/crates/shakmaty-syzygy.

## Documentation

[Read the documentation](https://docs.rs/shakmaty)

## Benchmarks

Simple [perft](https://www.chessprogramming.org/Perft) of the initial
position. No hashtables. i7-6850K CPU @ 3.60GHz.

| perft                                                    | 4      | 5       |
| -------------------------------------------------------- | ------ | ------- |
| shakmaty 0.16.0                                          | 1.0 ms | 24.1 ms |
| [jordanbray/chess]https://crates.io/crates/chess 3.1.1 | 0.8 ms | 18.6 ms |
| Stockfish 8 (x86-64-bmi2)                                | 4 ms   | 33 ms   |

It should be noted that Stockfish is not optimized for perft speed and also
maintains additional data structures for evaluation. Newer versions of
Stockfish put even less emphasis on this.

## Changelog

- 0.20.0
  - Removed tracking of promoted pieces from `Board` and added
    `Setup::promoted()` instead. This is used only by Crazyhouse. All other
    variants will return `Bitboard(0)`. Removed `FenOpts::promoted()`
    accordingly. Moved `fen::board_fen()` as a method to `Board`.
  - Implemented Zobrist hashing.
  - Fixed (or rather implemented) insufficient material detection for `Horde`.
  - Added new feature `step` that implements the nightly `Step` trait for
    `File`, `Rank` and `Square`.
  - Let `Bitboard` respect `Display` formatting options.
  - Fixed return type of `File::offset()`.
  - Implemented `Eq` and `Hash` for `Chess` and `Pieces`.
- 0.19.0
  - Update `arrayvec` to 0.7.x. `MoveList` is now using const generics.
  - Derive `Hash` for `Move`, `Outcome`, and `Fen`.
  - Eliminate unsafe usage where no longer required for performance. Justify
    remaining cases.
- 0.18.0
  - Remove `f32`, `f64`, `u128`, and `i128` conversions.
  - Use `std::num::TryFromIntError`.
  - Functions now return `MoveList` instead of using it as an out parameter.
    Return value optimization by hand is no longer required.
  - Introduce `ByColor`, used as `Material` and `ByColor<RemainingChecks>`.
  - Introduce `PlayError`.
  - Renamed `variants` module to `variant`. Now gated behind a non-default
    feature `variant`.
- 0.17.2
  - Parse `Uci::to_move()` where king captures unmoved rook.
- 0.17.1
  - Also reject checker aligned with king and en passant square with
    `PositionErrorKinds::IMPOSSIBLE_CHECK`.
- 0.17.0
  - Introduce `CastlingMode`, now required for
    `FromSetup::from_setup(..., mode)`, the `VariantPosition` analogon,
    `Fen::position(mode)`, and exposed by `Castles::mode()`.
  - `Uci::from_move()` now takes the mode as context instead of the position.
    Give `pos.castles().mode()` for the old behavior.
  - Add `Uci::from_standard()`.
  - Rework `PositionError`. The original error kinds are available as
    `PositionError::kinds()`. There are now methods to safely ignore particular
    errors.
  - Reject setups with impossible (i.e., too much) material with the new
    `PositionErrorKinds::IMPOSSIBLE_MATERIAL`. Can be ignored using
    `PositionError::ignore_impossible_material()` for the previous behavior.
  - Reject setups with multiple aligned sliding checkers with the new
    `PositionErrorKinds::IMPOSSIBLE_CHECK`.
  - Rename `BAD_CASTLING_RIGHTS` to `INVALID_CASTLING_RIGHTS`.
  - Remove `IllegalMoveError`. In the context of UCI validation, replace with
    `IllegalUciError`. `Position::play()` instead returns the original position
    as the error.
  - Change `fullmoves` from `u32` to `NonZeroU32` everywhere.
  - Remove public `Castles::from_setup()`.
  - Remove `Square::with_rank_of()`.
  - Remove `Giveaway` in favor of `Antichess` (where players start without
    castling rights).
  - Fix `swap_turn()` if en passant square exists. Would always fail, now
    discards the en passant square.
  - Add `Move::to_uci()` convenience method.
  - Add `CastlingSide::{king,rook}_to_file()`.
  - Add `Variant::distinguishes_promoted()`.
  - Add `Variant::uci()` and `Variant::from_uci()`.
  - Future proof error types (remove some implemented traits and available
    constructors).
- 0.16.4
  - Fix insufficient material detection with same-color bishops on both sides.
  - Document limitations of `Position::is_irreversible()`. Moves that cede
    en passant are now considered irreversible.
- 0.16.3
  - Implement `From<Role>` for nonzero integer types.
  - Performance: Remove internal `BB_BETWEEN` table and compute it from rays at
    runtime, to improve cache efficiency.
  - Support Miri.
- 0.16.2
  - Fix Racing Kings game end detection: Black cannot catch up if their own
    pieces block the goal.
  - Pawn drops in Crazyhouse are now considered zeroing.
- 0.16.1
  - Fix (impossible) Crazyhouse insufficient material.
  - Fix (impossible) castling rights of exploded king in Atomic chess.
- 0.16.0
  - Update `arrayvec` to 0.5.x, which comes with significant performance
    improvements.
  - The default `Giveaway` position now has castling rights.
- 0.15.3
  - Follow FICS rules in Atomic castling edge cases.
  - Use `#[repr(align)] enum` and `reverse_bits()` stabilized in Rust 1.37.
- 0.15.2
  - In Horde chess, allow double pawn moves from the first rank.
  - Added `{Square,Bitboard}::{flip_anti_diagonal,rotate_90,rotate_180,rotate_270}()`.
- 0.15.1
  - FEN parser was expecting `~` before promoted pieces, but it should be
    after.
- 0.15.0
  - Moved `Position::from_setup()` to a seperate new trait `FromSetup`.
  - Square and file/rank index calculations are now performed with `u32` and
    `i32`, which is more performant than using the narrower types `u8` and
    `i8`. The types are still `#[repr(u8)]`.
  - Renamed `Square::combine()` to `Square::with_rank_of()`.
  - Added `Fen::from_setup()`.
  - Added `FenOpts::scid()` for Scid/Lichess compatible FEN formatting.
    Of course the parser also accepts these formats.
  - Added `variant::Variant` and `VariantPosition` for runtime selected
    chess variants. Limited to the built in variants.
  - Added `{Material,MaterialSide}::is_empty()`.
- 0.14.1
  - `TryFrom` now available on stable.
- 0.14.0
  - `SanPlus::from_move()` no longer requires the move to be legal, which
    was an undocumented requirement. The new
    `SanPlus::from_move_and_play_unchecked()` is closest to the previous
    behavior.
  - Added `San::disambiguate()` and `SanSuffix::from_position()`.
  - Implement `TryFrom` for various types on nightly.
  - Implement `Add`, `AddAssign`, `Sub`, `SubAssign` for `Material` and
    `MaterialSide`.
  - Added `CastlingSide::from_{king|queen}_side()`.
  - Use `u32` for `depth` argument of `perft()`.
- 0.13.1
  - Performance improvements on nightly (aligned `Move` enum).
- 0.13.0
  - Replaced `SanPlus::check` and `SanPlus::checkmate` with `san::Suffix` enum.
  - Renamed `{Rank,File}::rotate()` to `flip_diagonal()`.
  - Renamed `Bitboard::flip()` to `toggle()`.
  - Added `Square::coords()`.
  - Added `Bitboard::flip_{vertical,horizontal,diagonal}()`.
  - Added `Position::promotion_moves()`.
  - Derive `Hash` on `Board`, `FenOpts`, `San`, `SanPlus`, `Suffix`, `Color`,
    `Role`, `Piece`, `RemainingChecks`, `CastlingSide`, and `Uci`.
  - Minimum Rust version 1.31.0.
- 0.12.0
  - `Setup::halfmove_clock()` is now `Setup::halfmoves()`.
  - New conversions: `f32::from(file)`, `f64::from(rank)`.
  - Replace `Pockets` and `Pocket` by more general `Material` and
    `MaterialSide`. Note that their `Display` and `FromStr` implementations
    differ.
  - Unify naming of error types.
- 0.11.2
  - Fix Atomic insufficient material: KQN can mate.
- 0.11.1
  - Fix Chess960 should not allow a-side castling over a blocking h-side rook.
- 0.11.0
  - `Outcome` is now `Copy`.
  - `Position::castling_uncovers_rank_attack()` is no longer public.
- 0.10.0
  - Add `File`, `Rank`. These are now returned by `Square::{file, rank}`.
    `Square::from_coords(file, rank)` takes the new types and is no longer
    fallible.
  - `Bitboard` is now `IntoIterator` instead of `Iterator` itself.
    Methods `Bitboard::{first, last, count, is_empty}` remain.
  - `Bitboard::{add, flip, discard, with, without}` are now generic over
    `Into<Bitboard>`. Alternative methods `*_all` have been removed.
  - `Bitboard::relative_shift(color, shift: u8)` now takes `u32`.
  - `shakmaty::CarryRippler` is now `shakmaty::bitboard::CarryRippler`.
  - Add new methods:
    `Bitboard::{pop_front, pop_back, is_disjoint, is_subset, is_superset}`.
  - Add `Position::has_insufficient_material(color)`.
- 0.9.0
  - Remove `uci`, `chess960_uci`, `san` and `san_plus` that were deprecated
    in 0.8.1.
  - Rename `*::from_bytes()` to `*::from_ascii()`.
  - Take small copy types by value: `Piece::char()`, `CastlingSide::*`.
  - Add `Castles::has(color, side)`.
  - `fen::{board_fen, epd, fen}` are now shortcuts for formatting with
    default options.
  - Minimum rust version 1.27.0 (i128 conversions again, fused iterators again,
    `Option::filter()`, `dyn Trait`).
  - Eliminate many uses of unsafe, including `TrustedLen` impls, at minor cost.
- 0.8.1
  - Make `Role` discriminants public.
  - Put `San`, `SanPlus` and `Uci` constructors on `San`, `SanPlus` and `Uci`
    respectively.
- 0.8.0
  - Revert fused iterators and u128. Minimum Rust version back to 1.23.0.
  - Change `Role` discriminants. Now starting with `Pawn = 1`.
  - Performance improvements (~12% faster perft).
  - Switch benchmarks to `criterion.rs`.
- 0.7.2
  - Add `Outcome.winner()`.
- 0.7.1
  - Minimum Rust version 1.26.0 (fused iterators, u128 conversions).
- 0.7.0
  - Reintroduce the remaining Lichess variants: `Crazyhouse`, `KingOfTheHill`,
    `ThreeCheck`, `Horde`, `RacingKings`.
  - Expose `Position.castles()` and replace `Position.is_chess960()` with
    `Position.castles().is_chess960()`.
  - Fix insufficient material: KNvK was not given as drawn due to a typo.
  - Fix insufficient material in `Atomic`: Two knights of different colors
    are not safe.
  - Let `Pockets.count()` and `Pocket.count()` return `usize`.
- 0.6.7
  - Giveaway starting position should have no castling rights.
- 0.6.6
  - Fix missing king promotions in Giveaway.
- 0.6.5
  - Validate color of missing king in atomic chess.
  - Clear move buffers before generating variant moves.
- 0.6.4
  - Reintroduce `Giveaway` and `Atomic` chess variants.
- 0.6.3
  - New method `Move.is_zeroing()`.
- 0.6.2
  - Make unit error types (`InvalidSquareName`, `InvalidUci`, `InvalidSan`)
    completely public.
  - Documentation, coding style and debugging tweaks.
- 0.6.1
  - Expose `attacks::bishop_mask` and `attacks::rook_mask`.
  - Eliminate almost all unchecked indexing.
- 0.6.0
  - Split `impl From<Move> for Uci` into `uci()` and `chess960_uci()`.
  - Fix display of pawn drops.
  - Move generating methods clear the move buffer (and therefor no longer panic on too full buffers).
  - Added `Position.is_chess960()`, `Bitboard.without_all()`, `Role.upper_char()`, `Board.stepper()`.
- 0.5.1
  - Fix `Uci::to_move()` for en passant moves. Thanks zxqfl.
- 0.5.0
  - Use `u64` instead of `usize` for `perft()`.
  - Export error type `InvalidSquareName`.
  - New methods: `CastlingSide.is_{queen|king}_side()`, `San.matches()`, `Move.is_capture()`, `Move.is_promotion()`, `Move.castling_side()`, `Position.is_check()`.
  - Derive `Ord` and `PartialOrd` for `Role`.
  - Support running benchmarks on stable.
- 0.4.2
  - Fix build error on beta due to the new nightly `option_filter` feature.
  - Fix unterminated code block in documentation.
- 0.4.1
  - Fix build error due to the new nightly
    [`option_filter`]https://github.com/rust-lang/rust/issues/45860 feature.
- 0.4.0
  - Rename `Color::from_bool()` to `Color::from_white()`,
    add `Color::from_black()`.
  - Add `Move::role()`, `Move::is_en_passant()` and `Move::is_castle()`.
  - Add `Position::en_passant_moves()` and `Position::capture_moves()`.
  - Implement `BitXor<bool>` for `Color`.
  - Implement `FusedIterator` and `TrustedLen` on `Bitboard`.
- 0.3.0
  - Switch to `#[repr(i8)]` for `Square`. Implement all lossless integer
    conversions `From<Square>`.
  - Add `Square::flip_horizontal()`, `flip_vertical()` and `flip_diagonal()`.
  - Efficiently implement `CarryRippler::last()` by @nvzqz.
  - Eliminate some unchecked indexing by @nvzqz.
  - Faster ASCII case conversions and tests by @nvzqz.
- 0.2.0
  - `Square` is now a `#[repr(u8)]` enum.
  - Use `bitflags` for `PositionError`.
  - Rename `RemainingChecks::subtract()` to `decrement()`.
  - Add `Position::swap_turn()`.
- 0.1.0
  - First release with support for stable Rust.

## License

Shakmaty is licensed under the GPL-3.0 (or any later version at your option).
See the COPYING file for the full license text.