Fixed bug in evaluate_king()
[owl.git] / evaluate.c
blob7715101dd34d69bd857e851cca82727bb9a52399
1 /*
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.
16 #include "common.h"
17 #include "attacks.h"
18 #include "board.h"
19 #include "engine.h"
20 #include "evaluate.h"
21 #include "move.h"
22 #include "trans.h"
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_attacks[2];
44 static int king_attackers[2];
45 static int king_score[2][2];
46 static int mobility_score[2][2];
47 static int pawn_score[2][2];
48 static int position_score[2][2];
49 static int side_score[2][2];
51 /* passed pawns bitboard */
52 static uint64_t passers[2];
54 /* bonus for side to move */
55 static int wtm_bonus[2] = {10, 10};
57 /* forward declarations of functions */
58 static void append_scores(void);
59 static void evaluate_pawns(int side);
60 static void evaluate_knights(int side);
61 static void evaluate_bishops(int side);
62 static void evaluate_rooks(int side);
63 static void evaluate_queens(int side);
64 static void evaluate_king(int side);
65 static int evaluate_draw_pattern(void);
66 static int evaluate_mate(int side);
67 static void evaluate_material_imbalances(int side);
68 static void evaluate_blocked_pieces(int side);
69 static void zero_scores(void);
71 static inline void
72 append_scores(void)
74 side_score[OPENING][WHITE] += king_score[OPENING][WHITE] + \
75 mobility_score[OPENING][WHITE] + pawn_score[OPENING][WHITE] + \
76 position_score[OPENING][WHITE];
77 side_score[OPENING][BLACK] += king_score[OPENING][BLACK] +
78 mobility_score[OPENING][BLACK] + pawn_score[OPENING][BLACK] + \
79 position_score[OPENING][BLACK];
80 side_score[ENDGAME][WHITE] += king_score[ENDGAME][WHITE] + \
81 mobility_score[ENDGAME][WHITE] + pawn_score[ENDGAME][WHITE] + \
82 position_score[ENDGAME][WHITE];
83 side_score[ENDGAME][BLACK] += king_score[ENDGAME][BLACK] + \
84 mobility_score[ENDGAME][BLACK] + pawn_score[ENDGAME][BLACK] + \
85 position_score[ENDGAME][BLACK];
88 /* bonus for rook behind passed pawn */
89 static int rook_behind_pp = 30;
91 /* bonus for having more pawns in endgame if there are no pieces
92 on the board */
93 static int more_pawns_bonus = 15;
95 static uint64_t pawn_attacks[2];
97 /* return TRUE if current position is DRAW */
98 int
99 evaluate_draw(void)
101 if (brd.fifty_rule >= 100)
102 return TRUE; /* draw by fifty rule */
104 if (material_pawns[WHITE] || material_pawns[BLACK])
105 return FALSE; /* there are some pawns on the board */
107 /* check for draw by insufficient material */
108 if (((material_complete[WHITE] < piece_value[ROOK]) || \
109 piece_count[WHITE][KNIGHT] == 2) && \
110 ((material_complete[BLACK] < piece_value[ROOK]) || \
111 piece_count[BLACK][KNIGHT] == 2))
112 return TRUE;
114 return FALSE;
117 /* evaluate current position */
118 int
119 evaluate(int alpha, int beta)
121 int score;
122 int mate_score;
123 int side;
124 int xside;
126 assert(alpha >= -MATE_VALUE && beta <= MATE_VALUE);
127 assert(beta > alpha);
129 /* we should find mate position */
130 if ((!material_pawns[WHITE] && !material_complete[BLACK]) || \
131 (!material_pawns[BLACK] && !material_complete[WHITE])) {
132 mate_score = evaluate_mate(WHITE) - evaluate_mate(BLACK);
133 if (mate_score)
134 return brd.wtm ? -mate_score : mate_score;
137 /* check for drawish endgame */
138 if (evaluate_draw_pattern())
139 return 0;
141 #ifdef STATISTIC_COUNTERS
142 counters.evaluations++;
143 #endif
144 zero_scores();
146 side_score[OPENING][WHITE] = material_complete[WHITE];
147 side_score[OPENING][BLACK] = material_complete[BLACK];
148 side_score[ENDGAME][WHITE] = material_complete[WHITE];
149 side_score[ENDGAME][BLACK] = material_complete[BLACK];
151 /* wtm bonus */
152 side_score[OPENING][brd.wtm] += wtm_bonus[OPENING];
153 side_score[ENDGAME][brd.wtm] += wtm_bonus[ENDGAME];
155 pawn_attacks[WHITE] = ((PAWNS(WHITE) & ~file_bit[7]) << 9) | \
156 ((PAWNS(WHITE) & ~file_bit[0]) << 7);
157 pawn_attacks[BLACK] = ((PAWNS(BLACK) & ~file_bit[0]) >> 9) | \
158 ((PAWNS(BLACK) & ~file_bit[7]) >> 7);
160 for (side = WHITE; side <= BLACK; side++) {
161 evaluate_pawns(side);
162 evaluate_knights(side);
163 evaluate_bishops(side);
164 evaluate_rooks(side);
165 evaluate_queens(side);
166 evaluate_king(side);
167 evaluate_material_imbalances(side);
168 evaluate_blocked_pieces(side);
171 /* look for rook behind passer */
172 for (side = WHITE; side <= BLACK; side++) {
173 int square;
174 uint64_t pp;
175 uint64_t bb = ROOKS(side);
177 while (bb) {
178 square = bit_scan_clear(&bb);
179 pp = file_bit[_FILE(square)] & (passers[WHITE] | passers[BLACK]);
180 if (pp) {
181 if (side == WHITE) {
182 if (_RANK(bit_scan(pp)) > _RANK(square))
183 position_score[ENDGAME][side] += rook_behind_pp;
184 } else {
185 if (_RANK(bit_scan(pp)) < _RANK(square))
186 position_score[ENDGAME][side] += rook_behind_pp;
192 /* bonus for having more pawns if there are now pieces on the board */
193 if (!material_pieces[WHITE] && !material_pieces[BLACK])
194 side_score[ENDGAME][WHITE] += (wpc - bpc) * more_pawns_bonus;
196 append_scores();
198 /* bishop of opposite colours */
199 if (wqc + wrc + wnc + bqc + brc + bnc == 0 && wbc == 1 && \
200 bbc == 1 && abs(wpc - bpc) <= 2) {
201 if (popcount((BISHOPS(WHITE) | BISHOPS(BLACK)) & WHITESQUARES) == 1) {
202 side_score[ENDGAME][WHITE] /= 2;
203 side_score[ENDGAME][BLACK] /= 2;
207 /* get final score according to game phase */
208 score = (OPENING_SCORE * (256 - GAME_PHASE) + \
209 ENDGAME_SCORE * GAME_PHASE) / 256;
210 assert(score >= -MATE_VALUE && score <= MATE_VALUE);
212 side = brd.wtm;
213 xside = 1 ^ side;
215 /* can't win if we have two knights or a bishop and no pawns
216 (but theoretically we can, for example so called 'cooperative mate') */
217 if (score > 0 && !material_pawns[side] && \
218 ((material_pieces[side] < piece_value[ROOK]) || \
219 (KNIGHTS(side) == r_pieces[side]))) {
220 score = 0;
221 } else if (score < 0 && !material_pawns[xside] && \
222 ((material_pieces[xside] < piece_value[ROOK]) || \
223 (KNIGHTS(xside) == r_pieces[xside]))) {
224 score = 0;
227 if (wqc == bqc && wrc == brc && abs(wbc + wnc - bbc - bnc) < 2) {
228 if (!wpc && !bpc) {
229 /* no pawns and one side is ahead by minor piece */
230 score /= 2;
231 } else {
232 if (score > 0) {
233 if (side == WHITE && (wbc + wnc - bbc - bnc == 1) && !wpc && bpc) {
234 score /= bpc + 1;
235 } else if (side == BLACK && (bbc + bnc - wbc - wnc == 1) && !bpc && wpc) {
236 score /= wpc + 1;
242 /* ROOK vs [KNIGHT|BISHOP] + (PAWN)? */
243 if ((material_pieces[WHITE] == piece_value[ROOK] && !wpc) && \
244 ((material_pieces[BLACK] == piece_value[KNIGHT] && bpc <= 1) || \
245 (material_pieces[BLACK] == piece_value[BISHOP] && bpc <= 1)))
246 score /= 8;
247 else if ((material_pieces[BLACK] == piece_value[ROOK] && !bpc) && \
248 ((material_pieces[WHITE] == piece_value[KNIGHT] && wpc <= 1) || \
249 (material_pieces[WHITE] == piece_value[BISHOP] && wpc <= 1)))
250 score /= 8;
252 return score;
255 static int pawn_square_op[2][64] = {
257 -15, -5, 0, 5, 5, 0, -5, -15,
258 -15, -5, 0, 5, 5, 0, -5, -15,
259 -15, -5, 0, 15, 15, 0, -5, -15,
260 -15, -5, 0, 25, 25, 0, -5, -15,
261 -15, -5, 0, 15, 15, 0, -5, -15,
262 -15, -5, 0, 5, 5, 0, -5, -15,
263 -15, -5, 0, 5, 5, 0, -5, -15,
264 -15, -5, 0, 5, 5, 0, -5, -15
267 -15, -5, 0, 5, 5, 0, -5, -15,
268 -15, -5, 0, 5, 5, 0, -5, -15,
269 -15, -5, 0, 5, 5, 0, -5, -15,
270 -15, -5, 0, 15, 15, 0, -5, -15,
271 -15, -5, 0, 25, 25, 0, -5, -15,
272 -15, -5, 0, 15, 15, 0, -5, -15,
273 -15, -5, 0, 5, 5, 0, -5, -15,
274 -15, -5, 0, 5, 5, 0, -5, -15
278 static int pawn_square_eg[2][64] = {
280 0, 0, 0, 0, 0, 0, 0, 0,
281 -1, -0, -0, -0, -0, -0, -0, -1,
282 -1, 0, 0, 0, 0, 0, 0, -1,
283 0, 0, 0, 5, 5, 0, 0, 0,
284 0, 5, 5, 10, 10, 5, 5, 0,
285 0, 5, 5, 10, 10, 5, 5, 0,
286 5, 15, 15, 15, 15, 15, 15, 5,
287 0, 0, 0, 0, 0, 0, 0, 0
290 0, 0, 0, 0, 0, 0, 0, 0,
291 5, 15, 15, 15, 15, 15, 15, 5,
292 0, 5, 5, 10, 10, 5, 5, 0,
293 0, 5, 5, 10, 10, 5, 5, 0,
294 0, 0, 0, 5, 5, 0, 0, 0,
295 -1, 0, 0, 0, 0, 0, 0, -1,
296 -1, -0, -0, -0, -0, -0, -0, -1,
297 0, 0, 0, 0, 0, 0, 0, 0
300 /* bonus for passed pawns */
301 static int passer_score_op[8] = {0, 0, 10, 15, 30, 45, 80, 0};
302 static int passer_score_eg[8] = {0, 0, 20, 35, 60, 10, 160, 0};
303 /* bonus for candidate passers */
304 static int can_passed_score_op[8] = {0, 0, 5, 10, 20, 35, 50, 0};
305 static int can_passed_score_eg[8] = {0, 0, 10, 20, 40, 70, 100, 0};
306 /* penalty for isolated pawns */
307 static int isolated_penalty_op[8] = {-6, -8, -10, -12, -12, -10, -8, -6};
308 static int isolated_penalty_eg[8] = {-7, -10, -14, -20, -20, -14, -10, -7};
309 /* penalty for isolated pawns on open files */
310 static int weak_isolated_penalty_op[8] = {-9, -10, -12, -18, -18, -12, -10, -9};
311 static int weak_isolated_penalty_eg[8] = {-10, -12, -14, -20, -20, -14, -12, -10};
312 /* penalty for doubled pawns */
313 static int doubled_penalty_op[8] = {-6, -8, -10, -12, -12, -10, -8, -6};
314 static int doubled_penalty_eg[8] = {-7, -10, -14, -20, -20, -14, -10, -7};
315 /* penalty for backward pawns */
316 static int backward_penalty_op = -8;
317 static int backward_penalty_eg = -10;
319 static void
320 evaluate_pawns(int side)
322 uint64_t b, bb;
323 int i;
324 int count;
325 int square;
326 int score_op, score_eg;
327 int xside;
329 int passed;
330 int side_defenders, xside_attackers;
331 struct pawn_hash_entry_t *phe;
333 score_op = 0;
334 score_eg = 0;
335 xside = 1 ^ side;
336 passers[side] = 0ULL;
337 bb = PAWNS(side);
339 phe = pawn_hash[side] + (brd.hash_pawn_key & pawn_hash_mask);
341 if (e.pawn_hash_enabled && phe->key == brd.hash_pawn_key) {
342 score_op = phe->score_op;
343 score_eg = phe->score_eg;
344 passers[side] = phe->passers;
345 #ifdef STATISTIC_COUNTERS
346 counters.pawn_hash_evaluations++;
347 #endif
348 } else {
349 while (bb) {
350 passed = FALSE;
351 square = bit_scan_clear(&bb);
353 /* search passers */
354 if (!(forward_ray[side][square] & PAWNS(side))) {
355 /* this is most advanced pawn */
356 if (!(PAWNS(xside) & passer_mask[side][square])) {
357 /* no opponents pawns on adjacent files */
358 score_op += passer_score_op[rank_flip[side][_RANK(square)]];
359 score_eg += passer_score_eg[rank_flip[side][_RANK(square)]];
361 SET(passers[side], square);
363 passed = TRUE;
365 } else if (!(forward_ray[side][square] & PAWNS(xside))) {
366 /* no opponent's pawns on the same file */
368 /* how many pawns defend our candidate */
369 side_defenders = popcount(pawn_moves[side][square] &
370 PAWNS(xside));
371 /* how many pawns attack our candidate */
372 xside_attackers = popcount(pawn_moves[side][square] & \
373 PAWNS(xside));
375 if (xside_attackers <= side_defenders) {
376 /* pawn is well protected */
378 /* how many pawns can support our candidate */
379 side_defenders = popcount((passer_mask[xside][square + \
380 (side == WHITE? 8 : -8)] & \
381 isolated_mask[_FILE(square)]) & PAWNS(side));
382 /* how many pawns can stop our candidate */
383 xside_attackers = popcount(passer_mask[side][square] & \
384 PAWNS(xside));
386 if (xside_attackers <= side_defenders)
387 /* true passed pawn candidate */
388 score_op += can_passed_score_op[rank_flip[side][_RANK(square)]];
389 score_eg += can_passed_score_eg[rank_flip[side][_RANK(square)]];
393 if (isolated_mask[_FILE(square)] & PAWNS(side)) {
394 /* pawn is not isolated, but maybe backward? */
395 if (!((passer_mask[xside][square + (side == WHITE? 8 : -8)] & \
396 isolated_mask[_FILE(square)]) & PAWNS(side)) && \
397 (rank_flip[side][square] != 1)) {
398 /* pawn is somewhat backward */
399 b = pawn_moves[side][square];
400 if (side == WHITE)
401 b <<= 8;
402 else
403 b >>= 8;
405 if (b & PAWNS(xside)) {
406 /* next square is attacked by opponents pawn */
407 score_op += backward_penalty_op;
408 score_eg += backward_penalty_eg;
410 /* backward on semiopen file */
411 if ((forward_ray[side][square] & PAWNS(xside)) == 0)
412 score_op += backward_penalty_op;
415 } else {
416 if (!passed) {
417 /* pawn is isolated */
418 if (!(forward_ray[side][square] & \
419 (PAWNS(side) | PAWNS(xside)))) {
420 /* isolated on semiopen file */
421 score_op += weak_isolated_penalty_op[_FILE(square)];
422 score_eg += weak_isolated_penalty_eg[_FILE(square)];
423 } else {
424 score_op += isolated_penalty_op[_FILE(square)];
425 score_eg += isolated_penalty_eg[_FILE(square)];
430 score_op += pawn_square_op[side][square];
431 score_eg += pawn_square_eg[side][square];
433 /* store scores in hashtable */
434 if (e.pawn_hash_enabled) {
435 phe->key = brd.hash_pawn_key;
436 phe->score_op = score_op;
437 phe->score_eg = score_eg;
438 phe->passers = passers[side];
442 /* evaluate doubled pawns */
443 for (i = 0; i < 8; i++) {
444 count = popcount(file_bit[i] & PAWNS(side));
445 if (count > 1) {
446 score_op += doubled_penalty_op[i] * (count - 1);
447 score_eg += doubled_penalty_eg[i] * (count - 1);
451 pawn_score[OPENING][side] += score_op;
452 pawn_score[ENDGAME][side] += score_eg;
455 static int knight_square_op[2][64] = {
457 -35, -25, -20, -15, -15, -20, -25, -35,
458 -20, -15, -10, -5, -5, -10, -15, -20,
459 -10, -5, 0, 5, 5, 0, -5, -10,
460 -5, 0, 5, 10, 10, 5, 0, -5,
461 -5, 5, 10, 15, 15, 10, 5, -5,
462 -3, 5, 10, 10, 10, 10, 5, -3,
463 -10, -5, 0, 5, 5, 0, -5, -10,
464 -25, -15, -10, -10, -10, -10, -15, -25
467 -25, -15, -10, -10, -10, -10, -15, -25,
468 -10, -5, 0, 5, 5, 0, -5, -10,
469 -3, 5, 10, 10, 10, 10, 5, -3,
470 -5, 5, 10, 15, 15, 10, 5, -5,
471 -5, 0, 5, 10, 10, 5, 0, -5,
472 -10, -5, 0, 5, 5, 0, -5, -10,
473 -20, -15, -10, -5, -5, -10, -15, -20,
474 -35, -25, -20, -15, -15, -20, -25, -35
478 static int knight_square_eg[64] = {
479 -30, -20, -15, -10, -10, -15, -20, -30,
480 -20, -15, -10, -5, -5, -10, -15, -20,
481 -15, -10, 0, 5, 5, 0, -10, -15,
482 -10, -5, 5, 10, 10, 5, -5, -10,
483 -10, -5, 5, 10, 10, 5, -5, -10,
484 -15, -10, 0, 5, 5, 0, -10, -15,
485 -20, -15, -10, -5, -5, -10, -15, -20,
486 -30, -20, -15, -10, -10, -15, -20, -30
489 static int knight_outpost[2][64] = {
491 0, 0, 0, 0, 0, 0, 0, 0,
492 0, 0, 0, 0, 0, 0, 0, 0,
493 0, 0, 0, 0, 0, 0, 0, 0,
494 0, 5, 9, 15, 15, 9, 5, 0,
495 0, 5, 9, 18, 18, 9, 5, 0,
496 0, 0, 5, 9, 9, 5, 0, 0,
497 0, 0, 0, 0, 0, 0, 0, 0,
498 0, 0, 0, 0, 0, 0, 0, 0
501 0, 0, 0, 0, 0, 0, 0, 0,
502 0, 0, 0, 0, 0, 0, 0, 0,
503 0, 0, 5, 9, 9, 5, 0, 0,
504 0, 5, 9, 18, 18, 9, 5, 0,
505 0, 5, 9, 15, 15, 9, 5, 0,
506 0, 0, 0, 0, 0, 0, 0, 0,
507 0, 0, 0, 0, 0, 0, 0, 0,
508 0, 0, 0, 0, 0, 0, 0, 0
512 static int knight_mobility_op[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
513 static int knight_mobility_eg[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
515 /* evaluate knights */
516 static void
517 evaluate_knights(int side)
519 int square;
520 int xside;
521 int xk;
522 int mobility;
523 int attack_count;
524 uint64_t my_knights;
525 uint64_t mobility_xmask;
527 xside = 1 ^ side;
528 xk = brd.kings[xside];
529 my_knights = KNIGHTS(side);
531 if (my_knights)
532 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
534 while (my_knights) {
535 square = bit_scan_clear(&my_knights);
537 /* piece square tables */
538 position_score[OPENING][side] += knight_square_op[side][square];
539 position_score[ENDGAME][side] += knight_square_eg[square];
541 if (knight_outpost[side][square])
542 /* is there enemy pawn that can potentially attack
543 our knight? */
544 if (!(PAWNS(xside) & (passer_mask[side][square] & \
545 isolated_mask[_FILE(square)])))
546 if (pawn_moves[xside][square] & PAWNS(side)) {
547 /* knight is supported by our pawn */
548 position_score[OPENING][side] += knight_outpost[side][square];
549 position_score[ENDGAME][side] += knight_outpost[side][square];
552 /* calculate mobility */
553 mobility = popcount(piece_moves[KNIGHT][square] & mobility_xmask);
554 mobility_score[OPENING][side] += knight_mobility_op[mobility];
555 mobility_score[ENDGAME][side] += knight_mobility_eg[mobility];
557 /* king attacks */
558 attack_count = popcount(piece_moves[KING][xk] &
559 (piece_moves[KNIGHT][square] | BIT(xk)));
560 if (attack_count) {
561 king_attacks[side] += attack_count;
562 king_attackers[side]++;
567 static int bishop_square_op[2][64] = {
569 -10, -10, -10, -5, -5, -10, -10, -10,
570 -5, -5, -5, 0, 0, -5, -5, -5,
571 -3, -1, 2, 3, 3, 2, -1, -3,
572 -2, 0, 3, 5, 5, 3, 0, -2,
573 -2, 0, 3, 5, 5, 3, 0, -2,
574 -3, -1, 2, 5, 5, 2, -1, -2,
575 -5, -2, 0, 0, 0, 0, -2, -5,
576 -10, -10, -10, -10, -10, -10, -10, -10
579 -10, -10, -10, -10, -10, -10, -10, -10,
580 -5, -2, 0, 0, 0, 0, -2, -5,
581 -3, -1, 2, 5, 5, 2, -1, -2,
582 -2, 0, 3, 5, 5, 3, 0, -2,
583 -2, 0, 3, 5, 5, 3, 0, -2,
584 -3, -1, 2, 3, 3, 2, -1, -3,
585 -5, -5, -5, 0, 0, -5, -5, -5,
586 -10, -10, -10, -5, -5, -10, -10, -10
590 static int bishop_square_eg[64] = {
591 -10, -10, -10, -5, -5, -10, -10, -10,
592 -5, -5, -5, 0, 0, -5, -5, -5,
593 -3, -1, 2, 3, 3, 2, -1, -3,
594 -2, 0, 3, 5, 5, 3, 0, -2,
595 -2, 0, 3, 5, 5, 3, 0, -2,
596 -3, -1, 2, 5, 5, 2, -1, -2,
597 -5, -5, -5, 0, 0, -5, -5, -5,
598 -10, -10, -10, -5, -5, -10, -10, -10
601 static int bishop_mobility_op[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 49, 60, 60};
602 static int bishop_mobility_eg[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 59, 60, 60};
604 /* evaluate bishops */
605 static void
606 evaluate_bishops(int side)
608 int square;
609 int mobility;
610 int xk;
611 int xside;
612 int attack_count;
613 uint64_t attacks;
614 uint64_t mobility_xmask;
615 uint64_t my_bishops;
617 xside = 1 ^ side;
618 xk = brd.kings[xside];
619 my_bishops = BISHOPS(side);
621 if (my_bishops)
622 /* exclude these squares from mobility */
623 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
625 while (my_bishops) {
626 square = bit_scan_clear(&my_bishops);
628 attacks = BISHOP_ATTACKS(square, complete);
630 /* calculate mobility */
631 mobility = popcount(attacks & mobility_xmask);
632 mobility_score[OPENING][side] += bishop_mobility_op[mobility];
633 mobility_score[ENDGAME][side] += bishop_mobility_eg[mobility];
635 position_score[OPENING][side] += bishop_square_op[side][square];
636 position_score[ENDGAME][side] += bishop_square_eg[square];
638 /* king attacks */
639 attack_count = popcount(BISHOP_ATTACKS(square, complete & ~attacks) &
640 (piece_moves[KING][xk] | BIT(xk)));
641 if (attack_count) {
642 king_attacks[side] += attack_count;
643 king_attackers[side]++;
648 static int rook_on_semiopen_file_op = 10;
649 static int rook_on_semiopen_file_eg = 10;
651 static int rook_on_semiopen_file_near_king_op = 15;
652 static int rook_on_semiopen_file_before_king_op = 20;
654 static int rook_on_open_file_op = 15;
655 static int rook_on_open_file_eg = 15;
657 static int rook_on_seven_rank_op = 20;
658 static int rook_on_seven_rank_eg = 20;
660 static int rook_mobility_op[] = {
661 -12, -8, -4, 0, 4, 8, 11, 14, 16, 18, 19, 20, 21, 22, 23, 24
663 static int rook_mobility_eg[] = {
664 -20, -12, -4, 4, 12, 20, 28, 36, 44, 50, 54, 56, 57, 58, 59, 60
667 static void
668 evaluate_rooks(int side)
670 int xk;
671 int file;
672 int square;
673 int xside;
674 int mobility;
675 int attack_count;
676 uint64_t my_rooks;
677 uint64_t attacks;
678 uint64_t mobility_xmask;
680 my_rooks = ROOKS(side);
681 xside = 1 ^ side; /* opponent's color */
682 xk = brd.kings[xside]; /* location of opponent's king */
684 if (my_rooks)
685 /* exclude these squares from mobility */
686 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
688 while (my_rooks) {
689 square = bit_scan_clear(&my_rooks);
690 file = _FILE(square);
692 if (!(PAWNS(side) & file_bit[file])) {
693 /* there are no our pawns on the rook's file */
694 if (PAWNS(xside) & file_bit[file]) {
695 /* ... but there are opponent's pawns */
696 if (file == (_FILE(xk) - 1) || file == (_FILE(xk) + 1))
697 /* opponent's king is on the adjacent file */
698 position_score[OPENING][side] += rook_on_semiopen_file_near_king_op;
699 else if (file == _FILE(xk))
700 /* opponent's king is on the same file */
701 position_score[OPENING][side] += rook_on_semiopen_file_before_king_op;
702 else {
703 /* rook on semiopen file */
704 position_score[OPENING][side] += rook_on_semiopen_file_op;
705 position_score[ENDGAME][side] += rook_on_semiopen_file_eg;
707 } else {
708 /* rook on open file */
709 position_score[OPENING][side] += rook_on_open_file_op;
710 position_score[ENDGAME][side] += rook_on_open_file_eg;
713 if (rank_flip[side][_RANK(square)] == 6) {
714 /* rook on 7th rank */
715 position_score[OPENING][side] += rook_on_seven_rank_op;
716 position_score[ENDGAME][side] += rook_on_seven_rank_eg;
719 attacks = ROOK_ATTACKS(square, complete);
720 /* calculate mobility */
721 mobility = popcount(attacks & mobility_xmask);
722 mobility_score[OPENING][side] += rook_mobility_op[mobility];
723 mobility_score[ENDGAME][side] += rook_mobility_eg[mobility];
725 /* king attacks */
726 attack_count = popcount(ROOK_ATTACKS(square, complete & ~attacks) &
727 (piece_moves[KING][xk] | BIT(xk)));
728 if (attack_count) {
729 king_attacks[side] += attack_count * 2;
730 king_attackers[side]++;
735 /* queen evaluation */
736 static void
737 evaluate_queens(int side)
739 int xk;
740 int square;
741 int attack_count;
742 uint64_t attacks;
743 uint64_t my_queens;
745 my_queens = QUEENS(side);
746 xk = brd.kings[1 ^ side];
748 while (my_queens) {
749 square = bit_scan_clear(&my_queens);
750 /* king attacks */
751 attacks = QUEEN_ATTACKS(square, complete);
752 attack_count = popcount(QUEEN_ATTACKS(square, complete & ~attacks) &
753 (piece_moves[KING][xk] | BIT(xk)));
754 if (attack_count) {
755 king_attacks[side] += attack_count * 2;
756 king_attackers[side]++;
761 static int king_square_op[2][64] = {
763 40, 50, 30, 10, 10, 30, 50, 40,
764 30, 40, 20, 0, 0, 20, 40, 30,
765 10, 20, 0, -20, -20, 0, 20, 10,
766 0, 10, -10, -30, -30, -10, 10, 0,
767 -10, 0, -20, -40, -40, -20, 0, -10,
768 -20, -10, -30, -50, -50, -30, -10, -20,
769 -30, -20, -40, -60, -60, -40, -20, -30,
770 -40, -30, -50, -70, -70, -50, -30, -40
773 -40, -30, -50, -70, -70, -50, -30, -40,
774 -30, -20, -40, -60, -60, -40, -20, -30,
775 -20, -10, -30, -50, -50, -30, -10, -20,
776 -10, 0, -20, -40, -40, -20, 0, -10,
777 0, 10, -10, -30, -30, -10, 10, 0,
778 10, 20, 0, -20, -20, 0, 20, 10,
779 30, 40, 20, 0, 0, 20, 40, 30,
780 40, 50, 30, 10, 10, 30, 50, 40
784 static int king_square_eg[64] = {
785 -72, -48, -36, -24, -24, -36, -48, -72,
786 -48, -24, -12, 0, 0, -12, -24, -48,
787 -36, -12, 0, 12, 12, 0, -12, -36,
788 -24, 0, 12, 24, 24, 12, 0, -24,
789 -24, 0, 12, 24, 24, 12, 0, -24,
790 -36, -12, 0, 12, 12, 0, -12, -36,
791 -48, -24, -12, 0, 0, -12, -24, -48,
792 -72, -48, -36, -24, -24, -36, -48, -72
795 static int attack_penalty_op = -10;
796 static int attack_scale[16] = {
797 0, 8, 10, 12, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
800 static const int side_offset[2] = {-8, 8};
802 /* evaluate king */
803 static void
804 evaluate_king(int side)
806 int i;
807 int file;
808 int rank;
809 int square;
810 int xside;
811 uint64_t bb, xbb;
813 xside = 1 ^ side; /* opponent's side */
814 square = brd.kings[side];
816 file = _FILE(square);
817 rank = _RANK(square);
819 /* include adjacent pawns into mask */
820 if ((side == WHITE && rank != 0) || (side == BLACK && rank != 7))
821 i = square + side_offset[side];
822 else
823 i = square;
825 /* pawn shield and pawn attacks */
826 bb = passer_mask[side][i] & PAWNS(side);
827 xbb = passer_mask[side][i] & PAWNS(xside);
829 if (file != 0) {
830 /* in case if there is no our pawn */
831 king_score[OPENING][side] += -36;
833 if (bb & file_bit[file - 1]) {
834 /* find nearest pawn */
835 if (side == BLACK)
836 i = bit_scan_rev(bb & file_bit[file - 1]);
837 else
838 i = bit_scan(bb & file_bit[file - 1]);
839 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
840 (7 - rank_flip[side][_RANK(i)]);
843 /* pawn attack */
844 if (xbb & file_bit[file - 1]) {
845 if (side)
846 i = bit_scan_rev(xbb & file_bit[file - 1]);
847 else
848 i = bit_scan(xbb & file_bit[file - 1]);
849 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
853 /* in case if there is no our pawn in front of our king */
854 king_score[OPENING][side] += -36;
856 if (bb & file_bit[file]) {
857 if (side == BLACK)
858 i = bit_scan_rev(bb & file_bit[file]);
859 else
860 i = bit_scan(bb & file_bit[file]);
861 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
862 (7 - rank_flip[side][_RANK(i)]);
865 if (xbb & file_bit[file]) {
866 if (side)
867 i = bit_scan_rev(xbb & file_bit[file]);
868 else
869 i = bit_scan(xbb & file_bit[file]);
870 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
873 if (file != 7) {
874 /* in case if there is no our pawn */
875 king_score[OPENING][side] += -36;
876 if (bb & file_bit[file + 1]) {
877 /* find nearest pawn */
878 if (side)
879 i = bit_scan_rev(bb & file_bit[file + 1]);
880 else
881 i = bit_scan(bb & file_bit[file + 1]);
882 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
883 (7 - rank_flip[side][_RANK(i)]);
886 /* pawn attack */
887 if (xbb & file_bit[file + 1]) {
888 if (side)
889 i = bit_scan_rev(xbb & file_bit[file + 1]);
890 else
891 i = bit_scan(xbb & file_bit[file + 1]);
892 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
896 king_score[OPENING][xside] += (attack_penalty_op * king_attacks[side] *
897 attack_scale[king_attackers[side]]) / 16;
899 position_score[OPENING][side] += king_square_op[side][square];
900 position_score[ENDGAME][side] += king_square_eg[square];
903 static int blocked_rook = -50;
904 static int trapped_bishop = -100;
906 static void
907 evaluate_blocked_pieces(int side)
909 int xside = 1 ^ side;
910 int side_inc = side * (A8 - A1);
912 /* rook */
913 if (square64[F1 + side_inc] == KING || square64[G1 + side_inc] == KING) {
914 if (square64[G1 + side_inc] == ROOK || square64[H1 + side_inc] == ROOK)
915 position_score[OPENING][side] += blocked_rook;
916 } else if (square64[C1 + side_inc] == KING || square64[B1 + side_inc] == KING) {
917 if (square64[A1 + side_inc] == ROOK || square64[B1 + side_inc] == ROOK)
918 position_score[OPENING][side] += blocked_rook;
921 int b_sq_a7 = side == WHITE? A7 : A2;
922 int b_sq_h7 = side == WHITE? H7 : H2;
923 int p_sq_b6 = side == WHITE? B6 : B3;
924 int p_sq_g6 = side == WHITE? G6 : G3;
926 if ((BISHOPS(side) & BIT(b_sq_a7)) && (PAWNS(xside) & BIT(p_sq_b6)) && \
927 SEE(SET_FROM(b_sq_a7) | SET_TO(p_sq_b6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
928 position_score[OPENING][side] += trapped_bishop;
929 position_score[ENDGAME][side] += trapped_bishop;
931 if ((BISHOPS(side) & BIT(b_sq_h7)) && (PAWNS(xside) & BIT(p_sq_g6)) && \
932 SEE(SET_FROM(b_sq_h7) | SET_TO(p_sq_g6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
933 position_score[OPENING][side] += trapped_bishop;
934 position_score[ENDGAME][side] += trapped_bishop;
938 /* clear scores */
939 static void
940 zero_scores(void)
942 king_attacks[WHITE] = 0;
943 king_attacks[BLACK] = 0;
944 king_attackers[WHITE] = 0;
945 king_attackers[BLACK] = 0;
947 king_score[OPENING][WHITE] = 0;
948 king_score[OPENING][BLACK] = 0;
949 king_score[ENDGAME][WHITE] = 0;
950 king_score[ENDGAME][BLACK] = 0;
952 mobility_score[OPENING][WHITE] = 0;
953 mobility_score[OPENING][BLACK] = 0;
954 mobility_score[ENDGAME][WHITE] = 0;
955 mobility_score[ENDGAME][BLACK] = 0;
957 pawn_score[OPENING][WHITE] = 0;
958 pawn_score[OPENING][BLACK] = 0;
959 pawn_score[ENDGAME][WHITE] = 0;
960 pawn_score[ENDGAME][BLACK] = 0;
962 position_score[OPENING][WHITE] = 0;
963 position_score[OPENING][BLACK] = 0;
964 position_score[ENDGAME][WHITE] = 0;
965 position_score[ENDGAME][BLACK] = 0;
968 static int simple_mate_squares[2][64] = {
970 160, 140, 120, 100, 100, 120, 140, 160,
971 140, 120, 100, 80, 80, 100, 120, 140,
972 120, 100, 80, 60, 60, 80, 100, 120,
973 100, 80, 60, 40, 40, 60, 80, 100,
974 100, 80, 60, 40, 40, 60, 80, 100,
975 120, 100, 80, 60, 60, 80, 100, 120,
976 140, 120, 100, 80, 80, 100, 120, 140,
977 160, 140, 120, 100, 100, 120, 140, 160
980 160, 140, 120, 100, 100, 120, 140, 160,
981 140, 120, 100, 80, 80, 100, 120, 140,
982 120, 100, 80, 60, 60, 80, 100, 120,
983 100, 80, 60, 40, 40, 60, 80, 100,
984 100, 80, 60, 40, 40, 60, 80, 100,
985 120, 100, 80, 60, 60, 80, 100, 120,
986 140, 120, 100, 80, 80, 100, 120, 140,
987 160, 140, 120, 100, 100, 120, 140, 160
991 /* for KING vs KING, KNIGHT, BISHOP */
992 static int b_n_mate_dark_squares[64] = {
993 99, 90, 80, 70, 60, 50, 40, 30,
994 90, 80, 70, 60, 50, 40, 30, 40,
995 80, 70, 60, 50, 40, 30, 40, 50,
996 70, 60, 50, 40, 30, 40, 50, 60,
997 60, 50, 40, 30, 40, 50, 60, 70,
998 50, 40, 30, 40, 50, 60, 70, 80,
999 40, 30, 40, 50, 60, 70, 80, 90,
1000 30, 40, 50, 60, 70, 80, 90, 99
1003 static int b_n_mate_light_squares[64] = {
1004 30, 40, 50, 60, 70, 80, 90, 99,
1005 40, 30, 40, 50, 60, 70, 80, 90,
1006 50, 40, 30, 40, 50, 60, 70, 80,
1007 60, 50, 40, 30, 40, 50, 60, 70,
1008 70, 60, 50, 40, 30, 40, 50, 60,
1009 80, 70, 60, 50, 40, 30, 40, 50,
1010 90, 80, 70, 60, 50, 40, 30, 40,
1011 99, 90, 80, 70, 60, 50, 40, 30
1014 static int
1015 evaluate_mate(int side)
1017 int score = 0;
1018 int xside = 1 ^ side;
1020 if (material_complete[side]) {
1021 score = material_complete[side] + 200;
1023 if (piece_count[side][KNIGHT] == 1 && piece_count[side][BISHOP] == 1) {
1024 if (BISHOPS(side) & BLACKSQUARES)
1025 score += b_n_mate_dark_squares[brd.kings[xside]];
1026 else
1027 score += b_n_mate_light_squares[brd.kings[xside]];
1028 } else {
1029 score += simple_mate_squares[side][brd.kings[xside]];
1030 score -= distance[brd.kings[side]][brd.kings[xside]] * 10;
1033 return score;
1036 static int evaluate_draw_pattern()
1038 /* TODO: add real draw code */
1039 return FALSE;
1042 static int bishop_pair = 50;
1043 static int bishop_pair_correction = 15;
1045 /* based on Larry Kaufman's paper */
1046 static void
1047 evaluate_material_imbalances(int side)
1049 /* TODO: more imbalances */
1051 int pc;
1053 /* bishop pair */
1054 if (piece_count[side][BISHOP] > 1) {
1055 side_score[OPENING][side] += bishop_pair;
1056 side_score[ENDGAME][side] += bishop_pair;
1058 /* how many pawns on the board? */
1059 pc = wpc + bpc;
1061 if (pc > 12) {
1062 side_score[OPENING][side] -= bishop_pair_correction;
1063 side_score[ENDGAME][side] -= bishop_pair_correction;
1064 } else if (pc < 8) {
1065 side_score[OPENING][side] += bishop_pair_correction;
1066 side_score[ENDGAME][side] += bishop_pair_correction;