@@ -12,6 +12,12 @@ type EvaluationPart struct {
1212 PieceScore int
1313 PieceSquareScoreMidgame int
1414 PieceSquareScoreEndgame int
15+ PairModifier int
16+ TempoModifier int
17+ RookFileModifier int
18+ BlockedPiecesModifier int
19+ KingShieldModifier int
20+ PassedPawnModifier int
1521}
1622
1723type Evaluation struct {
@@ -23,6 +29,26 @@ type Evaluation struct {
2329 TotalScorePerspective int
2430}
2531
32+ func (e * Evaluation ) CalculateEvaluation (g * game.Game ) int {
33+ e .Game = g
34+ e .GameOver = e .Game .Result != game .GameNotOver
35+
36+ e .White = EvaluationPart {}
37+ e .Black = EvaluationPart {}
38+
39+ if ! e .GameOver {
40+ e .White = calculateEvaluationPart (g , game .White )
41+ e .Black = calculateEvaluationPart (g , game .Black )
42+ }
43+
44+ e .updateTotal ()
45+ return e .TotalScorePerspective
46+ }
47+
48+ func (e * Evaluation ) GetPieceTypeValue (pieceType dragontoothmg.Piece ) int {
49+ return weights [game .White ].Midgame .Material [pieceType ]
50+ }
51+
2652func (e * Evaluation ) updateTotal () {
2753 if e .GameOver {
2854 if e .Game .Result == game .WhiteWon {
@@ -48,35 +74,35 @@ func (e *Evaluation) updateTotal() {
4874 e .TotalScore += (gamePhase * e .White .PieceSquareScoreMidgame + (24 - gamePhase )* e .White .PieceSquareScoreEndgame ) / 24
4975 e .TotalScore -= (gamePhase * e .Black .PieceSquareScoreMidgame + (24 - gamePhase )* e .Black .PieceSquareScoreEndgame ) / 24
5076
77+ e .TotalScore += e .White .PairModifier
78+ e .TotalScore -= e .Black .PairModifier
79+ e .TotalScore += e .White .TempoModifier
80+ e .TotalScore -= e .Black .TempoModifier
81+ e .TotalScore += e .White .RookFileModifier
82+ e .TotalScore -= e .Black .RookFileModifier
83+ e .TotalScore += e .White .BlockedPiecesModifier
84+ e .TotalScore -= e .Black .BlockedPiecesModifier
85+ e .TotalScore += e .White .KingShieldModifier
86+ e .TotalScore -= e .Black .KingShieldModifier
87+ e .TotalScore += e .White .PassedPawnModifier
88+ e .TotalScore -= e .Black .PassedPawnModifier
89+
5190 e .TotalScorePerspective = e .TotalScore
5291 if ! e .Game .Position .Wtomove {
5392 e .TotalScorePerspective = - e .TotalScore
5493 }
5594}
5695
57- func (e * Evaluation ) CalculateEvaluation (g * game.Game ) int {
58- e .Game = g
59- e .GameOver = e .Game .Result != game .GameNotOver
60-
61- e .White = EvaluationPart {}
62- e .Black = EvaluationPart {}
63-
64- if ! e .GameOver {
65- e .White = calculateEvaluationPart (g , game .White )
66- e .Black = calculateEvaluationPart (g , game .Black )
67- }
68-
69- e .updateTotal ()
70- return e .TotalScorePerspective
71- }
72-
7396func calculateEvaluationPart (g * game.Game , color game.PlayerColor ) EvaluationPart {
7497 ps , pstMid , pstEnd := calculateMaterialScore (g , color )
7598 evalPart := EvaluationPart {
7699 GamePhase : calculateGamephase (g , color ),
77100 PieceScore : ps ,
78101 PieceSquareScoreMidgame : pstMid ,
79102 PieceSquareScoreEndgame : pstEnd ,
103+ PairModifier : calculatePairModifier (g , color ),
104+ TempoModifier : calculateTempoModifier (g , color ),
105+ RookFileModifier : calculateRookModifier (g , color ),
80106 }
81107 return evalPart
82108}
@@ -143,6 +169,61 @@ func calculateMaterialScoreForPieceType(g *game.Game, color game.PlayerColor, pi
143169 return ps , pstMid , pstEnd
144170}
145171
146- func (e * Evaluation ) GetPieceTypeValue (pieceType dragontoothmg.Piece ) int {
147- return weights [game .White ].Midgame .Material [pieceType ]
172+ func calculatePairModifier (g * game.Game , color game.PlayerColor ) (result int ) {
173+ bboards := g .Position .White
174+ if color == game .Black {
175+ bboards = g .Position .Black
176+ }
177+
178+ if bits .OnesCount64 (bboards .Bishops ) >= 2 {
179+ result += weights [color ].AdditionalModifier .BishopPairModifier
180+ }
181+ if bits .OnesCount64 (bboards .Knights ) >= 2 {
182+ result += weights [color ].AdditionalModifier .KnightPairModifier
183+ }
184+ if bits .OnesCount64 (bboards .Rooks ) >= 2 {
185+ result += weights [color ].AdditionalModifier .RookPairModifier
186+ }
187+
188+ return
189+ }
190+
191+ func calculateTempoModifier (g * game.Game , color game.PlayerColor ) (result int ) {
192+ if g .Position .Wtomove == bool (color ) {
193+ result += weights [color ].AdditionalModifier .TempoModifier
194+ }
195+ return
196+ }
197+
198+ func calculateRookModifier (g * game.Game , color game.PlayerColor ) (result int ) {
199+ bboardsOwn := g .Position .White
200+ bboardsOther := g .Position .Black
201+ if color == game .Black {
202+ bboardsOwn = g .Position .Black
203+ bboardsOther = g .Position .White
204+ }
205+
206+ pawnFillOwn := calculatePawnFileFill (bboardsOwn .Pawns )
207+ pawnFillOther := calculatePawnFileFill (bboardsOther .Pawns )
208+
209+ openFiles := ^ pawnFillOwn & ^ pawnFillOther
210+ halfOpenFiles := ^ pawnFillOwn ^ openFiles
211+
212+ rooksOnOpenFiles := bits .OnesCount64 (bboardsOwn .Rooks & openFiles )
213+ rooksOnHalfOpenFiles := bits .OnesCount64 (bboardsOwn .Rooks & halfOpenFiles )
214+
215+ return rooksOnOpenFiles * weights [color ].AdditionalModifier .OpenRookModifier + rooksOnHalfOpenFiles * weights [color ].AdditionalModifier .HalfRookModifier
216+ }
217+
218+ func calculatePawnFileFill (pawnBitboard uint64 ) uint64 {
219+ // Northfill
220+ pawnBitboard |= (pawnBitboard << 8 )
221+ pawnBitboard |= (pawnBitboard << 16 )
222+ pawnBitboard |= (pawnBitboard << 32 )
223+ // Southfill
224+ pawnBitboard |= (pawnBitboard >> 8 )
225+ pawnBitboard |= (pawnBitboard >> 16 )
226+ pawnBitboard |= (pawnBitboard >> 32 )
227+
228+ return pawnBitboard
148229}
0 commit comments