2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #define OPENING_SCORE (side_score[OPENING][brd.wtm] - \
25 side_score[OPENING][1 ^ brd.wtm])
26 #define ENDGAME_SCORE (side_score[ENDGAME][brd.wtm] - \
27 side_score[ENDGAME][1 ^ brd.wtm])
29 static int rank_flip
[2][8] = {
30 { 0, 1, 2, 3, 4, 5, 6, 7 },
31 { 7, 6, 5, 4, 3, 2, 1, 0 }
34 /* cental pawns on their initial squares */
35 const uint64_t d2e2
[2] = {
36 0x0000000000001800ULL
, 0x0018000000000000ULL
38 /* bitmask for 7th rank */
39 const uint64_t rank7bb
[2] = {
40 0x00FF000000000000ULL
, 0x000000000000FF00ULL
43 static int king_score
[2][2];
44 static int mobility_score
[2][2];
45 static int pawn_score
[2][2];
46 static int position_score
[2][2];
47 static int side_score
[2][2];
49 /* passed pawns bitboard */
50 static uint64_t passers
[2];
52 /* bonus for side to move */
53 static int wtm_bonus
[2] = {10, 10};
55 /* forward declarations of functions */
56 static void append_scores(void);
57 static void evaluate_pawns(int side
);
58 static void evaluate_knights(int side
);
59 static void evaluate_bishops(int side
);
60 static void evaluate_rooks(int side
);
61 static void evaluate_queens(int side
);
62 static void evaluate_king(int side
);
63 static int evaluate_draw_pattern(void);
64 static int evaluate_mate(int side
);
65 static void evaluate_material_imbalances(int side
);
66 static void evaluate_blocked_pieces(int side
);
67 static void zero_scores(void);
72 side_score
[OPENING
][WHITE
] += king_score
[OPENING
][WHITE
] + \
73 mobility_score
[OPENING
][WHITE
] + pawn_score
[OPENING
][WHITE
] + \
74 position_score
[OPENING
][WHITE
];
75 side_score
[OPENING
][BLACK
] += king_score
[OPENING
][BLACK
] +
76 mobility_score
[OPENING
][BLACK
] + pawn_score
[OPENING
][BLACK
] + \
77 position_score
[OPENING
][BLACK
];
78 side_score
[ENDGAME
][WHITE
] += king_score
[ENDGAME
][WHITE
] + \
79 mobility_score
[ENDGAME
][WHITE
] + pawn_score
[ENDGAME
][WHITE
] + \
80 position_score
[ENDGAME
][WHITE
];
81 side_score
[ENDGAME
][BLACK
] += king_score
[ENDGAME
][BLACK
] + \
82 mobility_score
[ENDGAME
][BLACK
] + pawn_score
[ENDGAME
][BLACK
] + \
83 position_score
[ENDGAME
][BLACK
];
86 /* bonus for rook behind passed pawn */
87 static int rook_behind_pp
= 30;
89 /* bonus for having more pawns in endgame if there are no pieces
91 static int more_pawns_bonus
= 15;
93 static uint64_t pawn_attacks
[2];
95 /* return TRUE if current position is DRAW */
99 if (brd
.fifty_rule
>= 100)
100 return TRUE
; /* draw by fifty rule */
102 if (material_pawns
[WHITE
] || material_pawns
[BLACK
])
103 return FALSE
; /* there are some pawns on the board */
105 /* check for draw by insufficient material */
106 if (((material_complete
[WHITE
] < piece_value
[ROOK
]) || \
107 piece_count
[WHITE
][KNIGHT
] == 2) && \
108 ((material_complete
[BLACK
] < piece_value
[ROOK
]) || \
109 piece_count
[BLACK
][KNIGHT
] == 2))
115 /* evaluate current position */
117 evaluate(int alpha
, int beta
)
124 assert(alpha
>= -MATE_VALUE
&& beta
<= MATE_VALUE
);
125 assert(beta
> alpha
);
127 /* we should find mate position */
128 if ((!material_pawns
[WHITE
] && !material_complete
[BLACK
]) || \
129 (!material_pawns
[BLACK
] && !material_complete
[WHITE
])) {
130 mate_score
= evaluate_mate(WHITE
) - evaluate_mate(BLACK
);
132 return brd
.wtm
? -mate_score
: mate_score
;
135 /* check for drawish endgame */
136 if (evaluate_draw_pattern())
139 #ifdef STATISTIC_COUNTERS
140 counters
.evaluations
++;
144 side_score
[OPENING
][WHITE
] = material_complete
[WHITE
];
145 side_score
[OPENING
][BLACK
] = material_complete
[BLACK
];
146 side_score
[ENDGAME
][WHITE
] = material_complete
[WHITE
];
147 side_score
[ENDGAME
][BLACK
] = material_complete
[BLACK
];
150 side_score
[OPENING
][brd
.wtm
] += wtm_bonus
[OPENING
];
151 side_score
[ENDGAME
][brd
.wtm
] += wtm_bonus
[ENDGAME
];
153 pawn_attacks
[WHITE
] = ((PAWNS(WHITE
) & ~file_bit
[7]) << 9) | \
154 ((PAWNS(WHITE
) & ~file_bit
[0]) << 7);
155 pawn_attacks
[BLACK
] = ((PAWNS(BLACK
) & ~file_bit
[0]) >> 9) | \
156 ((PAWNS(BLACK
) & ~file_bit
[7]) >> 7);
158 for (side
= WHITE
; side
<= BLACK
; side
++) {
159 evaluate_pawns(side
);
160 evaluate_knights(side
);
161 evaluate_bishops(side
);
162 evaluate_rooks(side
);
163 evaluate_queens(side
);
165 evaluate_material_imbalances(side
);
166 evaluate_blocked_pieces(side
);
169 /* look for rook behind passer */
170 for (side
= WHITE
; side
<= BLACK
; side
++) {
173 uint64_t bb
= ROOKS(side
);
176 square
= bit_scan_clear(&bb
);
177 pp
= file_bit
[_FILE(square
)] & (passers
[WHITE
] | passers
[BLACK
]);
180 if (_RANK(bit_scan(pp
)) > _RANK(square
))
181 position_score
[ENDGAME
][side
] += rook_behind_pp
;
183 if (_RANK(bit_scan(pp
)) < _RANK(square
))
184 position_score
[ENDGAME
][side
] += rook_behind_pp
;
190 /* bonus for having more pawns if there are now pieces on the board */
191 if (!material_pieces
[WHITE
] && !material_pieces
[BLACK
])
192 side_score
[ENDGAME
][WHITE
] += (wpc
- bpc
) * more_pawns_bonus
;
196 /* bishop of opposite colours */
197 if (wqc
+ wrc
+ wnc
+ bqc
+ brc
+ bnc
== 0 && wbc
== 1 && \
198 bbc
== 1 && abs(wpc
- bpc
) <= 2) {
199 if (popcount((BISHOPS(WHITE
) | BISHOPS(BLACK
)) & WHITESQUARES
) == 1) {
200 side_score
[ENDGAME
][WHITE
] /= 2;
201 side_score
[ENDGAME
][BLACK
] /= 2;
205 /* get final score according to game phase */
206 score
= (OPENING_SCORE
* (256 - GAME_PHASE
) + \
207 ENDGAME_SCORE
* GAME_PHASE
) / 256;
208 assert(score
>= -MATE_VALUE
&& score
<= MATE_VALUE
);
213 /* can't win if we have two knights or a bishop and no pawns
214 (but theoretically we can, for example so called 'cooperative mate') */
215 if (score
> 0 && !material_pawns
[side
] && \
216 ((material_pieces
[side
] < piece_value
[ROOK
]) || \
217 (KNIGHTS(side
) == r_pieces
[side
]))) {
219 } else if (score
< 0 && !material_pawns
[xside
] && \
220 ((material_pieces
[xside
] < piece_value
[ROOK
]) || \
221 (KNIGHTS(xside
) == r_pieces
[xside
]))) {
225 if (wqc
== bqc
&& wrc
== brc
&& abs(wbc
+ wnc
- bbc
- bnc
) < 2) {
227 /* no pawns and one side is ahead by minor piece */
231 if (side
== WHITE
&& (wbc
+ wnc
- bbc
- bnc
== 1) && !wpc
&& bpc
) {
233 } else if (side
== BLACK
&& (bbc
+ bnc
- wbc
- wnc
== 1) && !bpc
&& wpc
) {
240 /* ROOK vs [KNIGHT|BISHOP] + (PAWN)? */
241 if ((material_pieces
[WHITE
] == piece_value
[ROOK
] && !wpc
) && \
242 ((material_pieces
[BLACK
] == piece_value
[KNIGHT
] && bpc
<= 1) || \
243 (material_pieces
[BLACK
] == piece_value
[BISHOP
] && bpc
<= 1)))
245 else if ((material_pieces
[BLACK
] == piece_value
[ROOK
] && !bpc
) && \
246 ((material_pieces
[WHITE
] == piece_value
[KNIGHT
] && wpc
<= 1) || \
247 (material_pieces
[WHITE
] == piece_value
[BISHOP
] && wpc
<= 1)))
253 static int pawn_square_op
[2][64] = {
255 -15, -5, 0, 5, 5, 0, -5, -15,
256 -15, -5, 0, 5, 5, 0, -5, -15,
257 -15, -5, 0, 15, 15, 0, -5, -15,
258 -15, -5, 0, 25, 25, 0, -5, -15,
259 -15, -5, 0, 15, 15, 0, -5, -15,
260 -15, -5, 0, 5, 5, 0, -5, -15,
261 -15, -5, 0, 5, 5, 0, -5, -15,
262 -15, -5, 0, 5, 5, 0, -5, -15
265 -15, -5, 0, 5, 5, 0, -5, -15,
266 -15, -5, 0, 5, 5, 0, -5, -15,
267 -15, -5, 0, 5, 5, 0, -5, -15,
268 -15, -5, 0, 15, 15, 0, -5, -15,
269 -15, -5, 0, 25, 25, 0, -5, -15,
270 -15, -5, 0, 15, 15, 0, -5, -15,
271 -15, -5, 0, 5, 5, 0, -5, -15,
272 -15, -5, 0, 5, 5, 0, -5, -15
276 static int pawn_square_eg
[2][64] = {
278 0, 0, 0, 0, 0, 0, 0, 0,
279 -1, -0, -0, -0, -0, -0, -0, -1,
280 -1, 0, 0, 0, 0, 0, 0, -1,
281 0, 0, 0, 5, 5, 0, 0, 0,
282 0, 5, 5, 10, 10, 5, 5, 0,
283 0, 5, 5, 10, 10, 5, 5, 0,
284 5, 15, 15, 15, 15, 15, 15, 5,
285 0, 0, 0, 0, 0, 0, 0, 0
288 0, 0, 0, 0, 0, 0, 0, 0,
289 5, 15, 15, 15, 15, 15, 15, 5,
290 0, 5, 5, 10, 10, 5, 5, 0,
291 0, 5, 5, 10, 10, 5, 5, 0,
292 0, 0, 0, 5, 5, 0, 0, 0,
293 -1, 0, 0, 0, 0, 0, 0, -1,
294 -1, -0, -0, -0, -0, -0, -0, -1,
295 0, 0, 0, 0, 0, 0, 0, 0
298 /* bonus for passed pawns */
299 static int passer_score_op
[8] = {0, 0, 10, 15, 30, 45, 80, 0};
300 static int passer_score_eg
[8] = {0, 0, 20, 35, 60, 10, 160, 0};
301 /* bonus for candidate passers */
302 static int can_passed_score_op
[8] = {0, 0, 5, 10, 20, 35, 50, 0};
303 static int can_passed_score_eg
[8] = {0, 0, 10, 20, 40, 70, 100, 0};
304 /* penalty for isolated pawns */
305 static int isolated_penalty_op
[8] = {-6, -8, -10, -12, -12, -10, -8, -6};
306 static int isolated_penalty_eg
[8] = {-7, -10, -14, -20, -20, -14, -10, -7};
307 /* penalty for isolated pawns on open files */
308 static int weak_isolated_penalty_op
[8] = {-9, -10, -12, -18, -18, -12, -10, -9};
309 static int weak_isolated_penalty_eg
[8] = {-10, -12, -14, -20, -20, -14, -12, -10};
310 /* penalty for doubled pawns */
311 static int doubled_penalty_op
[8] = {-6, -8, -10, -12, -12, -10, -8, -6};
312 static int doubled_penalty_eg
[8] = {-7, -10, -14, -20, -20, -14, -10, -7};
313 /* penalty for backward pawns */
314 static int backward_penalty_op
= -8;
315 static int backward_penalty_eg
= -10;
318 evaluate_pawns(int side
)
324 int score_op
, score_eg
;
328 int side_defenders
, xside_attackers
;
329 struct pawn_hash_entry_t
*phe
;
334 passers
[side
] = 0ULL;
337 phe
= pawn_hash
[side
] + (brd
.hash_pawn_key
& pawn_hash_mask
);
339 if (e
.pawn_hash_enabled
&& phe
->key
== brd
.hash_pawn_key
) {
340 score_op
= phe
->score_op
;
341 score_eg
= phe
->score_eg
;
342 passers
[side
] = phe
->passers
;
344 counters
.pawn_hash_evaluations
++;
348 square
= bit_scan_clear(&bb
);
351 if (!(forward_ray
[side
][square
] & PAWNS(side
))) {
352 /* this is most advanced pawn */
353 if (!(PAWNS(xside
) & passer_mask
[side
][square
])) {
354 /* no opponents pawns on adjacent files */
355 score_op
+= passer_score_op
[rank_flip
[side
][_RANK(square
)]];
356 score_eg
+= passer_score_eg
[rank_flip
[side
][_RANK(square
)]];
358 SET(passers
[side
], square
);
362 } else if (!(forward_ray
[side
][square
] & PAWNS(xside
))) {
363 /* no opponent's pawns on the same file */
365 /* how many pawns defend our candidate */
366 side_defenders
= popcount(pawn_moves
[side
][square
] &
368 /* how many pawns attack our candidate */
369 xside_attackers
= popcount(pawn_moves
[side
][square
] & \
372 if (xside_attackers
<= side_defenders
) {
373 /* pawn is well protected */
375 /* how many pawns can support our candidate */
376 side_defenders
= popcount((passer_mask
[xside
][square
+ \
377 (side
== WHITE
? 8 : -8)] & \
378 isolated_mask
[_FILE(square
)]) & PAWNS(side
));
379 /* how many pawns can stop our candidate */
380 xside_attackers
= popcount(passer_mask
[side
][square
] & \
383 if (xside_attackers
<= side_defenders
)
384 /* true passed pawn candidate */
385 score_op
+= can_passed_score_op
[rank_flip
[side
][_RANK(square
)]];
386 score_eg
+= can_passed_score_eg
[rank_flip
[side
][_RANK(square
)]];
390 if (isolated_mask
[_FILE(square
)] & PAWNS(side
)) {
391 /* pawn is not isolated, but maybe backward? */
392 if (!((passer_mask
[xside
][square
+ (side
== WHITE
? 8 : -8)] & \
393 isolated_mask
[_FILE(square
)]) & PAWNS(side
)) && \
394 (rank_flip
[side
][square
] != 1)) {
395 /* pawn is somewhat backward */
396 b
= pawn_moves
[side
][square
];
402 if (b
& PAWNS(xside
)) {
403 /* next square is attacked by opponents pawn */
404 score_op
+= backward_penalty_op
;
405 score_eg
+= backward_penalty_eg
;
407 /* backward on semiopen file */
408 if ((forward_ray
[side
][square
] & PAWNS(xside
)) == 0)
409 score_op
+= backward_penalty_op
;
414 /* pawn is isolated */
415 if (!(forward_ray
[side
][square
] & \
416 (PAWNS(side
) | PAWNS(xside
)))) {
417 /* isolated on semiopen file */
418 score_op
+= weak_isolated_penalty_op
[_FILE(square
)];
419 score_eg
+= weak_isolated_penalty_eg
[_FILE(square
)];
421 score_op
+= isolated_penalty_op
[_FILE(square
)];
422 score_eg
+= isolated_penalty_eg
[_FILE(square
)];
427 score_op
+= pawn_square_op
[side
][square
];
428 score_eg
+= pawn_square_eg
[side
][square
];
430 /* store scores in hashtable */
431 if (e
.pawn_hash_enabled
) {
432 phe
->key
= brd
.hash_pawn_key
;
433 phe
->score_op
= score_op
;
434 phe
->score_eg
= score_eg
;
435 phe
->passers
= passers
[side
];
439 /* evaluate doubled pawns */
440 for (i
= 0; i
< 8; i
++) {
441 count
= popcount(file_bit
[i
] & PAWNS(side
));
443 score_op
+= doubled_penalty_op
[i
] * (count
- 1);
444 score_eg
+= doubled_penalty_eg
[i
] * (count
- 1);
448 pawn_score
[OPENING
][side
] += score_op
;
449 pawn_score
[ENDGAME
][side
] += score_eg
;
452 static int knight_square_op
[2][64] = {
454 -35, -25, -20, -15, -15, -20, -25, -35,
455 -20, -15, -10, -5, -5, -10, -15, -20,
456 -10, -5, 0, 5, 5, 0, -5, -10,
457 -5, 0, 5, 10, 10, 5, 0, -5,
458 -5, 5, 10, 15, 15, 10, 5, -5,
459 -3, 5, 10, 10, 10, 10, 5, -3,
460 -10, -5, 0, 5, 5, 0, -5, -10,
461 -25, -15, -10, -10, -10, -10, -15, -25
464 -25, -15, -10, -10, -10, -10, -15, -25,
465 -10, -5, 0, 5, 5, 0, -5, -10,
466 -3, 5, 10, 10, 10, 10, 5, -3,
467 -5, 5, 10, 15, 15, 10, 5, -5,
468 -5, 0, 5, 10, 10, 5, 0, -5,
469 -10, -5, 0, 5, 5, 0, -5, -10,
470 -20, -15, -10, -5, -5, -10, -15, -20,
471 -35, -25, -20, -15, -15, -20, -25, -35
475 static int knight_square_eg
[64] = {
476 -30, -20, -15, -10, -10, -15, -20, -30,
477 -20, -15, -10, -5, -5, -10, -15, -20,
478 -15, -10, 0, 5, 5, 0, -10, -15,
479 -10, -5, 5, 10, 10, 5, -5, -10,
480 -10, -5, 5, 10, 10, 5, -5, -10,
481 -15, -10, 0, 5, 5, 0, -10, -15,
482 -20, -15, -10, -5, -5, -10, -15, -20,
483 -30, -20, -15, -10, -10, -15, -20, -30
486 static int knight_outpost
[2][64] = {
488 0, 0, 0, 0, 0, 0, 0, 0,
489 0, 0, 0, 0, 0, 0, 0, 0,
490 0, 0, 0, 0, 0, 0, 0, 0,
491 0, 5, 9, 15, 15, 9, 5, 0,
492 0, 5, 9, 18, 18, 9, 5, 0,
493 0, 0, 5, 9, 9, 5, 0, 0,
494 0, 0, 0, 0, 0, 0, 0, 0,
495 0, 0, 0, 0, 0, 0, 0, 0
498 0, 0, 0, 0, 0, 0, 0, 0,
499 0, 0, 0, 0, 0, 0, 0, 0,
500 0, 0, 5, 9, 9, 5, 0, 0,
501 0, 5, 9, 18, 18, 9, 5, 0,
502 0, 5, 9, 15, 15, 9, 5, 0,
503 0, 0, 0, 0, 0, 0, 0, 0,
504 0, 0, 0, 0, 0, 0, 0, 0,
505 0, 0, 0, 0, 0, 0, 0, 0
509 static int knight_mobility_op
[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
510 static int knight_mobility_eg
[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
512 /* evaluate knights */
514 evaluate_knights(int side
)
520 uint64_t mobility_xmask
;
523 my_knights
= KNIGHTS(side
);
526 mobility_xmask
= ~(side_boards
[side
] | pawn_attacks
[xside
]);
529 square
= bit_scan_clear(&my_knights
);
531 /* piece square tables */
532 position_score
[OPENING
][side
] += knight_square_op
[side
][square
];
533 position_score
[ENDGAME
][side
] += knight_square_eg
[square
];
535 if (knight_outpost
[side
][square
])
536 /* is there enemy pawn that can potentially attack
538 if (!(PAWNS(xside
) & (passer_mask
[side
][square
] & \
539 isolated_mask
[_FILE(square
)])))
540 if (pawn_moves
[xside
][square
] & PAWNS(side
)) {
541 /* knight is supported by our pawn */
542 position_score
[OPENING
][side
] += knight_outpost
[side
][square
];
543 position_score
[ENDGAME
][side
] += knight_outpost
[side
][square
];
546 /* calculate mobility */
547 mobility
= popcount(piece_moves
[KNIGHT
][square
] & mobility_xmask
);
548 mobility_score
[OPENING
][side
] += knight_mobility_op
[mobility
];
549 mobility_score
[ENDGAME
][side
] += knight_mobility_eg
[mobility
];
553 static int bishop_square_op
[2][64] = {
555 -10, -10, -10, -5, -5, -10, -10, -10,
556 -5, -5, -5, 0, 0, -5, -5, -5,
557 -3, -1, 2, 3, 3, 2, -1, -3,
558 -2, 0, 3, 5, 5, 3, 0, -2,
559 -2, 0, 3, 5, 5, 3, 0, -2,
560 -3, -1, 2, 5, 5, 2, -1, -2,
561 -5, -2, 0, 0, 0, 0, -2, -5,
562 -10, -10, -10, -10, -10, -10, -10, -10
565 -10, -10, -10, -10, -10, -10, -10, -10,
566 -5, -2, 0, 0, 0, 0, -2, -5,
567 -3, -1, 2, 5, 5, 2, -1, -2,
568 -2, 0, 3, 5, 5, 3, 0, -2,
569 -2, 0, 3, 5, 5, 3, 0, -2,
570 -3, -1, 2, 3, 3, 2, -1, -3,
571 -5, -5, -5, 0, 0, -5, -5, -5,
572 -10, -10, -10, -5, -5, -10, -10, -10
576 static int bishop_square_eg
[64] = {
577 -10, -10, -10, -5, -5, -10, -10, -10,
578 -5, -5, -5, 0, 0, -5, -5, -5,
579 -3, -1, 2, 3, 3, 2, -1, -3,
580 -2, 0, 3, 5, 5, 3, 0, -2,
581 -2, 0, 3, 5, 5, 3, 0, -2,
582 -3, -1, 2, 5, 5, 2, -1, -2,
583 -5, -5, -5, 0, 0, -5, -5, -5,
584 -10, -10, -10, -5, -5, -10, -10, -10
587 static int bishop_mobility_op
[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 49, 60, 60};
588 static int bishop_mobility_eg
[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 59, 60, 60};
590 /* evaluate bishops */
592 evaluate_bishops(int side
)
599 uint64_t mobility_xmask
;
603 xk
= brd
.kings
[xside
];
604 my_bishops
= BISHOPS(side
);
607 /* exclude these squares from mobility */
608 mobility_xmask
= ~(side_boards
[side
] | pawn_attacks
[xside
]);
611 square
= bit_scan_clear(&my_bishops
);
613 attacks
= BISHOP_ATTACKS(square
, complete
);
615 /* calculate mobility */
616 mobility
= popcount(attacks
& mobility_xmask
);
617 mobility_score
[OPENING
][side
] += bishop_mobility_op
[mobility
];
618 mobility_score
[ENDGAME
][side
] += bishop_mobility_eg
[mobility
];
620 position_score
[OPENING
][side
] += bishop_square_op
[side
][square
];
621 position_score
[ENDGAME
][side
] += bishop_square_eg
[square
];
625 static int rook_on_semiopen_file_op
= 10;
626 static int rook_on_semiopen_file_eg
= 10;
628 static int rook_on_semiopen_file_near_king_op
= 15;
629 static int rook_on_semiopen_file_before_king_op
= 20;
631 static int rook_on_open_file_op
= 15;
632 static int rook_on_open_file_eg
= 15;
634 static int rook_on_seven_rank_op
= 20;
635 static int rook_on_seven_rank_eg
= 20;
637 static int rook_mobility_op
[] = {
638 -12, -8, -4, 0, 4, 8, 11, 14, 16, 18, 19, 20, 21, 22, 23, 24
640 static int rook_mobility_eg
[] = {
641 -20, -12, -4, 4, 12, 20, 28, 36, 44, 50, 54, 56, 57, 58, 59, 60
645 evaluate_rooks(int side
)
654 uint64_t mobility_xmask
;
656 my_rooks
= ROOKS(side
);
657 xside
= 1 ^ side
; /* opponent's color */
658 xk
= brd
.kings
[xside
]; /* location of opponent's king */
661 /* exclude these squares from mobility */
662 mobility_xmask
= ~(side_boards
[side
] | pawn_attacks
[xside
]);
665 square
= bit_scan_clear(&my_rooks
);
666 file
= _FILE(square
);
668 if (!(PAWNS(side
) & file_bit
[file
])) {
669 /* there are no our pawns on the rook's file */
670 if (PAWNS(xside
) & file_bit
[file
]) {
671 /* ... but there are opponent's pawns */
672 if (file
== (_FILE(xk
) - 1) || file
== (_FILE(xk
) + 1))
673 /* opponent's king is on the adjacent file */
674 position_score
[OPENING
][side
] += rook_on_semiopen_file_near_king_op
;
675 else if (file
== _FILE(xk
))
676 /* opponent's king is on the same file */
677 position_score
[OPENING
][side
] += rook_on_semiopen_file_before_king_op
;
679 /* rook on semiopen file */
680 position_score
[OPENING
][side
] += rook_on_semiopen_file_op
;
681 position_score
[ENDGAME
][side
] += rook_on_semiopen_file_eg
;
684 /* rook on open file */
685 position_score
[OPENING
][side
] += rook_on_open_file_op
;
686 position_score
[ENDGAME
][side
] += rook_on_open_file_eg
;
689 if (rank_flip
[side
][_RANK(square
)] == 6) {
690 /* rook on 7th rank */
691 position_score
[OPENING
][side
] += rook_on_seven_rank_op
;
692 position_score
[ENDGAME
][side
] += rook_on_seven_rank_eg
;
695 attacks
= ROOK_ATTACKS(square
, complete
);
696 /* calculate mobility */
697 mobility
= popcount(attacks
& mobility_xmask
);
698 mobility_score
[OPENING
][side
] += rook_mobility_op
[mobility
];
699 mobility_score
[ENDGAME
][side
] += rook_mobility_eg
[mobility
];
703 /* queen evaluation */
705 evaluate_queens(int side
)
707 /* TODO: mobility, attacks */
710 static int king_square_op
[2][64] = {
712 40, 50, 30, 10, 10, 30, 50, 40,
713 30, 40, 20, 0, 0, 20, 40, 30,
714 10, 20, 0, -20, -20, 0, 20, 10,
715 0, 10, -10, -30, -30, -10, 10, 0,
716 -10, 0, -20, -40, -40, -20, 0, -10,
717 -20, -10, -30, -50, -50, -30, -10, -20,
718 -30, -20, -40, -60, -60, -40, -20, -30,
719 -40, -30, -50, -70, -70, -50, -30, -40
722 -40, -30, -50, -70, -70, -50, -30, -40,
723 -30, -20, -40, -60, -60, -40, -20, -30,
724 -20, -10, -30, -50, -50, -30, -10, -20,
725 -10, 0, -20, -40, -40, -20, 0, -10,
726 0, 10, -10, -30, -30, -10, 10, 0,
727 10, 20, 0, -20, -20, 0, 20, 10,
728 30, 40, 20, 0, 0, 20, 40, 30,
729 40, 50, 30, 10, 10, 30, 50, 40
733 static int king_square_eg
[64] = {
734 -72, -48, -36, -24, -24, -36, -48, -72,
735 -48, -24, -12, 0, 0, -12, -24, -48,
736 -36, -12, 0, 12, 12, 0, -12, -36,
737 -24, 0, 12, 24, 24, 12, 0, -24,
738 -24, 0, 12, 24, 24, 12, 0, -24,
739 -36, -12, 0, 12, 12, 0, -12, -36,
740 -48, -24, -12, 0, 0, -12, -24, -48,
741 -72, -48, -36, -24, -24, -36, -48, -72
746 evaluate_king(int side
)
754 xside
= 1 ^ side
; /* opponent's side */
755 square
= brd
.kings
[side
];
756 file
= _FILE(square
);
758 /* pawn shield and pawn attacks */
759 bb
= passer_mask
[side
][square
] & PAWNS(side
);
760 xbb
= passer_mask
[side
][square
] & PAWNS(xside
);
763 /* in case if there is no our pawn */
764 king_score
[OPENING
][side
] += -36;
766 if (bb
& file_bit
[file
- 1]) {
767 /* find nearest pawn */
769 i
= bit_scan_rev(bb
& file_bit
[file
- 1]);
771 i
= bit_scan(bb
& file_bit
[file
- 1]);
772 king_score
[OPENING
][side
] += (7 - rank_flip
[side
][_RANK(i
)]) * \
773 (7 - rank_flip
[side
][_RANK(i
)]);
777 if (xbb
& file_bit
[file
- 1]) {
779 i
= bit_scan_rev(xbb
& file_bit
[file
- 1]);
781 i
= bit_scan(xbb
& file_bit
[file
- 1]);
782 king_score
[OPENING
][side
] -= MAX(0, (5 - rank_flip
[side
][_RANK(i
)])) * 15;
786 /* in case if there is no our pawn in front of our king */
787 king_score
[OPENING
][side
] += -36;
789 if (bb
& file_bit
[file
]) {
791 i
= bit_scan_rev(bb
& file_bit
[file
]);
793 i
= bit_scan(bb
& file_bit
[file
]);
794 king_score
[OPENING
][side
] += (7 - rank_flip
[side
][_RANK(i
)]) * \
795 (7 - rank_flip
[side
][_RANK(i
)]);
798 if (xbb
& file_bit
[file
]) {
800 i
= bit_scan_rev(xbb
& file_bit
[file
]);
802 i
= bit_scan(xbb
& file_bit
[file
]);
803 king_score
[OPENING
][side
] -= MAX(0, (5 - rank_flip
[side
][_RANK(i
)])) * 15;
807 /* in case if there is no our pawn */
808 king_score
[OPENING
][side
] += -36;
809 if (bb
& file_bit
[file
+ 1]) {
810 /* find nearest pawn */
812 i
= bit_scan_rev(bb
& file_bit
[file
+ 1]);
814 i
= bit_scan(bb
& file_bit
[file
+ 1]);
815 king_score
[OPENING
][side
] += (7 - rank_flip
[side
][_RANK(i
)]) * \
816 (7 - rank_flip
[side
][_RANK(i
)]);
820 if (xbb
& file_bit
[file
+ 1]) {
822 i
= bit_scan_rev(xbb
& file_bit
[file
+ 1]);
824 i
= bit_scan(xbb
& file_bit
[file
+ 1]);
825 king_score
[OPENING
][side
] -= MAX(0, (5 - rank_flip
[side
][_RANK(i
)])) * 15;
829 position_score
[OPENING
][side
] += king_square_op
[side
][square
];
830 position_score
[ENDGAME
][side
] += king_square_eg
[square
];
833 static int blocked_rook
= -50;
834 static int trapped_bishop
= -100;
837 evaluate_blocked_pieces(int side
)
839 int xside
= 1 ^ side
;
840 int side_inc
= side
* (A8
- A1
);
843 if (square64
[F1
+ side_inc
] == KING
|| square64
[G1
+ side_inc
] == KING
) {
844 if (square64
[G1
+ side_inc
] == ROOK
|| square64
[H1
+ side_inc
] == ROOK
)
845 position_score
[OPENING
][side
] += blocked_rook
;
846 } else if (square64
[C1
+ side_inc
] == KING
|| square64
[B1
+ side_inc
] == KING
) {
847 if (square64
[A1
+ side_inc
] == ROOK
|| square64
[B1
+ side_inc
] == ROOK
)
848 position_score
[OPENING
][side
] += blocked_rook
;
851 int b_sq_a7
= side
== WHITE
? A7
: A2
;
852 int b_sq_h7
= side
== WHITE
? H7
: H2
;
853 int p_sq_b6
= side
== WHITE
? B6
: B3
;
854 int p_sq_g6
= side
== WHITE
? G6
: G3
;
856 if ((BISHOPS(side
) & BIT(b_sq_a7
)) && (PAWNS(xside
) & BIT(p_sq_b6
)) && \
857 SEE(SET_FROM(b_sq_a7
) | SET_TO(p_sq_b6
) | SET_TYPE(TYPE_CAPTURE
)) < 0) {
858 position_score
[OPENING
][side
] += trapped_bishop
;
859 position_score
[ENDGAME
][side
] += trapped_bishop
;
861 if ((BISHOPS(side
) & BIT(b_sq_h7
)) && (PAWNS(xside
) & BIT(p_sq_g6
)) && \
862 SEE(SET_FROM(b_sq_h7
) | SET_TO(p_sq_g6
) | SET_TYPE(TYPE_CAPTURE
)) < 0) {
863 position_score
[OPENING
][side
] += trapped_bishop
;
864 position_score
[ENDGAME
][side
] += trapped_bishop
;
872 king_score
[OPENING
][WHITE
] = 0;
873 king_score
[OPENING
][BLACK
] = 0;
874 king_score
[ENDGAME
][WHITE
] = 0;
875 king_score
[ENDGAME
][BLACK
] = 0;
877 mobility_score
[OPENING
][WHITE
] = 0;
878 mobility_score
[OPENING
][BLACK
] = 0;
879 mobility_score
[ENDGAME
][WHITE
] = 0;
880 mobility_score
[ENDGAME
][BLACK
] = 0;
882 pawn_score
[OPENING
][WHITE
] = 0;
883 pawn_score
[OPENING
][BLACK
] = 0;
884 pawn_score
[ENDGAME
][WHITE
] = 0;
885 pawn_score
[ENDGAME
][BLACK
] = 0;
887 position_score
[OPENING
][WHITE
] = 0;
888 position_score
[OPENING
][BLACK
] = 0;
889 position_score
[ENDGAME
][WHITE
] = 0;
890 position_score
[ENDGAME
][BLACK
] = 0;
893 static int simple_mate_squares
[2][64] = {
895 160, 140, 120, 100, 100, 120, 140, 160,
896 140, 120, 100, 80, 80, 100, 120, 140,
897 120, 100, 80, 60, 60, 80, 100, 120,
898 100, 80, 60, 40, 40, 60, 80, 100,
899 100, 80, 60, 40, 40, 60, 80, 100,
900 120, 100, 80, 60, 60, 80, 100, 120,
901 140, 120, 100, 80, 80, 100, 120, 140,
902 160, 140, 120, 100, 100, 120, 140, 160
905 160, 140, 120, 100, 100, 120, 140, 160,
906 140, 120, 100, 80, 80, 100, 120, 140,
907 120, 100, 80, 60, 60, 80, 100, 120,
908 100, 80, 60, 40, 40, 60, 80, 100,
909 100, 80, 60, 40, 40, 60, 80, 100,
910 120, 100, 80, 60, 60, 80, 100, 120,
911 140, 120, 100, 80, 80, 100, 120, 140,
912 160, 140, 120, 100, 100, 120, 140, 160
916 /* for KING vs KING, KNIGHT, BISHOP */
917 static int b_n_mate_dark_squares
[64] = {
918 99, 90, 80, 70, 60, 50, 40, 30,
919 90, 80, 70, 60, 50, 40, 30, 40,
920 80, 70, 60, 50, 40, 30, 40, 50,
921 70, 60, 50, 40, 30, 40, 50, 60,
922 60, 50, 40, 30, 40, 50, 60, 70,
923 50, 40, 30, 40, 50, 60, 70, 80,
924 40, 30, 40, 50, 60, 70, 80, 90,
925 30, 40, 50, 60, 70, 80, 90, 99
928 static int b_n_mate_light_squares
[64] = {
929 30, 40, 50, 60, 70, 80, 90, 99,
930 40, 30, 40, 50, 60, 70, 80, 90,
931 50, 40, 30, 40, 50, 60, 70, 80,
932 60, 50, 40, 30, 40, 50, 60, 70,
933 70, 60, 50, 40, 30, 40, 50, 60,
934 80, 70, 60, 50, 40, 30, 40, 50,
935 90, 80, 70, 60, 50, 40, 30, 40,
936 99, 90, 80, 70, 60, 50, 40, 30
940 evaluate_mate(int side
)
943 int xside
= 1 ^ side
;
945 if (material_complete
[side
]) {
946 score
= material_complete
[side
] + 200;
948 if (piece_count
[side
][KNIGHT
] == 1 && piece_count
[side
][BISHOP
] == 1) {
949 if (BISHOPS(side
) & BLACKSQUARES
)
950 score
+= b_n_mate_dark_squares
[brd
.kings
[xside
]];
952 score
+= b_n_mate_light_squares
[brd
.kings
[xside
]];
954 score
+= simple_mate_squares
[side
][brd
.kings
[xside
]];
955 score
-= distance
[brd
.kings
[side
]][brd
.kings
[xside
]] * 10;
961 static int evaluate_draw_pattern()
966 if (!material_pieces
[BLACK
] && bpc
<= 1 && material_pawns
[WHITE
] && \
967 material_pieces
[WHITE
] == piece_value
[BISHOP
] && wbc
== 1 && \
968 ((PAWNS(WHITE
) & file_bit
[0]) == PAWNS(WHITE
) || (PAWNS(WHITE
) & \
969 file_bit
[7]) == PAWNS(WHITE
))) {
971 square
= bit_scan(PAWNS(WHITE
));
972 file
= _FILE(square
);
974 if (file
== 0 || file
== 7) {
976 if (file
== 0 && (WHITESQUARES
& BISHOPS(WHITE
)))
978 if (file
== 7 && (BLACKSQUARES
& BISHOPS(WHITE
)))
980 if (distance
[brd
.kings
[BLACK
]][file
== 0? A8
: H8
] <= 1)
983 } else if (!material_pieces
[WHITE
] && wpc
<= 1 && \
984 material_pieces
[BLACK
] == piece_value
[BISHOP
] && bbc
== 1 && \
985 ((PAWNS(BLACK
) & file_bit
[0]) == PAWNS(BLACK
) || (PAWNS(BLACK
) & \
986 file_bit
[7]) == PAWNS(BLACK
))) {
987 square
= bit_scan(PAWNS(BLACK
));
988 file
= _FILE(square
);
990 if (file
== 0 || file
== 7) {
992 if (file
== 0 && (BLACKSQUARES
& BISHOPS(BLACK
)))
994 if (file
== 7 && (WHITESQUARES
& BISHOPS(BLACK
)))
996 if (distance
[brd
.kings
[WHITE
]][file
== 0? A1
: H1
] <= 1)
1004 static int bishop_pair
= 50;
1005 static int bishop_pair_correction
= 15;
1007 /* based on Larry Kaufman's paper */
1009 evaluate_material_imbalances(int side
)
1011 /* TODO: more imbalances */
1016 if (piece_count
[side
][BISHOP
] > 1) {
1017 side_score
[OPENING
][side
] += bishop_pair
;
1018 side_score
[ENDGAME
][side
] += bishop_pair
;
1020 /* how many pawns on the board? */
1024 side_score
[OPENING
][side
] -= bishop_pair_correction
;
1025 side_score
[ENDGAME
][side
] -= bishop_pair_correction
;
1026 } else if (pc
< 8) {
1027 side_score
[OPENING
][side
] += bishop_pair_correction
;
1028 side_score
[ENDGAME
][side
] += bishop_pair_correction
;