@@ -24,6 +24,25 @@ use crate::defs::MAX_DEPTH;
2424pub type ScoreType = i16 ;
2525pub ( crate ) type LargeScoreType = i32 ;
2626/// Represents a score in centipawns.
27+ ///
28+ /// This type has saturating add/sub operations to prevent overflow.
29+ /// It will not wrap around on overflow, but instead saturate to the internal types min/max.
30+ ///
31+ /// The score is represented as a signed 16-bit integer, which allows for a range of -32,768 to 32,767.
32+ ///
33+ /// Example usage:
34+ /// ```rust
35+ /// use engine::score::{Score, ScoreType};
36+ /// let score = Score::new(150); // Represents a score of 150 centipawns
37+ /// let mate_score = Score::MATE; // Represents a checkmate score
38+ /// let draw_score = Score::DRAW; // Represents a draw score
39+ /// let mut s = Score::INF / 2;
40+ /// s += Score::INF;
41+ /// assert_eq!(s, Score::INF); // Saturating addition
42+ /// let mut ss = -Score::INF;
43+ /// ss -= Score::INF;
44+ /// assert_eq!(ss, Score::new(ScoreType::MIN)); // Saturating subtraction
45+ /// ```
2746#[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Default ) ]
2847pub struct Score ( pub ScoreType ) ;
2948
@@ -83,55 +102,55 @@ impl Neg for Score {
83102
84103impl AddAssign for Score {
85104 fn add_assign ( & mut self , other : Score ) {
86- self . 0 += other. 0 ;
105+ * self = * self + other;
87106 }
88107}
89108
90109impl AddAssign < ScoreType > for Score {
91110 fn add_assign ( & mut self , other : ScoreType ) {
92- self . 0 += other;
111+ * self = * self + other;
93112 }
94113}
95114
96115impl Add for Score {
97116 type Output = Score ;
98117
99- fn add ( self , other : Score ) -> Score {
100- Score ( self . 0 + other. 0 )
118+ fn add ( self , other : Score ) -> Self :: Output {
119+ Score ( self . 0 . saturating_add ( other. 0 ) )
101120 }
102121}
103122
104123impl Add < ScoreType > for Score {
105124 type Output = Score ;
106125
107- fn add ( self , other : ScoreType ) -> Score {
108- Score ( self . 0 + other)
126+ fn add ( self , other : ScoreType ) -> Self :: Output {
127+ Score ( self . 0 . saturating_add ( other) )
109128 }
110129}
111130
112131impl Sub for Score {
113132 type Output = Score ;
114- fn sub ( self , other : Score ) -> Score {
115- Score ( self . 0 - other. 0 )
133+ fn sub ( self , other : Score ) -> Self :: Output {
134+ Score ( self . 0 . saturating_sub ( other. 0 ) )
116135 }
117136}
118137
119138impl Sub < ScoreType > for Score {
120139 type Output = Score ;
121140 fn sub ( self , other : ScoreType ) -> Score {
122- Score ( self . 0 - other)
141+ Score ( self . 0 . saturating_sub ( other) )
123142 }
124143}
125144
126145impl SubAssign for Score {
127146 fn sub_assign ( & mut self , other : Score ) {
128- self . 0 -= other. 0 ;
147+ * self = * self - other;
129148 }
130149}
131150
132151impl SubAssign < ScoreType > for Score {
133152 fn sub_assign ( & mut self , rhs : ScoreType ) {
134- self . 0 -= rhs;
153+ * self = * self - rhs;
135154 }
136155}
137156
@@ -193,3 +212,14 @@ impl Shl<u32> for Score {
193212 Score ( self . 0 << rhs)
194213 }
195214}
215+
216+ #[ cfg( test) ]
217+ mod tests {
218+ use super :: * ;
219+ #[ test]
220+ fn add_assign ( ) {
221+ let mut right = Score :: INF / 2 ;
222+ right += Score :: INF ;
223+ assert_eq ! ( right, Score :: INF ) ;
224+ }
225+ }
0 commit comments