@@ -4,37 +4,64 @@ namespace MinimalChess
44{
55 public class Evaluation
66 {
7- const int CheckmateScore = 9999 ;
8-
9- public static bool IsCheckmate ( int score ) => Math . Abs ( score ) == CheckmateScore ;
7+ public struct Eval
8+ {
9+ public short MidgameScore ;
10+ public short EndgameScore ;
11+ public short Phase ;
12+ public int Score
13+ {
14+ get
15+ {
16+ //linearily interpolate between midGame and endGame score based on current phase (tapered eval)
17+ double phase = Linstep ( Midgame , Endgame , Phase ) ;
18+ double score = MidgameScore + phase * ( EndgameScore - MidgameScore ) ;
19+ return ( int ) score ;
20+ }
21+ }
1022
11- public static int Checkmate ( Color color ) => ( int ) color * - CheckmateScore ;
23+ public Eval ( Board board ) : this ( )
24+ {
25+ for ( int i = 0 ; i < 64 ; i ++ )
26+ if ( board [ i ] != Piece . None )
27+ AddPiece ( board [ i ] , i ) ;
28+ }
1229
13- public static int Evaluate ( Board board )
14- {
15- int midGame = 0 ;
16- int endGame = 0 ;
17- int phaseValue = 0 ;
18- for ( int i = 0 ; i < 64 ; i ++ )
30+ public void Update ( Piece oldPiece , Piece newPiece , int index )
1931 {
20- Piece piece = board [ i ] ;
21- if ( piece == Piece . None )
22- continue ;
32+ if ( oldPiece != Piece . None )
33+ RemovePiece ( oldPiece , index ) ;
34+ if ( newPiece != Piece . None )
35+ AddPiece ( newPiece , index ) ;
36+ }
2337
24- int sign = ( int ) piece . Color ( ) ;
38+ private void AddPiece ( Piece piece , int squareIndex )
39+ {
40+ short color = ( short ) piece . Color ( ) ;
2541 int pieceIndex = PieceTableIndex ( piece ) ;
26- int squareIndex = SquareTableIndex ( i , piece ) ;
27- phaseValue += PhaseValues [ pieceIndex ] ;
28- midGame += sign * MidgameTables [ pieceIndex , squareIndex ] ;
29- endGame += sign * EndgameTables [ pieceIndex , squareIndex ] ;
42+ int tableIndex = SquareTableIndex ( squareIndex , piece ) ;
43+ Phase += PhaseValues [ pieceIndex ] ;
44+ MidgameScore += ( short ) ( color * MidgameTables [ pieceIndex , tableIndex ] ) ;
45+ EndgameScore += ( short ) ( color * EndgameTables [ pieceIndex , tableIndex ] ) ;
3046 }
3147
32- //linearily interpolate between midGame and endGame score based on current phase (tapered eval)
33- double phase = Linstep ( Midgame , Endgame , phaseValue ) ;
34- double score = midGame + phase * ( endGame - midGame ) ;
35- return ( int ) score ;
48+ private void RemovePiece ( Piece piece , int squareIndex )
49+ {
50+ int color = ( int ) piece . Color ( ) ;
51+ int pieceIndex = PieceTableIndex ( piece ) ;
52+ int tableIndex = SquareTableIndex ( squareIndex , piece ) ;
53+ Phase -= PhaseValues [ pieceIndex ] ;
54+ MidgameScore -= ( short ) ( color * MidgameTables [ pieceIndex , tableIndex ] ) ;
55+ EndgameScore -= ( short ) ( color * EndgameTables [ pieceIndex , tableIndex ] ) ;
56+ }
3657 }
3758
59+ const int CheckmateScore = 9999 ;
60+
61+ public static bool IsCheckmate ( int score ) => Math . Abs ( score ) == CheckmateScore ;
62+
63+ public static int Checkmate ( Color color ) => ( int ) color * - CheckmateScore ;
64+
3865 public static double Linstep ( double edge0 , double edge1 , double value )
3966 {
4067 return Math . Min ( 1 , Math . Max ( 0 , ( value - edge0 ) / ( edge1 - edge0 ) ) ) ;
@@ -50,13 +77,13 @@ public static double Linstep(double edge0, double edge1, double value)
5077 MeanSquareError(k=102): 0.23835033815795936
5178 */
5279
53- const int Midgame = 5255 ;
54- const int Endgame = 435 ;
80+ const short Midgame = 5255 ;
81+ const short Endgame = 435 ;
5582
5683 //Pawn = 0, Knight = 155, Bishop = 305; Rook = 405, Queen = 1050, King = 0
57- static readonly int [ ] PhaseValues = new int [ 6 ] { 0 , 155 , 305 , 405 , 1050 , 0 } ;
84+ static readonly short [ ] PhaseValues = new short [ 6 ] { 0 , 155 , 305 , 405 , 1050 , 0 } ;
5885
59- static readonly int [ , ] MidgameTables = new int [ 6 , 64 ] {
86+ static readonly short [ , ] MidgameTables = new short [ 6 , 64 ] {
6087 { //PAWN MG
6188 100 , 100 , 100 , 100 , 100 , 100 , 100 , 100 ,
6289 176 , 214 , 147 , 194 , 189 , 214 , 132 , 77 ,
@@ -119,7 +146,7 @@ public static double Linstep(double edge0, double edge1, double value)
119146 }
120147 } ;
121148
122- static readonly int [ , ] EndgameTables = new int [ 6 , 64 ] {
149+ static readonly short [ , ] EndgameTables = new short [ 6 , 64 ] {
123150 { //PAWN EG
124151 100 , 100 , 100 , 100 , 100 , 100 , 100 , 100 ,
125152 277 , 270 , 252 , 229 , 240 , 233 , 264 , 285 ,
@@ -181,7 +208,7 @@ public static double Linstep(double edge0, double edge1, double value)
181208 - 55 , - 40 , - 23 , - 6 , - 20 , - 8 , - 28 , - 47 ,
182209 } } ;
183210
184- public static int [ ] MobilityValues = new int [ 13 * 6 ]
211+ public static short [ ] MobilityValues = new short [ 13 * 6 ]
185212 {
186213 // opponent friendly
187214 // - P N B R Q K P N B R Q K
0 commit comments