@@ -5,7 +5,7 @@ use std::{
55
66use anyhow:: { Result , anyhow} ;
77use chess:: { bitboard_helpers, board:: Board , pieces:: Piece , side:: Side } ;
8- use engine:: psqt:: GAMEPHASE_INC ;
8+ use engine:: { hce_values :: GAME_PHASE_MAX , psqt:: GAMEPHASE_INC } ;
99
1010use crate :: { offsets:: Offsets , tuning_position:: TuningPosition } ;
1111
@@ -77,25 +77,20 @@ fn parse_epd_line(line: &str) -> Result<TuningPosition> {
7777 }
7878 }
7979
80- let stm = match board. side_to_move ( ) {
81- Side :: White => 1f64 ,
82- Side :: Black => -1f64 ,
83- Side :: Both => panic ! ( "Side to move cannot be both." ) ,
84- } ;
80+ let is_white_relative = matches ! ( game_result, 0.0 | 0.5 | 1.0 ) ;
8581
86- let result = match game_result {
87- // if we have an exact result, this indicates that we parsed a "book" file
88- // not an epd with centipawn evaluation
89- 0.0 | 0.5 | 1.0 => game_result,
90- // otherwise, adjust based on the side to move
91- _ => match board. side_to_move ( ) {
82+ let result = if is_white_relative {
83+ game_result
84+ } else {
85+ match board. side_to_move ( ) {
9286 Side :: White => game_result,
9387 Side :: Black => 1.0 - game_result,
9488 Side :: Both => panic ! ( "Side to move cannot be both." ) ,
95- } ,
89+ }
9690 } ;
9791
98- let tuning_pos = TuningPosition :: new ( w_indexes, b_indexes, phase, result, stm) ;
92+ let scaled_phase = phase as f64 / ( GAME_PHASE_MAX as f64 ) ;
93+ let tuning_pos = TuningPosition :: new ( w_indexes, b_indexes, scaled_phase, result) ;
9994
10095 Ok ( tuning_pos)
10196}
@@ -148,7 +143,7 @@ fn get_game_result(part: &str) -> Result<f64> {
148143#[ cfg( test) ]
149144mod tests {
150145 use chess:: { board:: Board , side:: Side } ;
151- use engine:: { evaluation:: ByteKnightEvaluation , traits:: Eval } ;
146+ use engine:: { evaluation:: ByteKnightEvaluation , hce_values :: GAME_PHASE_MAX , traits:: Eval } ;
152147
153148 use crate :: {
154149 epd_parser:: { get_game_result, process_epd_line} ,
@@ -208,20 +203,31 @@ mod tests {
208203 "r2q1rk1/ppp1npbp/4b1p1/1P3nN1/2Pp4/3P4/PB1NBPPP/R2QR1K1 b - - 0 1 [0.0]" ,
209204 ] ;
210205
211- const EXPECTED_GAME_PHASES : [ usize ; 10 ] = [ 7 , 18 , 12 , 10 , 10 , 8 , 17 , 20 , 5 , 24 ] ;
206+ let mut expected_game_phases: [ f64 ; 10 ] = [ 7. , 18. , 12. , 10. , 10. , 8. , 17. , 20. , 5. , 24. ] ;
207+ for phase in & mut expected_game_phases {
208+ * phase /= GAME_PHASE_MAX as f64 ;
209+ }
210+
212211 const EXPECTED_GAME_RESULTS : [ f64 ; 10 ] = [ 0.0 , 0.0 , 0.0 , 1.0 , 1.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ] ;
213212 let eval = ByteKnightEvaluation :: default ( ) ;
214213 let params = Parameters :: create_from_engine_values ( ) ;
215214
216215 let parsed_results = test_epd_lines ( & epd_lines) ;
217216
218217 for ( i, ( position, board, result) ) in parsed_results. iter ( ) . enumerate ( ) {
219- assert_eq ! ( position. phase, EXPECTED_GAME_PHASES [ i] ) ;
218+ assert_eq ! ( position. phase, expected_game_phases [ i] ) ;
220219 assert_eq ! ( position. game_result, EXPECTED_GAME_RESULTS [ i] ) ;
221220 assert_eq ! ( * result, EXPECTED_GAME_RESULTS [ i] ) ;
222221 // also verify that the evaluation matches
223222 let expected_value = eval. eval ( board) ;
224- let val = position. evaluate ( & params) ;
223+
224+ // tuning position evaluation is always from white's perspective
225+ let val = match board. side_to_move ( ) {
226+ Side :: White => position. evaluate ( & params) ,
227+ Side :: Black => -position. evaluate ( & params) ,
228+ Side :: Both => panic ! ( "Side to move cannot be both." ) ,
229+ } ;
230+
225231 println ! ( "{} // {}" , expected_value, val) ;
226232 assert ! ( ( expected_value. 0 as f64 - val) . abs( ) . round( ) <= 1.0 )
227233 }
@@ -265,7 +271,13 @@ mod tests {
265271 assert_eq ! ( position. game_result, expected_game_result) ;
266272 assert_eq ! ( * result, EXPECTED_PARSED_GAME_RESULTS [ i] ) ;
267273 let expected_value = eval. eval ( board) ;
268- let val = position. evaluate ( & params) ;
274+
275+ // tuning position evaluation is always from white's perspective
276+ let val = match board. side_to_move ( ) {
277+ Side :: White => position. evaluate ( & params) ,
278+ Side :: Black => -position. evaluate ( & params) ,
279+ Side :: Both => panic ! ( "Side to move cannot be both." ) ,
280+ } ;
269281 println ! ( "{} // {}" , expected_value, val) ;
270282 assert ! ( ( expected_value. 0 as f64 - val) . abs( ) . round( ) <= 1.0 )
271283 }
@@ -299,7 +311,12 @@ mod tests {
299311 assert_eq ! ( position. game_result, EXPECTED_PARSED_GAME_RESULTS [ i] ) ;
300312 assert_eq ! ( * result, EXPECTED_PARSED_GAME_RESULTS [ i] ) ;
301313 let expected_value = eval. eval ( board) ;
302- let val = position. evaluate ( & params) ;
314+ // tuning position evaluation is always from white's perspective
315+ let val = match board. side_to_move ( ) {
316+ Side :: White => position. evaluate ( & params) ,
317+ Side :: Black => -position. evaluate ( & params) ,
318+ Side :: Both => panic ! ( "Side to move cannot be both." ) ,
319+ } ;
303320 println ! ( "{} // {}" , expected_value, val) ;
304321 assert ! ( ( expected_value. 0 as f64 - val) . abs( ) . round( ) <= 1.0 )
305322 }
0 commit comments