eschac
This commit is contained in:
commit
faccfbc1c5
16 changed files with 5154 additions and 0 deletions
95
src/uci.rs
Normal file
95
src/uci.rs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
//! UCI notation.
|
||||
//!
|
||||
//! Move notation as defined by the Universal Chess Interface standard used for most chess engines
|
||||
//! and chess servers.
|
||||
//!
|
||||
//! A move is described by its origin and target squares. Castling is described as the move done by
|
||||
//! the king. For promotion, a lowercase letter is added at the end of the move.
|
||||
//!
|
||||
//! Examples: *`e2e4`*, *`d1d8`*, *`e1g1`* (short castling), *`h7h8q`* (promotion)
|
||||
|
||||
use crate::board::*;
|
||||
use crate::position::*;
|
||||
|
||||
/// **The UCI notation of a move.**
|
||||
///
|
||||
/// UCI notation can be obtained from a legal move using the [`Move::to_uci`] method.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct UciMove {
|
||||
pub from: Square,
|
||||
pub to: Square,
|
||||
pub promotion: Option<Role>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for UciMove {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{}{}", self.from, self.to)?;
|
||||
if let Some(promotion) = self.promotion {
|
||||
write!(f, "{}", promotion.to_char_lowercase())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for UciMove {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
f.debug_tuple("UciMove").field(&self.to_string()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for UciMove {
|
||||
type Err = ParseUciMoveError;
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Self::from_ascii(s.as_bytes()).ok_or(ParseUciMoveError)
|
||||
}
|
||||
}
|
||||
|
||||
/// A syntax error when parsing a [`UciMove`].
|
||||
#[derive(Debug)]
|
||||
pub struct ParseUciMoveError;
|
||||
impl std::fmt::Display for ParseUciMoveError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("invalid UCI notation")
|
||||
}
|
||||
}
|
||||
impl std::error::Error for ParseUciMoveError {}
|
||||
|
||||
/// An error when converting [`UciMove`] notation to a playable [`Move`].
|
||||
#[derive(Debug)]
|
||||
pub enum InvalidUciMove {
|
||||
/// The is no move on the position that matches the UCI notation.
|
||||
Illegal,
|
||||
}
|
||||
impl std::fmt::Display for InvalidUciMove {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("illegal UCI move")
|
||||
}
|
||||
}
|
||||
impl std::error::Error for InvalidUciMove {}
|
||||
|
||||
impl UciMove {
|
||||
/// Tries to convert UCI notation to a playable move.
|
||||
#[inline]
|
||||
pub fn to_move<'l>(&self, position: &'l Position) -> Result<Move<'l>, InvalidUciMove> {
|
||||
position.move_from_uci(*self)
|
||||
}
|
||||
|
||||
/// Tries to read UCI notation from ascii text.
|
||||
#[inline]
|
||||
pub fn from_ascii(s: &[u8]) -> Option<Self> {
|
||||
match s {
|
||||
[a, b, c, d, s @ ..] => Some(Self {
|
||||
from: Square::new(File::from_ascii(*a)?, Rank::from_ascii(*b)?),
|
||||
to: Square::new(File::from_ascii(*c)?, Rank::from_ascii(*d)?),
|
||||
promotion: match s {
|
||||
[] => None,
|
||||
[c] => Some(Role::from_ascii(*c)?),
|
||||
_ => return None,
|
||||
},
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue