1
0
Fork 0

make RawMove public

This commit is contained in:
Paul-Nicolas Madelaine 2025-12-01 23:39:31 +01:00
parent 6de44c64a7
commit 22098bbfff
3 changed files with 93 additions and 60 deletions

View file

@ -93,7 +93,7 @@ pub mod prelude {
board::Piece, board::Piece,
board::{ByCastlingSide, ByColor, ByFile, ByRank, ByRole, BySquare}, board::{ByCastlingSide, ByColor, ByFile, ByRank, ByRole, BySquare},
board::{CastlingSide, Color, File, Rank, Role, Square}, board::{CastlingSide, Color, File, Rank, Role, Square},
position::Position, position::{Position, RawMove},
san::San, san::San,
setup::Setup, setup::Setup,
uci::UciMove, uci::UciMove,

View file

@ -21,7 +21,7 @@ pub struct Move<'l> {
impl<'l> Move<'l> { impl<'l> Move<'l> {
#[inline] #[inline]
pub(crate) unsafe fn new_unchecked(position: &'l Position, raw: RawMove) -> Self { pub(crate) unsafe fn new(position: &'l Position, raw: RawMove) -> Self {
Self { position, raw } Self { position, raw }
} }
@ -83,10 +83,16 @@ impl<'l> Move<'l> {
} }
} }
/// Returns the raw data of the move.
#[inline]
pub fn raw(self) -> RawMove {
self.raw
}
/// Returns the UCI notation of the move. /// Returns the UCI notation of the move.
#[inline] #[inline]
pub fn to_uci(self) -> UciMove { pub fn to_uci(self) -> UciMove {
self.raw.uci() self.raw.to_uci()
} }
/// Returns the standard algebraic notation of the move. /// Returns the standard algebraic notation of the move.

View file

@ -293,6 +293,15 @@ impl Position {
} }
} }
/// Plays a move without checking for its legality.
///
/// **Safety:** if `m` is not legal on `self` then this might cause undefined behavior, see
/// [`RawMove`] for details.
#[inline]
pub unsafe fn play_unchecked(&mut self, m: RawMove) {
unsafe { play_move(self, m) };
}
pub(crate) fn move_from_uci<'l>(&'l self, uci: UciMove) -> Result<Move<'l>, InvalidUciMove> { pub(crate) fn move_from_uci<'l>(&'l self, uci: UciMove) -> Result<Move<'l>, InvalidUciMove> {
struct MoveGenImpl<const ROLE: u8> { struct MoveGenImpl<const ROLE: u8> {
role: Role, role: Role,
@ -352,7 +361,7 @@ impl Position {
.generate_moves(&mut moves) .generate_moves(&mut moves)
.break_value() .break_value()
.ok_or(InvalidUciMove::Illegal)?; .ok_or(InvalidUciMove::Illegal)?;
Ok(unsafe { Move::new_unchecked(position, raw) }) Ok(unsafe { Move::new(position, raw) })
} }
let promotion = if role == Role::Pawn { let promotion = if role == Role::Pawn {
promotion.unwrap_or(Role::Pawn) promotion.unwrap_or(Role::Pawn)
@ -463,7 +472,7 @@ impl Position {
None => Err(InvalidSan::Illegal), None => Err(InvalidSan::Illegal),
Some(raw) => match moves.found_other { Some(raw) => match moves.found_other {
true => Err(InvalidSan::Ambiguous), true => Err(InvalidSan::Ambiguous),
false => Ok(unsafe { Move::new_unchecked(position, raw) }), false => Ok(unsafe { Move::new(position, raw) }),
}, },
} }
} }
@ -486,12 +495,19 @@ impl Default for Position {
} }
} }
/// The raw data of a move.
///
/// The [`Move<'l>`](crate::moves::Move) type should usually be preferred for playing moves, but
/// this type allows accessing the unsafe interface [`Position::play_unchecked`].
///
/// When playing this move ([`Position::play_unchecked`]) or converting to a legal move
/// ([`RawMove::to_move`]) it is the caller's responsability to ensure legality. The only w
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub(crate) struct RawMove { pub struct RawMove {
pub kind: MoveType, pub(crate) kind: MoveType,
pub role: Role, pub(crate) role: Role,
pub from: Square, pub(crate) from: Square,
pub to: Square, pub(crate) to: Square,
} }
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, PartialEq, Eq)]
@ -510,16 +526,9 @@ pub(crate) enum MoveType {
} }
impl RawMove { impl RawMove {
/// Returns the type of piece that moves.
#[inline] #[inline]
pub fn from(&self) -> Square { pub fn role(self) -> Role {
self.from
}
#[inline]
pub fn to(&self) -> Square {
self.to
}
#[inline]
pub fn role(&self) -> Role {
match self.kind { match self.kind {
MoveType::CastleShort | MoveType::CastleLong | MoveType::KingMove => Role::King, MoveType::CastleShort | MoveType::CastleLong | MoveType::KingMove => Role::King,
MoveType::PieceMove => self.role, MoveType::PieceMove => self.role,
@ -531,15 +540,33 @@ impl RawMove {
| MoveType::EnPassant => Role::Pawn, | MoveType::EnPassant => Role::Pawn,
} }
} }
/// Returns the origin square of the move.
#[inline] #[inline]
pub fn promotion(&self) -> Option<Role> { pub fn from(self) -> Square {
self.from
}
/// Returns the target square of the move.
#[inline]
pub fn to(self) -> Square {
self.to
}
/// Returns the type of piece that the pawn is promoted to, if the move is a promotion.
#[inline]
pub fn promotion(self) -> Option<Role> {
match self.kind { match self.kind {
MoveType::PawnAdvancePromotion | MoveType::PawnAttackPromotion => Some(self.role), MoveType::PawnAdvancePromotion | MoveType::PawnAttackPromotion => Some(self.role),
_ => None, _ => None,
} }
} }
/// Converts the move to a [`Move<'l>`] bound to the given position, without checking for the
/// legality of the move.
/// **Safety:**
#[inline] #[inline]
pub fn uci(&self) -> UciMove { pub unsafe fn to_move<'l>(self, position: &'l Position) -> Move<'l> {
unsafe { Move::new(position, self) }
}
#[inline]
pub fn to_uci(self) -> UciMove {
UciMove { UciMove {
from: self.from(), from: self.from(),
to: self.to(), to: self.to(),
@ -914,10 +941,11 @@ impl Position {
ControlFlow::Continue(()) ControlFlow::Continue(())
} }
}
#[inline] #[inline]
pub(crate) unsafe fn play_unchecked(&mut self, m: RawMove) { pub(crate) unsafe fn play_move(position: &mut Position, m: RawMove) {
let Self(setup) = self; let Position(setup) = position;
setup.en_passant = None; setup.en_passant = None;
@ -958,7 +986,6 @@ impl Position {
} }
setup.turn = !setup.turn; setup.turn = !setup.turn;
}
} }
#[inline] #[inline]