From 03b8ba42361e438c29c5c8646e8de8d2c99d8d3c Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Wed, 27 Jul 2022 23:40:15 +0200 Subject: [PATCH 1/5] Add FEN side to move parsing --- src/board/color.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/board/color.rs b/src/board/color.rs index 6e828a6..828b1cf 100644 --- a/src/board/color.rs +++ b/src/board/color.rs @@ -1,4 +1,5 @@ -use super::{Direction, Rank}; +use super::{Direction, FromFen, Rank}; +use crate::error::Error; /// An enum representing the color of a player. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -106,6 +107,20 @@ impl Color { } } +/// Convert a side to move segment of a FEN string to a [Color]. +impl FromFen for Color { + type Err = Error; + + fn from_fen(s: &str) -> Result { + let res = match s { + "w" => Color::White, + "b" => Color::Black, + _ => return Err(Error::InvalidFen), + }; + Ok(res) + } +} + impl std::ops::Not for Color { type Output = Color; From 5d956fa08f60204ef695b1a8d2fa04b84c28b308 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Wed, 27 Jul 2022 23:40:38 +0200 Subject: [PATCH 2/5] Add FEN en-passant target square parsing --- src/board/square.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/board/square.rs b/src/board/square.rs index 9ffa824..9fbd5ee 100644 --- a/src/board/square.rs +++ b/src/board/square.rs @@ -1,5 +1,5 @@ -use super::{Bitboard, File, Rank}; -use crate::utils::static_assert; +use super::{Bitboard, File, FromFen, Rank}; +use crate::{error::Error, utils::static_assert}; /// Represent a square on a chessboard. Defined in the same order as the /// [Bitboard] squares. @@ -107,6 +107,23 @@ impl Square { } } +/// Convert an en-passant target square segment of a FEN string to an optional [Square]. +impl FromFen for Option { + type Err = Error; + + fn from_fen(s: &str) -> Result { + let res = match s.as_bytes() { + [b'-'] => None, + [file @ b'a'..=b'h', rank @ b'1'..=b'8'] => Some(Square::new( + File::from_index((file - b'a') as usize), + Rank::from_index((rank - b'1') as usize), + )), + _ => return Err(Error::InvalidFen), + }; + Ok(res) + } +} + /// Shift the square's index left by the amount given. impl std::ops::Shl for Square { type Output = Square; From 0a1e1dc39d199d7b66cf518a9fe5aa7e7adfce40 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Wed, 27 Jul 2022 23:40:55 +0200 Subject: [PATCH 3/5] Add FEN piece type parsing --- src/board/piece.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/board/piece.rs b/src/board/piece.rs index 58f989a..99ec091 100644 --- a/src/board/piece.rs +++ b/src/board/piece.rs @@ -1,3 +1,6 @@ +use super::FromFen; +use crate::error::Error; + /// An enum representing the type of a piece. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Piece { @@ -52,6 +55,23 @@ impl Piece { } } +impl FromFen for Piece { + type Err = Error; + + fn from_fen(s: &str) -> Result { + let res = match s { + "p" | "P" => Self::Pawn, + "n" | "N" => Self::Knight, + "b" | "B" => Self::Bishop, + "r" | "R" => Self::Rook, + "q" | "Q" => Self::Queen, + "k" | "K" => Self::King, + _ => return Err(Error::InvalidFen), + }; + Ok(res) + } +} + #[cfg(test)] mod test { use super::*; From 0c73caaf60b999d803720747b963b2912faa5586 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Wed, 27 Jul 2022 23:41:08 +0200 Subject: [PATCH 4/5] Add FEN castling rights parsing --- src/board/castle_rights.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/board/castle_rights.rs b/src/board/castle_rights.rs index b8d8f2b..a48bf4d 100644 --- a/src/board/castle_rights.rs +++ b/src/board/castle_rights.rs @@ -1,4 +1,5 @@ -use super::{Bitboard, Color, File, Square}; +use super::{Bitboard, Color, File, FromFen, Square}; +use crate::error::Error; /// Current castle rights for a player. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -108,6 +109,39 @@ impl CastleRights { } } +/// Convert the castling rights segment of a FEN string to an array of [CastleRights]. +impl FromFen for [CastleRights; 2] { + type Err = Error; + + fn from_fen(s: &str) -> Result { + if s.len() > 4 { + return Err(Error::InvalidFen); + } + + let mut res = [CastleRights::NoSide; 2]; + + if s == "-" { + return Ok(res); + } + + for b in s.chars() { + let color = if b.is_uppercase() { + Color::White + } else { + Color::Black + }; + let rights = &mut res[color.index()]; + match b { + 'k' | 'K' => *rights = rights.with_king_side(), + 'q' | 'Q' => *rights = rights.with_queen_side(), + _ => return Err(Error::InvalidFen), + } + } + + Ok(res) + } +} + #[cfg(test)] mod test { use super::*; From b1ae941560f2af26d2f742a643fc9ad3b8064649 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Thu, 28 Jul 2022 13:24:41 +0200 Subject: [PATCH 5/5] WIP --- .drone.yml | 2 +- flake.nix | 72 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/.drone.yml b/.drone.yml index 8fb7774..6a9ddd2 100644 --- a/.drone.yml +++ b/.drone.yml @@ -6,7 +6,7 @@ name: abacus checks steps: - name: pre commit check commands: - - nix develop . --command pre-commit run --all + - nix develop . --command cargo vendor - name: flake check commands: diff --git a/flake.nix b/flake.nix index c8e7566..22a05e4 100644 --- a/flake.nix +++ b/flake.nix @@ -80,42 +80,44 @@ rustc = my-rust; }; inherit (pkgs) lib; - pre-commit = - let - # See https://github.com/cachix/pre-commit-hooks.nix/issues/126 - rust-env = pkgs.buildEnv { - name = "rust-env"; - buildInputs = [ pkgs.makeWrapper ]; - paths = [ my-rust ]; - pathsToLink = [ "/" "/bin" ]; - postBuild = '' - for i in $out/bin/*; do - wrapProgram "$i" --prefix PATH : "$out/bin" - done - ''; - }; - in - pre-commit-hooks.lib.${system}.run { - src = self; - - hooks = { - clippy = { - enable = true; - entry = lib.mkForce "${rust-env}/bin/cargo-clippy clippy"; - }; - - nixpkgs-fmt = { - enable = true; - }; - - rustfmt = { - enable = true; - entry = lib.mkForce "${rust-env}/bin/cargo-fmt fmt -- --check --color always"; - }; - }; - }; in rec { + checks = { + pre-commit = + let + # See https://github.com/cachix/pre-commit-hooks.nix/issues/126 + rust-env = pkgs.buildEnv { + name = "rust-env"; + buildInputs = [ pkgs.makeWrapper ]; + paths = [ my-rust ]; + pathsToLink = [ "/" "/bin" ]; + postBuild = '' + for i in $out/bin/*; do + wrapProgram "$i" --prefix PATH : "$out/bin" + done + ''; + }; + in + pre-commit-hooks.lib.${system}.run { + src = self; + + hooks = { + clippy = { + enable = true; + entry = lib.mkForce "${rust-env}/bin/cargo-clippy clippy"; + }; + + nixpkgs-fmt = { + enable = true; + }; + + rustfmt = { + enable = true; + entry = lib.mkForce "${rust-env}/bin/cargo-fmt fmt -- --check --color always"; + }; + }; + }; + }; devShells = { default = pkgs.mkShell { @@ -129,7 +131,7 @@ my-rust ]; - inherit (pre-commit) shellHook; + inherit (checks.pre-commit) shellHook; RUST_SRC_PATH = "${my-rust}/lib/rustlib/src/rust/library"; };