Giter Club home page Giter Club logo

shakmaty's Introduction

shakmaty

A Rust library for chess move generation

crates.io docs.rs

Features

  • Generate legal moves:

    use shakmaty::{Chess, Position};
    
    let pos = Chess::default();
    let legals = pos.legal_moves();
    assert_eq!(legals.len(), 20);
  • Play moves:

    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 FEN, SAN and UCI notation.

  • 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.

  • Zobrist hash positions.

  • Probe Syzygy tablebases with shakmaty-syzygy.

Documentation

Read the documentation

Benchmarks

Simple 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 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.

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.

shakmaty's People

Contributors

bastidood avatar brunocodutra avatar dependabot-preview[bot] avatar dmitry123 avatar hyperchessbot avatar johanfleury avatar kornelski avatar kraktus avatar lakinwecker avatar leesongun avatar niklasf avatar nvzqz avatar stevepapazis avatar thomas-daniels avatar ue2020 avatar wspeirs avatar zxqfl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shakmaty's Issues

debug performance regression between nightly-2017-11-20 and nightly-2017-11-21

rust-lang/rust#46364


Before:

$ cargo +nightly-2017-11-20 bench
[...]
test perft::tests::bench_deep_perft               ... bench:  29,666,456 ns/iter (+/- 10,492,824)
test perft::tests::bench_shallow_perft            ... bench:   1,153,713 ns/iter (+/- 3,677)
test position::tests::bench_generate_moves        ... bench:         122 ns/iter (+/- 3)
test position::tests::bench_play_unchecked        ... bench:          10 ns/iter (+/- 0)
test position::tests::bench_san_candidates        ... bench:          15 ns/iter (+/- 0)
test san::tests::bench_parse_san_move_complicated ... bench:          10 ns/iter (+/- 0)

After:

$ cargo +nightly-2017-11-21 bench
[...]
test perft::tests::bench_deep_perft               ... bench:  34,374,405 ns/iter (+/- 2,849,721)
test perft::tests::bench_shallow_perft            ... bench:   1,317,448 ns/iter (+/- 1,264)
test position::tests::bench_generate_moves        ... bench:         159 ns/iter (+/- 2)
test position::tests::bench_play_unchecked        ... bench:          14 ns/iter (+/- 0)
test position::tests::bench_san_candidates        ... bench:          15 ns/iter (+/- 0)
test san::tests::bench_parse_san_move_complicated ... bench:           9 ns/iter (+/- 0)

Platform:

binary: rustc
host: x86_64-unknown-linux-gnu
LLVM version: 4.0

Bug: Shakmaty produces incorrect position and generates misleading list of moves in it

Hi, thanks for an amazing crate! I'm using it to validate my own clunky move generator and fuzz both & compare the results using shakmaty as the reference. Unfortunately, I've run into a problem early on: there is a position which both my generator (does not reliably check whether the position is truly valid or not) and shakmaty accept but shakmaty produces an incorrect list of moves (if we take the en-passant square out of the equation). Because the position is incorrect, I guess the real problem is both programs accepting the position rather than producing different move lists. Here's the reproducer:

use shakmaty::{CastlingMode, Chess, Position};

fn main() {
    let shakmaty_setup: shakmaty::fen::Fen =
        "rnbqk1nr/bb3p1p/1q2r3/2pPp3/3P4/7P/1PP1NpPP/R1BQKBNR w KQkq c6"
            .parse()
            .expect("The FEN is fine but the position is not (en passant with a check delivered by a piece other than a pawn).");
    let shakmaty_position: Chess = shakmaty_setup
        .position(CastlingMode::Standard)
        .expect("Oh-oh, this is not a legal position!");
    println!("{:?}", shakmaty_position.legal_moves());
}

Gives:

[EnPassant { from: D5, to: C6 }, Normal { role: King, from: E1, capture: None, to: D2, promotion: None }, Normal { role: King, from: E1, capture: Some(Pawn), to: F2, promotion: None }]

The problematic move is EnPassant { from: D5, to: C6 } because it doesn't actually resolve the check given by an F2 pawn! I guess, generating moves in invalid position is undefined/should not be reliable.

Here's the position in the editor for esier inspection: https://lichess.org/editor/rnbqk1nr/bb3p1p/1q2r3/2pPp3/3P4/7P/1PP1NpPP/R1BQKBNR_w_KQkq_c6_0_1

UCI castling not recognized by some GUIs

shakmaty writes a black kingside castle as e8h8, but PyChess only understands e8g8. It looks like shakmaty uses e8h8 on purpose to accomodate Chess960 games, so I wasn't sure of the best way to fix this issue.

This is the fix I'm using in my own code:

fn map_uci(x: String) -> String {
    match x.as_str() {
        "e8h8" => "e8g8".into(),
        "e8a8" => "e8c8".into(),
        "e1h1" => "e1g1".into(),
        "e1a1" => "e1c1".into(),
        _ => x,
    }
}

Knight double disambiguation bug

Hi,

When parsing games on lichess, I stumbled upon this game, which almost has a double disambiguation checkmate. However, the only reason that I was able to find this game was because the move was incorrectly labelled as a double disambiguation.

image

In this position, the move N5xf6# is causing the problem. Since all three knights are able to move to f6, two disambiguation checks are being done. The first check disambiguates with the g4 knight, and identifies that the file should be disambiguated. Then, the check is done for the d7 knight, which identifies that the rank needs to be disambiguated. However, it would be sufficient to only disambiguate the rank in this case.

I was also able to find this game, where the same problem exists.

Minimal example to reproduce

fn main() -> Result<(), Box<dyn std::error::Error>>{
    let fen: Fen = "8/2KN1p2/5p2/3N1B1k/5PNp/7P/7P/8 w - - ".parse()?;
    let position: Chess = fen.into_position(CastlingMode::Standard)?;
    let correct_san = "N5xf6#";

    let san = San::from_str(&correct_san)?;
    let m = san.to_move(&position)?;
    let san_plus = SanPlus::from_move(position, &m);

    // this fails, the actual value is "Nd5xf6#"
    assert_eq!(san_plus.to_string(), correct_san);
    Ok(())
}

The bug

It seems that the bug arises from the disambiguation logic in san.rs. Since the folding considers each disambiguation separately, it won't be able to find the correct disambiguation.

let (rank, file) = moves
    .iter()
    .filter(|c| match *c {
        Move::Normal {
            role: r,
            to: t,
            promotion: p,
            ..
        } => role == *r && to == *t && promotion == *p,
        _ => false,
    })
    .fold((false, false), |(rank, file), c| match *c {
        Move::Normal {
            from: candidate, ..
        } => {
            if from == candidate {
                (rank, file)
            } else if from.rank() == candidate.rank()
                || from.file() != candidate.file()
            {
                (rank, true)
            } else {
                (true, file)
            }
        }
        _ => (rank, file),
    });

Wrongly converting Rook capture from UCI

    let mut position: Chess = Fen::from_str("8/8/8/B2p3Q/2qPp1P1/b7/2P2PkP/4K2R b K - 0 1")
        .unwrap()
        .position(CastlingMode::Standard)
        .unwrap();
    Uci::from_str("g2h1")
        .ok()
        .and_then(|x| x.to_move(&position).ok())
        .unwrap();

This crashes: called `Option::unwrap()` on a `None` value'. My initial guess is that is has to do something with capturing the Rook which is relevant for castling, since removing the castling flag no longer leads to crashes.

UCI/XBoard Support

I can see the point here: jordanbray/chess#6 but it also suggests putting all the engine communication stuff into a different library which I'm not too much a fan of as it may be harder to discover. Is there any consensus on this?
I actually would like to help out too but my Rust is not up to the mark yet.

Add all encompassing error type

Official example for uci parsing only compiles after creating an error type that encompasses all possible uci parse errors.

This is a lot to do for such a simple example ( or for use cases when one is content with ignoring error handling ).

Please consider adding an all encompassing error type, that one can use for testing or using features where error handling is not necessary.

use thiserror::Error;

#[derive(Error, Debug)]
enum UciError {
	#[error("parse uci error")]
	ParseUciError(#[from] ParseUciError),
	#[error("illegal uci error")]
	IllegelUciError(#[from] IllegalUciError),
}

fn _shakmaty_official() -> Result<(), UciError> {
	let uci: Uci = "g1f3".parse()?;
	let pos = Chess::default();
	let m = uci.to_move(&pos)?;
	println!("move {}", m);
	Ok(())
}

Implement incremental Zobrist hashing

I'm working on adding Zobrist hashes to shakmaty: https://github.com/wspeirs/shakmaty

@niklasf would love your feedback on what I have thus far. I still need to implement it for all the variations; however, I have do_move complete so it shouldn't be too bad. I have a unit test that computes 100k positions and ensures there are no collisions. I've also gone up to 1m, but it takes a while unless you're running on release.

Let me know how to proceed and any feedback... thanks!

API guidelines checklist

  • Naming (crate aligns with Rust naming conventions)
    • Casing conforms to RFC 430 (C-CASE)
    • Ad-hoc conversions follow as_, to_, into_ conventions (C-CONV)
    • Getter names follow Rust convention (C-GETTER)
    • Methods on collections that produce iterators follow iter, iter_mut, into_iter (C-ITER)
    • Iterator type names match the methods that produce them (C-ITER-TY)
    • Feature names are free of placeholder words (C-FEATURE)
    • Names use a consistent word order (C-WORD-ORDER)
  • Interoperability (crate interacts nicely with other library functionality)
    • Types eagerly implement common traits (C-COMMON-TRAITS)
      • Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug,
        Display, Default
    • Conversions use the standard traits From, AsRef, AsMut (C-CONV-TRAITS)
    • Collections implement FromIterator and Extend (C-COLLECT)
    • Data structures implement Serde's Serialize, Deserialize (C-SERDE) (Instead, implement Display and FromStr where relevant and use serde_with)
    • Types are Send and Sync where possible (C-SEND-SYNC)
    • Error types are meaningful and well-behaved (C-GOOD-ERR)
    • Binary number types provide Hex, Octal, Binary formatting (C-NUM-FMT)
    • Generic reader/writer functions take R: Read and W: Write by value (C-RW-VALUE)
  • Macros (crate presents well-behaved macros)
  • Documentation (crate is abundantly documented)
    • Crate level docs are thorough and include examples (C-CRATE-DOC)
    • All items have a rustdoc example (C-EXAMPLE)
    • Examples use ?, not try!, not unwrap (C-QUESTION-MARK)
    • Function docs include error, panic, and safety considerations ([C-FAILURE])
    • Prose contains hyperlinks to relevant things (C-LINK)
    • Cargo.toml includes all common metadata (C-METADATA)
      • authors, description, license, homepage, documentation, repository,
        readme, keywords, categories
    • Release notes document all significant changes (C-RELNOTES)
    • Rustdoc does not show unhelpful implementation details (C-HIDDEN)
  • Predictability (crate enables legible code that acts how it looks)
    • Smart pointers do not add inherent methods (C-SMART-PTR)
    • Conversions live on the most specific type involved (C-CONV-SPECIFIC)
    • Functions with a clear receiver are methods (C-METHOD)
    • Functions do not take out-parameters (C-NO-OUT)
      • Some methods on Position reuse existing move buffers, especially because return value optimization does not work there (bluss/arrayvec#64)
    • Operator overloads are unsurprising (C-OVERLOAD)
    • Only smart pointers implement Deref and DerefMut (C-DEREF)
    • Constructors are static, inherent methods (C-CTOR)
  • Flexibility (crate supports diverse real-world use cases)
    • Functions expose intermediate results to avoid duplicate work (C-INTERMEDIATE)
    • Caller decides where to copy and place data (C-CALLER-CONTROL)
    • Functions minimize assumptions about parameters by using generics (C-GENERIC)
    • Traits are object-safe if they may be useful as a trait object (C-OBJECT)
  • Type safety (crate leverages the type system effectively)
    • Newtypes provide static distinctions (C-NEWTYPE)
    • Arguments convey meaning through types, not bool or Option (C-CUSTOM-TYPE)
    • Types for a set of flags are bitflags, not enums (C-BITFLAG)
    • Builders enable construction of complex values (C-BUILDER)
  • Dependability (crate is unlikely to do the wrong thing)
  • Debuggability (crate is conducive to easy debugging)
  • Future proofing (crate is free to improve without breaking users' code)
  • Necessities (to whom they matter, they really matter)

Variants are inaccessible

Hi,
I am unable to instantiate a new shakmaty::variant::Crazyhouse since the module seems to be private. I'm not sure if this is related to one of the recent changes you made a few hours ago or if I am doing something wrong (I am new to Rust, forgive me). The docs say nothing about how to create variant positions and make moves on them, so I tried this:

use shakmaty::variant::Crazyhouse;

However, the variant module seems to be private. I have enabled the feature by including

[features]
variant = []

in my Cargo.toml file, so I don't see why I get the error unresolved import 'shakmaty::variant' could not find 'variant' in 'shakmaty'. What I'm trying to do is just create a basic crazyhouse board and make some moves on it, like I can with the example in the docs for standard chess.

Detect draws by 50-move-rule (and possibly 3-fold repetition)

Currently, is_game_over only detects checkmates, stalemates, and insufficient material, but not draws by the 50 move rule, or by 3-fold repetition.

Implementing the 50 move rule should be trivial, as the Chess struct keeps track of the halfmoves counter.
(should also probably change legal_moves and is_legal to match this behavior.)

It's impossible to check for 3-fold repetition in is_game_over given the way the Chess struct is implemented, but maybe it's possible to expose a separate API, that given a starting position and a list of moves, returns whether any position repeated three times.
(I'm sure there's a better solution than keeping a hashmap of board FENs since the last irreversible move)

Correctly support Put

Hi.
It seems this library have support for the CrazyHouse variant, but it does not seem to work for me.
Adding the following line here (even though it's probably not the correct fix) allows me to play CrazyHouse games:

                legals.push(Move::Put { role, to });

Thanks to fix this issue.

ELO loss on shakmaty upgrade

Hi, I made a change to my engine, which is just a shakmaty upgrade princesslana/princhess#155

But on running an sprt test with cutechess, I get the following results:

princhess-sprt_equal-1  | Score of princhess vs princhess-main: 918 - 1069 - 623  [0.471] 2610
princhess-sprt_equal-1  | ...      princhess playing White: 461 - 541 - 303  [0.469] 1305
princhess-sprt_equal-1  | ...      princhess playing Black: 457 - 528 - 320  [0.473] 1305
princhess-sprt_equal-1  | ...      White vs Black: 989 - 998 - 623  [0.498] 2610
princhess-sprt_equal-1  | Elo difference: -20.1 +/- 11.6, LOS: 0.0 %, DrawRatio: 23.9 %
princhess-sprt_equal-1  | SPRT: llr -2.95 (-100.3%), lbound -2.94, ubound 2.94 - H0 was accepted

Any ideas on what could cause this elo loss?

The likely critical parts called on every rollout are:
This loop through Board#occupied: https://github.com/princesslana/princhess/blob/main/src/state.rs#L199-L216
Make move: https://github.com/princesslana/princhess/blob/main/src/state.rs#L108-L124
Evaluation, including a syzygy lookup with shakmaty-syzygy: https://github.com/princesslana/princhess/blob/main/src/evaluation.rs#L16-L32

`Move` does not implement `Hash`

It would be helpful if Move implemented Hash... I think this is as simple as adding it to the derive macro, as both Role and Square already implement Hash.

use of unstable library feature 'bool_to_option'

Hello, I'm trying to build shakmaty version 0.18.0, but I'm running into the following build error. Maybe you could give me a hint what I am doing wrong. I'm using rustc version 1.49. Is version 1.50 required by any chance?

error[E0658]: use of unstable library feature 'bool_to_option'
   --> /build/fishnet-2.2.6-vendor.tar.gz/shakmaty/src/fen.rs:454:110
    |
454 |         } else if let Some(split_point) = board_part.iter().enumerate().filter_map(|(idx, ch)| (*ch == b'/').then(|| idx)).nth(7) {
    |                                                                                                              ^^^^
    |
    = note: see issue #64260 <https://github.com/rust-lang/rust/issues/64260> for more information

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
error: could not compile `shakmaty`

Mirror boards

Hi, I'm looking for a way to mirror boards. For example, with python-chess I can do .mirror():

import chess
board = chess.Board(fen="6k1/pp3pp1/4b2p/4N3/2p5/2q3P1/P4PKP/3r4 w - - 0 1")
print(board.mirror().fen()) # 3R4/p4pkp/2Q3p1/2P5/4n3/4B2P/PP3PP1/6K1 b - - 0 1

fens

Which flips vertically and swaps colors.

I tried the same thing with shakmaty but only managed to flip the board, and can't find a way to swap colors:

let fen: Fen = "6k1/pp3pp1/4b2p/4N3/2p5/2q3P1/P4PKP/3r4 w - - 0 1"
    .parse()
    .unwrap();
let pos: Chess = fen.into_position(CastlingMode::Standard).unwrap();
let mut board = pos.board().clone();
board.flip_vertical();
println!("{}", board); // 3r4/P4PKP/2q3P1/2p5/4N3/4b2p/pp3pp1/6k1

image

How could I do it? Can it be added to shakmaty?


I'm looking for this because I'm working with ML and need the board to always be from the POV of white

Thanks!

Allow Board::color_at to return empty squares colour

It would be useful for turning a board into e.g emojis

pub fn create_emoji_board(board: Board) -> String {
    let mut board_str = String::new();

    for sq in Square::ALL {
        let piece = board.piece_at(sq);
        if let Some(piece) = piece {
			// use the piece to generate emoji
        } else {
            let col = board.color_at(sq); // If there is no piece at said square, return the
                                          // blank squares colour
        }
    }

    board_str
}

serde serialization and deserialization support

There is no way to currently encode chess positions from this crate in an efficient way with a binary encoding and serde support would enable this without much trouble. I am willing to implement this through a feature flag with all of the public facing types in the crate.

Incorrectly getting an invalid EP square error

For the following Fen: rnbqkbnr/pppp2pp/5p2/3Pp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e5 0 1 e5 is a valid en passant square as it can be captured by d5 via en passant. However when I do

let fen: Fen = "rnbqkbnr/pppp2pp/5p2/3Pp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e5 0 1".parse().unwrap();
let board: Chess = fen.into_position(CastlingMode::Standard).unwrap();

I get:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: PositionError { errors: PositionErrorKinds(INVALID_EP_SQUARE) }', src/game.rs:21:64

The game sequence to lead to this was:

  1. d4 f6
  2. d5 e5
  3. dxe6 e.p.

Edit: I realise this is likely incorrect FEN and e5 should be e6 instead and the other library I'm using has a bug instead closing this.

Bug: Missing En Passant capture in legal move generation

Position: q6k/8/8/3pP3/8/8/8/7K w - d6 0 1

Code (same as before):

use shakmaty::{CastlingMode, Chess, Position};

fn main() {
    let shakmaty_setup: shakmaty::fen::Fen = "q6k/8/8/3pP3/8/8/8/7K w - d6 0 1"
        .parse()
        .expect("If we parsed a position, it should be parsed by shakmaty, too.");
    let shakmaty_position: Chess = shakmaty_setup
        .position(CastlingMode::Standard)
        .expect("Oh-oh, this is not a legal position!");
    println!("{:?}", shakmaty_position.legal_moves());
}

Generated moves:

[Normal { role: Pawn, from: E5, capture: None, to: E6, promotion: None }, Normal { role: King, from: H1, capture: None, to: G1, promotion: None }, Normal { role: King, from: H1, capture: None, to: G2, promotion: None }, Normal { role: King, from: H1, capture: None, to: H2, promotion: None }]

This is missing move is EnPassant { from: E5, to: D6 }. This is the move that my engine has but shakmaty misses right now (latest version).

Add promotion_moves() method?

Hi,

Thanks for a great crate!

Not sure if you entertain feature requests, but I'm implementing quiescence search, and one thing that would improve it is evaluating promotion moves. A Position.promotion_moves() method would be super useful. Thanks again! I'll share my engine when I'm a bit further along.

Shakmaty support added to chess_perft

Just an FYI, I added shakmaty to the chess_perft crate/binary, so that it could use either move generator in the background, depending on the use case (with -c or -s). Additionally, I added all the benchmarks from the 'chess' crate to the 'chess_perft' crate, and a fancy python script to compare and graph performance.
You can run the performance tests yourself with cargo bench in the chess_perft library, which will look at both chess and shakmaty.

`Move` could be `Copy`.

The Move enum has a simple definition, and is very small: when I compile the crate it's only 8 bytes/64 bits. It would be very convenient if it derived the Copy trait so we don't need to call .clone or work with references anywhere. I can't really think of any disadvantages.

Using `Move::Put` results in an illegal move

The following snippet fails when I think it should pass

let pos = Chess::default();
assert!(pos.is_legal(&Move::Put {
    role: Role::Pawn,
    to: Square::D4
}));

In the method, the move list does contain the valid move, but it has constructed a type of Move::Normal so the .contains(m) fails when using Move::Put

fn is_legal(&self, m: &Move) -> bool {
    ...
    moves.contains(m)
}

SanPlus::from_move needs a mutable Position?

I'm confused by the signature of from_move for SanPlus, it takes a mut Position, which doesn't seem necessary, and is tripping me up a bit when using the library.

Looking at the source, I see this:

https://docs.rs/shakmaty/latest/src/shakmaty/san.rs.html#608

Which also confuses me, why is pos.play_unchecked(m); called in there?

My assumption would be that from_move would just take a &Position and a &Move, and then return a SanPlus, not play any moves or require a mutable Position.

Thank you for the excellent library, I wouldn't have been able to write the backend of my chess site in Rust without it.

Direct initialization using bitboards

It would be very handy if there was a way to initialize the position using directly bitboard values like below, instead of using FEN:

let b = shakmaty::Board {
	by_role: shakmaty::ByRole {
		pawn: shakmaty::Bitboard(0x00ff_0000_0000_ff00),
		knight: shakmaty::Bitboard(0x4200_0000_0000_0042),
		bishop: shakmaty::Bitboard(0x2400_0000_0000_0024),
		rook: shakmaty::Bitboard(0x8100_0000_0000_0081),
		queen: shakmaty::Bitboard(0x0800_0000_0000_0008),
		king: shakmaty::Bitboard(0x1000_0000_0000_0010),
	},
	by_color: shakmaty::ByColor {
		black: shakmaty::Bitboard(0xffff_0000_0000_0000),
		white: shakmaty::Bitboard(0xffff),
	},
	occupied: shakmaty::Bitboard(0xffff_0000_0000_ffff),
};

let chess = shakmaty::Chess::from_setup(
	Setup {
		board: b,
		turn: shakmaty::Color::White,
		ep_square: None,
		halfmoves: 0,
		fullmoves: NonZeroU32::new(1).unwrap(),
		promoted: shakmaty::Bitboard::default(),
		pockets: None,
		castling_rights: shakmaty::Bitboard::default(),
		remaining_checks: None,
	},
	CastlingMode::Standard,
)
.unwrap();

Now, shakamaty::Board's fields are private, so it's impossible. I'm integrating shakmaty-syzygy with my bitboard-based chess engine where going through the whole process of making and then parsing FENs can be pretty slow, so I'm looking for a faster way.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.