try from
This commit is contained in:
parent
8733993f1a
commit
d9e3879937
4 changed files with 47 additions and 40 deletions
|
|
@ -28,7 +28,7 @@
|
|||
//!
|
||||
//! // read a position from a text record
|
||||
//! let setup = Setup::from_text_record("7k/4P1rp/5Q2/5p2/1Pp1bP2/8/r4K1P/6R1 w - -")?;
|
||||
//! let position = setup.validate()?;
|
||||
//! let position = setup.try_into()?;
|
||||
//!
|
||||
//! // read a move in algebraic notation
|
||||
//! let san = "Ke1".parse::<San>()?;
|
||||
|
|
|
|||
|
|
@ -90,14 +90,14 @@ impl Position {
|
|||
/// ```
|
||||
/// # use eschac::setup::Setup;
|
||||
/// # |s: &str| -> Option<eschac::position::Position> {
|
||||
/// Setup::from_text_record(s).ok().and_then(|pos| pos.validate().ok())
|
||||
/// Setup::from_text_record(s).ok().and_then(|setup| setup.try_into().ok())
|
||||
/// # };
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn from_text_record(s: &str) -> Option<Self> {
|
||||
Setup::from_text_record(s)
|
||||
.ok()
|
||||
.and_then(|pos| pos.validate().ok())
|
||||
.and_then(|setup| setup.try_into().ok())
|
||||
}
|
||||
|
||||
/// Returns the text record of the position.
|
||||
|
|
|
|||
77
src/setup.rs
77
src/setup.rs
|
|
@ -339,10 +339,44 @@ impl Setup {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the bitboard of each kind of piece.
|
||||
#[inline]
|
||||
pub fn pieces(&self) -> ByColor<ByRole<Bitboard>> {
|
||||
let Self {
|
||||
w,
|
||||
p_b_q,
|
||||
n_b_k,
|
||||
r_q_k,
|
||||
..
|
||||
} = self.clone();
|
||||
let k = n_b_k & r_q_k;
|
||||
let q = p_b_q & r_q_k;
|
||||
let b = p_b_q & n_b_k;
|
||||
let n = n_b_k ^ b ^ k;
|
||||
let r = r_q_k ^ q ^ k;
|
||||
let p = p_b_q ^ b ^ q;
|
||||
ByColor::new(|color| {
|
||||
let mask = match color {
|
||||
Color::White => w,
|
||||
Color::Black => !w,
|
||||
};
|
||||
ByRole::new(|kind| {
|
||||
mask & match kind {
|
||||
Role::Pawn => p,
|
||||
Role::Knight => n,
|
||||
Role::Bishop => b,
|
||||
Role::Rook => r,
|
||||
Role::Queen => q,
|
||||
Role::King => k,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Tries to validate the position, i.e. converting it to a [`Position`].
|
||||
///
|
||||
/// See [`IllegalPositionReason`] for details.
|
||||
pub fn validate(self) -> Result<Position, IllegalPosition> {
|
||||
pub fn into_position(self) -> Result<Position, IllegalPosition> {
|
||||
debug_assert!((self.w & !(self.p_b_q | self.n_b_k | self.r_q_k)).is_empty());
|
||||
debug_assert!((self.p_b_q & self.n_b_k & self.r_q_k).is_empty());
|
||||
|
||||
|
|
@ -467,40 +501,6 @@ impl Setup {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the bitboard of each kind of piece.
|
||||
#[inline]
|
||||
pub fn pieces(&self) -> ByColor<ByRole<Bitboard>> {
|
||||
let Self {
|
||||
w,
|
||||
p_b_q,
|
||||
n_b_k,
|
||||
r_q_k,
|
||||
..
|
||||
} = self.clone();
|
||||
let k = n_b_k & r_q_k;
|
||||
let q = p_b_q & r_q_k;
|
||||
let b = p_b_q & n_b_k;
|
||||
let n = n_b_k ^ b ^ k;
|
||||
let r = r_q_k ^ q ^ k;
|
||||
let p = p_b_q ^ b ^ q;
|
||||
ByColor::new(|color| {
|
||||
let mask = match color {
|
||||
Color::White => w,
|
||||
Color::Black => !w,
|
||||
};
|
||||
ByRole::new(|kind| {
|
||||
mask & match kind {
|
||||
Role::Pawn => p,
|
||||
Role::Knight => n,
|
||||
Role::Bishop => b,
|
||||
Role::Rook => r,
|
||||
Role::Queen => q,
|
||||
Role::King => k,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn get_role(&self, square: Square) -> Option<Role> {
|
||||
let mask = square.bitboard();
|
||||
|
|
@ -514,6 +514,13 @@ impl Setup {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Setup> for Position {
|
||||
type Error = IllegalPosition;
|
||||
fn try_from(setup: Setup) -> Result<Position, IllegalPosition> {
|
||||
setup.into_position()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Setup {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
f.debug_tuple("Setup")
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ fn recursive_check_aux(position: Position, depth: usize) {
|
|||
.en_passant_target_square()
|
||||
.map(|square| square.mirror()),
|
||||
);
|
||||
setup.validate().unwrap()
|
||||
setup.into_position().unwrap()
|
||||
};
|
||||
let expected_mirror = position.mirror();
|
||||
assert_eq!(computed_mirror, expected_mirror);
|
||||
|
|
@ -192,7 +192,7 @@ fn setup() {
|
|||
assert!(
|
||||
Setup::from_text_record(record)
|
||||
.unwrap()
|
||||
.validate()
|
||||
.into_position()
|
||||
.is_err_and(|e| e.reasons().contains(reason)),
|
||||
"{record} should be invalid because of {reason:?}",
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue