2222#include " board.h"
2323#include " evalscores.h"
2424#include < cstring>
25+ #include < math.h>
26+
2527struct EvalData
2628{
2729 int king_attackers_count[2 ] = {0 };
2830 int king_attackers_weight[2 ] = {0 };
2931 uint64_t king_ring[2 ] = {0 };
32+ int attackers_count[2 ];
3033
3134 void init (Position const &position)
3235 {
3336 std::memset (this , 0 , sizeof (EvalData));
3437 king_ring[White] = Attacks::king (get_lsb (position.pieces .get_piece_bb <King>(White)));
3538 king_ring[Black] = Attacks::king (get_lsb (position.pieces .get_piece_bb <King>(Black)));
3639 }
40+ void update_attackers_count (uint64_t attacks, Color by)
41+ {
42+ attackers_count[by] += popcount64 (attacks);
43+ }
3744};
3845
3946template <PieceType pt, bool safe = false >
@@ -42,6 +49,8 @@ static constexpr int calculate_moblity(Position const &position, EvalData &data,
4249 uint64_t occupancy = position.total_occupancy ();
4350 uint64_t attacks = Attacks::generate (pt, sq, occupancy);
4451
52+ data.update_attackers_count (attacks, us);
53+
4554 if constexpr (!safe)
4655 {
4756 if (attacks & data.king_ring [!us])
@@ -133,14 +142,16 @@ static Square psqt_sq(Square sq, Color color)
133142 return color == White ? flip_square (sq) : sq;
134143}
135144
136- static int evaluate_pawn (Position const &position, EvalData, Square sq, Color us)
145+ static int evaluate_pawn (Position const &position, EvalData& data , Square sq, Color us)
137146{
138147 int score = 0 ;
139148 uint64_t enemy_pawns = position.pieces .get_piece_bb <Pawn>(!us);
140149 uint64_t friend_pawns = position.pieces .get_piece_bb <Pawn>(us);
141150 uint64_t enemy = position.pieces .get_occupancy (!us);
142151 uint64_t ahead_squares = BitMask::passed_pawn[us][sq] & BitMask::files[sq];
143152
153+ data.update_attackers_count (BitMask::pawn_attacks[us][sq], us);
154+
144155 score += PawnEval::psqt[psqt_sq (sq, us)];
145156 score += pawn_is_isolated (friend_pawns, sq) * PawnEval::isolated;
146157 score += pawn_is_stacked (friend_pawns, sq) * PawnEval::stacked;
@@ -157,8 +168,6 @@ static int evaluate_pawn(Position const &position, EvalData, Square sq, Color us
157168 if (BitMask::pawn_attacks[!us][sq] & friend_pawns)
158169 score += PawnEval::passed_connected;
159170 }
160-
161-
162171 return score;
163172}
164173
@@ -295,6 +304,8 @@ static int eval_king(Position const &position, EvalData &data, Color us)
295304 int score = KingEval::psqt[psqt_sq (sq, us)];
296305 Color enemy = !us;
297306
307+ data.update_attackers_count (BitMask::king_attacks[sq], us);
308+
298309 if (data.king_attackers_count [enemy] >= 2 )
299310 {
300311 int weight = data.king_attackers_weight [enemy];
@@ -308,6 +319,12 @@ static int eval_king(Position const &position, EvalData &data, Color us)
308319 return score;
309320}
310321
322+ template <Color us>
323+ static inline int evaluate_control (EvalData& data)
324+ {
325+ return MiscEval::control * (data.attackers_count [us] - data.attackers_count [!us]);
326+ }
327+
311328static inline int scale_score (Position const &position, int score)
312329{
313330#define mg_score (s ) ((int16_t )((uint16_t )((unsigned )((s)))))
@@ -336,6 +353,9 @@ int eval_position(Position const &position)
336353 score += eval_king (position, data, White);
337354 score -= eval_king (position, data, Black);
338355
356+ score += evaluate_control<White>(data);
357+ score -= evaluate_control<Black>(data);
358+
339359 score = scale_score (position, score);
340360
341361 return position.side == White ? score : -score;
0 commit comments