feat: move conversion to uci algebraic

This commit is contained in:
dogeystamp 2024-10-26 16:48:51 -04:00
parent 420e32fe86
commit 3ebadf995f

View File

@ -39,6 +39,29 @@ impl From<PromotePiece> for Piece {
} }
} }
impl From<PromotePiece> for char {
fn from(value: PromotePiece) -> Self {
Piece::from(value).into()
}
}
struct NonPromotePiece;
impl TryFrom<Piece> for PromotePiece {
type Error = NonPromotePiece;
fn try_from(value: Piece) -> Result<Self, Self::Error> {
match value {
Piece::Rook => Ok(PromotePiece::Rook),
Piece::Bishop => Ok(PromotePiece::Bishop),
Piece::Knight => Ok(PromotePiece::Knight),
Piece::Queen => Ok(PromotePiece::Queen),
Piece::King => Err(NonPromotePiece),
Piece::Pawn => Err(NonPromotePiece),
}
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
enum AntiMoveType { enum AntiMoveType {
Normal, Normal,
@ -360,6 +383,8 @@ pub enum MoveAlgebraicError {
InvalidLength(usize), InvalidLength(usize),
/// Invalid character at given index. /// Invalid character at given index.
InvalidCharacter(usize), InvalidCharacter(usize),
/// Can't promote to a given piece (char at given index).
InvalidPromotePiece(usize),
/// Could not parse square string at a certain index. /// Could not parse square string at a certain index.
SquareError(usize, SquareError), SquareError(usize, SquareError),
} }
@ -391,13 +416,12 @@ impl FromUCIAlgebraic for Move {
if value_len == 5 { if value_len == 5 {
let promote_char = value.as_bytes()[4] as char; let promote_char = value.as_bytes()[4] as char;
match promote_char {
'q' => move_type = MoveType::Promotion(PromotePiece::Queen), let err = Err(MoveAlgebraicError::InvalidCharacter(4));
'b' => move_type = MoveType::Promotion(PromotePiece::Bishop), let pc = Piece::try_from(promote_char).or(err)?;
'n' => move_type = MoveType::Promotion(PromotePiece::Knight),
'r' => move_type = MoveType::Promotion(PromotePiece::Rook), let err = Err(MoveAlgebraicError::InvalidPromotePiece(4));
_ => return Err(MoveAlgebraicError::InvalidCharacter(4)), move_type = MoveType::Promotion(PromotePiece::try_from(pc).or(err)?);
}
} }
Ok(Move { Ok(Move {
@ -408,6 +432,17 @@ impl FromUCIAlgebraic for Move {
} }
} }
impl ToUCIAlgebraic for Move {
fn to_uci_algebraic(&self) -> String {
let prom_str = match self.move_type {
MoveType::Promotion(promote_piece) => char::from(promote_piece).to_string(),
_ => "".to_string(),
};
format!("{}{}{}", self.src, self.dest, prom_str)
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum MoveGenType { pub enum MoveGenType {
/// Legal move generation. /// Legal move generation.
@ -1350,6 +1385,15 @@ mod tests {
} }
} }
#[test]
fn test_uci_move_fmt() {
let test_cases = ["a1e5", "e7e8q", "e7e8r", "e7e8b", "e7e8n"];
for tc in test_cases {
let mv = Move::from_uci_algebraic(tc).unwrap();
assert_eq!(mv.to_uci_algebraic(), tc);
}
}
/// The standard movegen test. /// The standard movegen test.
/// ///
/// See https://www.chessprogramming.org/Perft /// See https://www.chessprogramming.org/Perft