@@ -70,21 +70,82 @@ export const Highlight: React.FC<Props> = ({
7070      } ) ( ) 
7171    : false 
7272
73-   // Helper function to format evaluation values 
74-   const  formatEvaluation  =  ( 
75-     cp : number , 
76-     mateIn ?: number , 
77-     isCheckmate ?: boolean , 
78-   )  =>  { 
79-     if  ( isCheckmate )  { 
73+   const  currentTurn : 'w'  |  'b'  = 
74+     currentNode ?. turn  ||  ( recommendations . isBlackTurn  ? 'b'  : 'w' ) 
75+ 
76+   const  formatMateDisplay  =  ( mateValue : number )  =>  { 
77+     const  deliveringColor  = 
78+       mateValue  >  0  ? currentTurn  : currentTurn  ===  'w'  ? 'b'  : 'w' 
79+     const  prefix  =  deliveringColor  ===  'w'  ? '+'  : '-' 
80+     return  `${ prefix } ${ Math . abs ( mateValue ) }  
81+   } 
82+ 
83+   const  getStockfishEvalDisplay  =  ( )  =>  { 
84+     if  ( ! moveEvaluation ?. stockfish )  { 
85+       return  '...' 
86+     } 
87+ 
88+     const  {  stockfish }  =  moveEvaluation 
89+     const  isBlackTurn  =  currentTurn  ===  'b' 
90+ 
91+     if  ( stockfish . is_checkmate )  { 
8092      return  'Checkmate' 
8193    } 
82-     if  ( mateIn  !==  undefined )  { 
83-       // Show +M2/-M2 to indicate whose mate it is 
84-       const  sign  =  mateIn  >  0  ? '+'  : '-' 
85-       return  `${ sign } ${ Math . abs ( mateIn ) }  
94+ 
95+     const  mateEntries  =  Object . entries ( stockfish . mate_vec  ??  { } ) 
96+     const  positiveMates  =  mateEntries . filter ( ( [ ,  mate ] )  =>  mate  >  0 ) 
97+ 
98+     if  ( positiveMates . length  >  0 )  { 
99+       const  minMate  =  positiveMates . reduce ( 
100+         ( min ,  [ ,  mate ] )  =>  Math . min ( min ,  mate ) , 
101+         Infinity , 
102+       ) 
103+ 
104+       if  ( isFinite ( minMate ) )  { 
105+         return  formatMateDisplay ( minMate ) 
106+       } 
107+     } 
108+ 
109+     const  mateVec  =  stockfish . mate_vec  ??  { } 
110+     const  cpEntries  =  Object . entries ( stockfish . cp_vec ) 
111+     const  nonMateEntries  =  cpEntries . filter ( 
112+       ( [ move ] )  =>  mateVec [ move ]  ===  undefined , 
113+     ) 
114+     const  bestCp  =  nonMateEntries . reduce < number  |  null > ( ( acc ,  [ ,  cp ] )  =>  { 
115+       if  ( acc  ===  null )  { 
116+         return  cp 
117+       } 
118+       return  isBlackTurn  ? Math . min ( acc ,  cp )  : Math . max ( acc ,  cp ) 
119+     } ,  null ) 
120+ 
121+     if  ( bestCp  !==  null )  { 
122+       return  `${ bestCp  >  0  ? '+'  : '' } ${ ( bestCp  /  100 ) . toFixed ( 2 ) }  
86123    } 
87-     return  `${ cp  >  0  ? '+'  : '' } ${ ( cp  /  100 ) . toFixed ( 2 ) }  
124+ 
125+     const  opponentMates  =  mateEntries . filter ( ( [ ,  mate ] )  =>  mate  <  0 ) 
126+     if  ( opponentMates . length  >  0 )  { 
127+       const  maxMate  =  opponentMates . reduce ( 
128+         ( max ,  [ ,  mate ] )  =>  Math . max ( max ,  Math . abs ( mate ) ) , 
129+         0 , 
130+       ) 
131+ 
132+       if  ( maxMate  >  0 )  { 
133+         return  formatMateDisplay ( - maxMate ) 
134+       } 
135+     } 
136+ 
137+     const  fallbackCp  =  cpEntries . reduce < number  |  null > ( ( acc ,  [ ,  cp ] )  =>  { 
138+       if  ( acc  ===  null )  { 
139+         return  cp 
140+       } 
141+       return  isBlackTurn  ? Math . min ( acc ,  cp )  : Math . max ( acc ,  cp ) 
142+     } ,  null ) 
143+ 
144+     if  ( fallbackCp  !==  null )  { 
145+       return  `${ fallbackCp  >  0  ? '+'  : '' } ${ ( fallbackCp  /  100 ) . toFixed ( 2 ) }  
146+     } 
147+ 
148+     return  '...' 
88149  } 
89150  const  [ tooltipData ,  setTooltipData ]  =  useState < { 
90151    move : string 
@@ -246,23 +307,26 @@ export const Highlight: React.FC<Props> = ({
246307      return  currentTurn  ===  'w'  ? '0.0%'  : '100.0%' 
247308    } 
248309
249-     if  ( moveEvaluation ?. stockfish ?. is_checkmate )  { 
310+     const  stockfishEval  =  moveEvaluation ?. stockfish 
311+ 
312+     if  ( stockfishEval ?. is_checkmate )  { 
250313      const  currentTurn  =  currentNode ?. turn  ||  'w' 
251314      return  currentTurn  ===  'w'  ? '0.0%'  : '100.0%' 
252315    } 
253316
254-     if  ( moveEvaluation ?. stockfish ?. mate_in  !==  undefined )  { 
255-       const  mateIn  =  moveEvaluation . stockfish . mate_in 
256-       return  mateIn  >  0  ? '100.0%'  : '0.0%' 
257-     } 
258- 
259317    if  ( 
260-       isInFirst10Ply  && 
261-       moveEvaluation ?. stockfish ?. model_optimal_cp  !==  undefined 
318+       stockfishEval ?. model_move  && 
319+       stockfishEval . mate_vec  && 
320+       stockfishEval . mate_vec [ stockfishEval . model_move ]  !==  undefined 
262321    )  { 
263-       const  stockfishWinRate  =  cpToWinrate ( 
264-         moveEvaluation . stockfish . model_optimal_cp , 
265-       ) 
322+       const  mateValue  =  stockfishEval . mate_vec [ stockfishEval . model_move ] 
323+       const  deliveringColor  = 
324+         mateValue  >  0  ? currentTurn  : currentTurn  ===  'w'  ? 'b'  : 'w' 
325+       return  deliveringColor  ===  'w'  ? '100.0%'  : '0.0%' 
326+     } 
327+ 
328+     if  ( isInFirst10Ply  &&  stockfishEval ?. model_optimal_cp  !==  undefined )  { 
329+       const  stockfishWinRate  =  cpToWinrate ( stockfishEval . model_optimal_cp ) 
266330      return  `${ Math . round ( stockfishWinRate  *  1000 )  /  10 }  
267331    }  else  if  ( moveEvaluation ?. maia )  { 
268332      return  `${ Math . round ( moveEvaluation . maia . value  *  1000 )  /  10 }  
@@ -391,13 +455,7 @@ export const Highlight: React.FC<Props> = ({
391455            < p  className = "text-sm font-bold text-engine-1 md:text-sm lg:text-lg" > 
392456              { isCurrentPositionCheckmate 
393457                ? 'Checkmate' 
394-                 : moveEvaluation ?. stockfish 
395-                   ? formatEvaluation ( 
396-                       moveEvaluation . stockfish . model_optimal_cp , 
397-                       moveEvaluation . stockfish . mate_in , 
398-                       moveEvaluation . stockfish . is_checkmate , 
399-                     ) 
400-                   : '...' } 
458+                 : getStockfishEvalDisplay ( ) } 
401459            </ p > 
402460          </ div > 
403461
@@ -424,6 +482,11 @@ export const Highlight: React.FC<Props> = ({
424482            { recommendations . stockfish 
425483              ?. slice ( 0 ,  4 ) 
426484              . map ( ( {  move,  cp,  winrate,  cp_relative } ,  index )  =>  { 
485+                 const  mateValue  =  moveEvaluation ?. stockfish ?. mate_vec ?. [ move ] 
486+                 const  moveEvalDisplay  = 
487+                   mateValue  !==  undefined 
488+                     ? formatMateDisplay ( mateValue ) 
489+                     : `${ cp  >  0  ? '+'  : '' } ${ ( cp  /  100 ) . toFixed ( 2 ) }  
427490                return  ( 
428491                  < button 
429492                    key = { index } 
@@ -463,9 +526,7 @@ export const Highlight: React.FC<Props> = ({
463526                    < p 
464527                      className = { `text-right font-mono ${ simplified  ? 'text-sm'  : 'text-sm md:text-xxs xl:text-xs' }  } 
465528                    > 
466-                       { Math . abs ( cp )  >=  10000 
467-                         ? `${ cp  >  0  ? '+'  : '-' } ${ Math . max ( 1 ,  Math . floor ( Math . abs ( 10000  -  Math . abs ( cp ) )  /  100 )  +  1 ) }  
468-                         : `${ cp  >  0  ? '+'  : '' } ${ ( cp  /  100 ) . toFixed ( 2 ) }  } 
529+                       { moveEvalDisplay } 
469530                    </ p > 
470531                  </ button > 
471532                ) 
0 commit comments