Compare commits

...

5 commits

Author SHA1 Message Date
Bruno BELANYI b1ae941560 WIP
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-28 13:24:41 +02:00
Bruno BELANYI 0c73caaf60 Add FEN castling rights parsing 2022-07-27 23:41:08 +02:00
Bruno BELANYI 0a1e1dc39d Add FEN piece type parsing 2022-07-27 23:40:55 +02:00
Bruno BELANYI 5d956fa08f Add FEN en-passant target square parsing 2022-07-27 23:40:38 +02:00
Bruno BELANYI 03b8ba4236 Add FEN side to move parsing 2022-07-27 23:40:15 +02:00
6 changed files with 128 additions and 40 deletions

View file

@ -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:

View file

@ -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";
};

View file

@ -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<Self, Self::Err> {
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::*;

View file

@ -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<Self, Self::Err> {
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;

View file

@ -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<Self, Self::Err> {
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::*;

View file

@ -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<Square> {
type Err = Error;
fn from_fen(s: &str) -> Result<Self, Self::Err> {
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<usize> for Square {
type Output = Square;