// Eryn Wells use std::{ fmt, ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}, }; pub(crate) type Value = i32; /// A score for a position in centipawns. #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct Score(Value); impl Score { pub const ZERO: Score = Score(0); /// The minimum possible value of a score. Notably, this is *not* the /// minimum value for the inner integer value so negation works correctly. /// This property is important during search, which relies on being able to /// negate "infinity". /// /// ## Examples /// /// ``` /// use chessfriend_core::score::Score; /// assert_eq!(-Score::MIN, Score::MAX); /// ``` /// pub const MIN: Score = Score(Value::MIN + 1); /// The maximum possible value of a score. pub const MAX: Score = Score(Value::MAX); pub(crate) const CENTIPAWNS_PER_POINT: f32 = 100.0; #[must_use] pub const fn new(value: Value) -> Self { Self(value) } /// Returns `true` if this [`Score`] is zero. /// /// ## Examples /// /// ``` /// use chessfriend_core::score::Score; /// assert!(Score::ZERO.is_zero()); /// assert!(Score::new(0).is_zero()); /// ``` /// #[must_use] pub const fn is_zero(&self) -> bool { self.0 == 0 } } impl Add for Score { type Output = Self; fn add(self, rhs: Self) -> Self::Output { Score(self.0 + rhs.0) } } impl AddAssign for Score { fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0; } } impl Sub for Score { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { Score(self.0 - rhs.0) } } impl SubAssign for Score { fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0; } } impl Mul for Score { type Output = Self; fn mul(self, rhs: Value) -> Self::Output { Score(self.0 * rhs) } } impl Mul for Value { type Output = Score; fn mul(self, rhs: Score) -> Self::Output { Score(self * rhs.0) } } impl Neg for Score { type Output = Self; fn neg(self) -> Self::Output { Score(-self.0) } } impl From for Score { fn from(value: Value) -> Self { Score(value) } } impl fmt::Display for Score { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let value = self.0; if *self == Self::MAX { write!(f, "INF") } else if *self == Self::MIN { write!(f, "-INF") } else { write!(f, "{value}cp") } } }