Fixed bug in 'rook behind passer' code
[owl.git] / evaluate.c
blobebc40c7412b2566454bc21d684827c333e41094e
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] = {25, 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[side];
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) | KING(side)) == side_boards[side]))) {
220 score = 0;
221 } else if (score < 0 && !material_pawns[xside] && \
222 ((material_pieces[xside] < piece_value[ROOK]) || \
223 ((KNIGHTS(xside) | KING(xside)) == side_boards[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, 50, 100, 0};
302 static int passer_score_eg[8] = {0, 0, 20, 35, 90, 150, 200, 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[9] = {0, 0, -35, -28, -23, -16, -12, -12, -12};
314 static int doubled_penalty_eg[9] = {0, 0, -45, -39, -33, -28, -23, -16, -12};
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 int next_square = side? square - 8 : square + 8;
362 if ((BIT(next_square) & side_boards[xside]) ||
363 (pawn_moves[side][next_square] & PAWNS(xside)))
364 score_eg -= passer_score_eg[rank_flip[side][_RANK(square)]] / 3;
366 SET(passers[side], square);
368 passed = TRUE;
370 } else if (!(forward_ray[side][square] & PAWNS(xside))) {
371 /* no opponent's pawns on the same file */
373 /* how many pawns defend our candidate */
374 side_defenders = popcount(pawn_moves[side][square] &
375 PAWNS(xside));
376 /* how many pawns attack our candidate */
377 xside_attackers = popcount(pawn_moves[side][square] & \
378 PAWNS(xside));
380 if (xside_attackers <= side_defenders) {
381 /* pawn is well protected */
383 /* how many pawns can support our candidate */
384 side_defenders = popcount((passer_mask[xside][square + \
385 (side == WHITE? 8 : -8)] & \
386 isolated_mask[_FILE(square)]) & PAWNS(side));
387 /* how many pawns can stop our candidate */
388 xside_attackers = popcount(passer_mask[side][square] & \
389 PAWNS(xside));
391 if (xside_attackers <= side_defenders) {
392 /* true passed pawn candidate */
393 score_op += can_passed_score_op[rank_flip[side][_RANK(square)]];
394 score_eg += can_passed_score_eg[rank_flip[side][_RANK(square)]];
399 if (isolated_mask[_FILE(square)] & PAWNS(side)) {
400 /* pawn is not isolated, but maybe backward? */
401 if (!((passer_mask[xside][square + (side == WHITE? 8 : -8)] & \
402 isolated_mask[_FILE(square)]) & PAWNS(side))) {
403 /* pawn is somewhat backward */
404 b = pawn_moves[side][square];
405 if (side == WHITE)
406 b <<= 8;
407 else
408 b >>= 8;
410 if (b & PAWNS(xside)) {
411 /* next square is attacked by opponents pawn */
412 score_op += backward_penalty_op;
413 score_eg += backward_penalty_eg;
415 /* backward on semiopen file */
416 if ((forward_ray[side][square] & PAWNS(xside)) == 0)
417 score_op += backward_penalty_op;
420 } else {
421 if (!passed) {
422 /* pawn is isolated */
423 if (!(forward_ray[side][square] & \
424 (PAWNS(side) | PAWNS(xside)))) {
425 /* isolated on semiopen file */
426 score_op += weak_isolated_penalty_op[_FILE(square)];
427 score_eg += weak_isolated_penalty_eg[_FILE(square)];
428 } else {
429 score_op += isolated_penalty_op[_FILE(square)];
430 score_eg += isolated_penalty_eg[_FILE(square)];
435 score_op += pawn_square_op[side][square];
436 score_eg += pawn_square_eg[side][square];
439 /* evaluate doubled pawns */
440 for (i = 0; i < 8; i++) {
441 count = popcount(file_bit[i] & PAWNS(side));
442 if (count > 1) {
443 score_op += doubled_penalty_op[piece_count[side][PAWN]] * (count - 1);
444 score_eg += doubled_penalty_eg[piece_count[side][PAWN]] * (count - 1);
448 /* store scores in hashtable */
449 if (e.pawn_hash_enabled) {
450 phe->key = brd.hash_pawn_key;
451 phe->score_op = score_op;
452 phe->score_eg = score_eg;
453 phe->passers = passers[side];
457 bb = passers[side];
458 while (bb) {
459 square = bit_scan_clear(&bb);
460 score_eg += 5 - distance[square][brd.kings[side]] * 5 +
461 distance[square][brd.kings[xside]] * 5;
464 pawn_score[OPENING][side] += score_op;
465 pawn_score[ENDGAME][side] += score_eg;
468 static int knight_square_op[2][64] = {
470 -35, -25, -20, -15, -15, -20, -25, -35,
471 -20, -15, -10, -5, -5, -10, -15, -20,
472 -10, -5, 0, 5, 5, 0, -5, -10,
473 -5, 0, 5, 10, 10, 5, 0, -5,
474 -5, 5, 10, 15, 15, 10, 5, -5,
475 -3, 5, 10, 10, 10, 10, 5, -3,
476 -10, -5, 0, 5, 5, 0, -5, -10,
477 -25, -15, -10, -10, -10, -10, -15, -25
480 -25, -15, -10, -10, -10, -10, -15, -25,
481 -10, -5, 0, 5, 5, 0, -5, -10,
482 -3, 5, 10, 10, 10, 10, 5, -3,
483 -5, 5, 10, 15, 15, 10, 5, -5,
484 -5, 0, 5, 10, 10, 5, 0, -5,
485 -10, -5, 0, 5, 5, 0, -5, -10,
486 -20, -15, -10, -5, -5, -10, -15, -20,
487 -35, -25, -20, -15, -15, -20, -25, -35
491 static int knight_square_eg[64] = {
492 -30, -20, -15, -10, -10, -15, -20, -30,
493 -20, -15, -10, -5, -5, -10, -15, -20,
494 -15, -10, 0, 5, 5, 0, -10, -15,
495 -10, -5, 5, 10, 10, 5, -5, -10,
496 -10, -5, 5, 10, 10, 5, -5, -10,
497 -15, -10, 0, 5, 5, 0, -10, -15,
498 -20, -15, -10, -5, -5, -10, -15, -20,
499 -30, -20, -15, -10, -10, -15, -20, -30
502 static int knight_outpost[2][64] = {
504 0, 0, 0, 0, 0, 0, 0, 0,
505 0, 0, 0, 0, 0, 0, 0, 0,
506 0, 0, 0, 0, 0, 0, 0, 0,
507 0, 5, 9, 15, 15, 9, 5, 0,
508 0, 5, 9, 18, 18, 9, 5, 0,
509 0, 0, 5, 9, 9, 5, 0, 0,
510 0, 0, 0, 0, 0, 0, 0, 0,
511 0, 0, 0, 0, 0, 0, 0, 0
514 0, 0, 0, 0, 0, 0, 0, 0,
515 0, 0, 0, 0, 0, 0, 0, 0,
516 0, 0, 5, 9, 9, 5, 0, 0,
517 0, 5, 9, 18, 18, 9, 5, 0,
518 0, 5, 9, 15, 15, 9, 5, 0,
519 0, 0, 0, 0, 0, 0, 0, 0,
520 0, 0, 0, 0, 0, 0, 0, 0,
521 0, 0, 0, 0, 0, 0, 0, 0
525 static int knight_mobility_op[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
526 static int knight_mobility_eg[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
527 static int knight_bonus[17] = {-12, -11, -11, -10, -10, -8, -8, -5, -5, 0, 0,
528 5, 5, 8, 8, 10, 10};
530 /* evaluate knights */
531 static void
532 evaluate_knights(int side)
534 int square;
535 int xside;
536 int xk;
537 int mobility;
538 int attack_count;
539 uint64_t my_knights;
540 uint64_t mobility_xmask;
542 xside = 1 ^ side;
543 xk = brd.kings[xside];
544 my_knights = KNIGHTS(side);
546 if (my_knights)
547 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
549 while (my_knights) {
550 square = bit_scan_clear(&my_knights);
552 /* piece square tables */
553 position_score[OPENING][side] += knight_square_op[side][square];
554 position_score[ENDGAME][side] += knight_square_eg[square];
556 if (knight_outpost[side][square])
557 /* is there enemy pawn that can potentially attack
558 our knight? */
559 if (!(PAWNS(xside) & (passer_mask[side][square] & \
560 isolated_mask[_FILE(square)])))
561 if (pawn_moves[xside][square] & PAWNS(side)) {
562 /* knight is supported by our pawn */
563 position_score[OPENING][side] += knight_outpost[side][square];
564 position_score[ENDGAME][side] += knight_outpost[side][square];
567 /* calculate mobility */
568 mobility = popcount(piece_moves[KNIGHT][square] & mobility_xmask);
569 mobility_score[OPENING][side] += knight_mobility_op[mobility];
570 mobility_score[ENDGAME][side] += knight_mobility_eg[mobility];
572 /* value of the knight depending of the pawns count */
573 position_score[OPENING][side] += knight_bonus[wpc + bpc];
574 position_score[ENDGAME][side] += knight_bonus[wpc + bpc];
576 /* king attacks */
577 attack_count = popcount((piece_moves[KING][xk] | BIT(xk)) &
578 piece_moves[KNIGHT][square]);
579 if (attack_count) {
580 king_attacks[side] += attack_count;
581 king_attackers[side]++;
586 static int bishop_square_op[2][64] = {
588 -10, -10, -10, -5, -5, -10, -10, -10,
589 -5, -5, -5, 0, 0, -5, -5, -5,
590 -3, -1, 2, 3, 3, 2, -1, -3,
591 -2, 0, 3, 5, 5, 3, 0, -2,
592 -2, 0, 3, 5, 5, 3, 0, -2,
593 -3, -1, 2, 5, 5, 2, -1, -2,
594 -5, -2, 0, 0, 0, 0, -2, -5,
595 -10, -10, -10, -10, -10, -10, -10, -10
598 -10, -10, -10, -10, -10, -10, -10, -10,
599 -5, -2, 0, 0, 0, 0, -2, -5,
600 -3, -1, 2, 5, 5, 2, -1, -2,
601 -2, 0, 3, 5, 5, 3, 0, -2,
602 -2, 0, 3, 5, 5, 3, 0, -2,
603 -3, -1, 2, 3, 3, 2, -1, -3,
604 -5, -5, -5, 0, 0, -5, -5, -5,
605 -10, -10, -10, -5, -5, -10, -10, -10
609 static int bishop_square_eg[64] = {
610 -10, -10, -10, -5, -5, -10, -10, -10,
611 -5, -5, -5, 0, 0, -5, -5, -5,
612 -3, -1, 2, 3, 3, 2, -1, -3,
613 -2, 0, 3, 5, 5, 3, 0, -2,
614 -2, 0, 3, 5, 5, 3, 0, -2,
615 -3, -1, 2, 5, 5, 2, -1, -2,
616 -5, -5, -5, 0, 0, -5, -5, -5,
617 -10, -10, -10, -5, -5, -10, -10, -10
620 static int bishop_mobility_op[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 49, 60, 60};
621 static int bishop_mobility_eg[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 59, 60, 60};
623 /* evaluate bishops */
624 static void
625 evaluate_bishops(int side)
627 int square;
628 int mobility;
629 int xk;
630 int xside;
631 int attack_count;
632 uint64_t attacks;
633 uint64_t mobility_xmask;
634 uint64_t my_bishops;
636 xside = 1 ^ side;
637 xk = brd.kings[xside];
638 my_bishops = BISHOPS(side);
640 if (my_bishops)
641 /* exclude these squares from mobility */
642 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
644 while (my_bishops) {
645 square = bit_scan_clear(&my_bishops);
647 attacks = BISHOP_ATTACKS(square, complete);
649 /* calculate mobility */
650 mobility = popcount(attacks & mobility_xmask);
651 mobility_score[OPENING][side] += bishop_mobility_op[mobility];
652 mobility_score[ENDGAME][side] += bishop_mobility_eg[mobility];
654 position_score[OPENING][side] += bishop_square_op[side][square];
655 position_score[ENDGAME][side] += bishop_square_eg[square];
657 /* king attacks */
658 attack_count = popcount(BISHOP_ATTACKS(square, complete & ~attacks) &
659 (piece_moves[KING][xk] | BIT(xk)));
660 if (attack_count) {
661 king_attacks[side] += attack_count;
662 king_attackers[side]++;
667 static int rook_on_semiopen_file_op = 10;
668 static int rook_on_semiopen_file_eg = 10;
670 static int rook_on_semiopen_file_near_king_op = 15;
671 static int rook_on_semiopen_file_before_king_op = 20;
673 static int rook_on_open_file_op = 15;
674 static int rook_on_open_file_eg = 15;
676 static int rook_on_seven_rank_op = 20;
677 static int rook_on_seven_rank_eg = 20;
679 static int rook_mobility_op[] = {
680 -12, -8, -4, 0, 4, 8, 11, 14, 16, 18, 19, 20, 21, 22, 23, 24
682 static int rook_mobility_eg[] = {
683 -20, -12, -4, 4, 12, 20, 28, 36, 44, 50, 54, 56, 57, 58, 59, 60
686 static void
687 evaluate_rooks(int side)
689 int xk;
690 int file;
691 int square;
692 int xside;
693 int mobility;
694 int attack_count;
695 uint64_t my_rooks;
696 uint64_t attacks;
697 uint64_t mobility_xmask;
699 my_rooks = ROOKS(side);
700 xside = 1 ^ side; /* opponent's color */
701 xk = brd.kings[xside]; /* location of opponent's king */
703 if (my_rooks)
704 /* exclude these squares from mobility */
705 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
707 while (my_rooks) {
708 square = bit_scan_clear(&my_rooks);
709 file = _FILE(square);
711 if (!(PAWNS(side) & file_bit[file])) {
712 /* there are no our pawns on the rook's file */
713 if (PAWNS(xside) & file_bit[file]) {
714 /* ... but there are opponent's pawns */
715 if (file == (_FILE(xk) - 1) || file == (_FILE(xk) + 1))
716 /* opponent's king is on the adjacent file */
717 position_score[OPENING][side] += rook_on_semiopen_file_near_king_op;
718 else if (file == _FILE(xk))
719 /* opponent's king is on the same file */
720 position_score[OPENING][side] += rook_on_semiopen_file_before_king_op;
721 else {
722 /* rook on semiopen file */
723 position_score[OPENING][side] += rook_on_semiopen_file_op;
724 position_score[ENDGAME][side] += rook_on_semiopen_file_eg;
726 } else {
727 /* rook on open file */
728 position_score[OPENING][side] += rook_on_open_file_op;
729 position_score[ENDGAME][side] += rook_on_open_file_eg;
732 if (rank_flip[side][_RANK(square)] == 6) {
733 /* rook on 7th rank */
734 position_score[OPENING][side] += rook_on_seven_rank_op;
735 position_score[ENDGAME][side] += rook_on_seven_rank_eg;
738 attacks = ROOK_ATTACKS(square, complete);
739 /* calculate mobility */
740 mobility = popcount(attacks & mobility_xmask);
741 mobility_score[OPENING][side] += rook_mobility_op[mobility];
742 mobility_score[ENDGAME][side] += rook_mobility_eg[mobility];
744 /* king attacks */
745 attack_count = popcount(ROOK_ATTACKS(square, complete & ~attacks) &
746 (piece_moves[KING][xk] | BIT(xk)));
747 if (attack_count) {
748 king_attacks[side] += attack_count * 2;
749 king_attackers[side]++;
754 /* queen evaluation */
755 static void
756 evaluate_queens(int side)
758 int xk;
759 int square;
760 int attack_count;
761 uint64_t attacks;
762 uint64_t my_queens;
764 my_queens = QUEENS(side);
765 xk = brd.kings[1 ^ side];
767 while (my_queens) {
768 square = bit_scan_clear(&my_queens);
769 /* king attacks */
770 attacks = QUEEN_ATTACKS(square, complete);
771 attack_count = popcount(QUEEN_ATTACKS(square, complete & ~attacks) &
772 (piece_moves[KING][xk] | BIT(xk)));
773 if (attack_count) {
774 king_attacks[side] += attack_count * 4;
775 king_attackers[side]++;
780 static int king_square_op[2][64] = {
782 40, 50, 30, 10, 10, 30, 50, 40,
783 30, 40, 20, 0, 0, 20, 40, 30,
784 10, 20, 0, -20, -20, 0, 20, 10,
785 0, 10, -10, -30, -30, -10, 10, 0,
786 -10, 0, -20, -40, -40, -20, 0, -10,
787 -20, -10, -30, -50, -50, -30, -10, -20,
788 -30, -20, -40, -60, -60, -40, -20, -30,
789 -40, -30, -50, -70, -70, -50, -30, -40
792 -40, -30, -50, -70, -70, -50, -30, -40,
793 -30, -20, -40, -60, -60, -40, -20, -30,
794 -20, -10, -30, -50, -50, -30, -10, -20,
795 -10, 0, -20, -40, -40, -20, 0, -10,
796 0, 10, -10, -30, -30, -10, 10, 0,
797 10, 20, 0, -20, -20, 0, 20, 10,
798 30, 40, 20, 0, 0, 20, 40, 30,
799 40, 50, 30, 10, 10, 30, 50, 40
803 static int king_square_eg[64] = {
804 -72, -48, -36, -24, -24, -36, -48, -72,
805 -48, -24, -12, 0, 0, -12, -24, -48,
806 -36, -12, 0, 12, 12, 0, -12, -36,
807 -24, 0, 12, 24, 24, 12, 0, -24,
808 -24, 0, 12, 24, 24, 12, 0, -24,
809 -36, -12, 0, 12, 12, 0, -12, -36,
810 -48, -24, -12, 0, 0, -12, -24, -48,
811 -72, -48, -36, -24, -24, -36, -48, -72
814 static int attack_penalty_op = -15;
815 static int attack_scale[16] = {
816 0, 0, 8, 10, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
819 static const int side_offset[2] = {-8, 8};
821 /* evaluate king */
822 static void
823 evaluate_king(int side)
825 int i;
826 int file;
827 int rank;
828 int square;
829 int xside;
830 uint64_t bb, xbb;
832 xside = 1 ^ side; /* opponent's side */
833 square = brd.kings[side];
835 file = _FILE(square);
836 rank = _RANK(square);
838 /* include adjacent pawns into mask */
839 if ((side == WHITE && rank != 0) || (side == BLACK && rank != 7))
840 i = square + side_offset[side];
841 else
842 i = square;
844 /* pawn shield and pawn attacks */
845 bb = passer_mask[side][i] & PAWNS(side);
846 xbb = passer_mask[side][i] & PAWNS(xside);
848 if (file != 0) {
849 /* in case if there is no our pawn */
850 king_score[OPENING][side] += -36;
852 if (bb & file_bit[file - 1]) {
853 /* find nearest pawn */
854 if (side == BLACK)
855 i = bit_scan_rev(bb & file_bit[file - 1]);
856 else
857 i = bit_scan(bb & file_bit[file - 1]);
858 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
859 (7 - rank_flip[side][_RANK(i)]);
862 /* pawn attack */
863 if (xbb & file_bit[file - 1]) {
864 if (side)
865 i = bit_scan_rev(xbb & file_bit[file - 1]);
866 else
867 i = bit_scan(xbb & file_bit[file - 1]);
868 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
872 /* in case if there is no our pawn in front of our king */
873 king_score[OPENING][side] += -36;
875 if (bb & file_bit[file]) {
876 if (side == BLACK)
877 i = bit_scan_rev(bb & file_bit[file]);
878 else
879 i = bit_scan(bb & file_bit[file]);
880 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
881 (7 - rank_flip[side][_RANK(i)]);
884 if (xbb & file_bit[file]) {
885 if (side)
886 i = bit_scan_rev(xbb & file_bit[file]);
887 else
888 i = bit_scan(xbb & file_bit[file]);
889 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
892 if (file != 7) {
893 /* in case if there is no our pawn */
894 king_score[OPENING][side] += -36;
895 if (bb & file_bit[file + 1]) {
896 /* find nearest pawn */
897 if (side)
898 i = bit_scan_rev(bb & file_bit[file + 1]);
899 else
900 i = bit_scan(bb & file_bit[file + 1]);
901 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
902 (7 - rank_flip[side][_RANK(i)]);
905 /* pawn attack */
906 if (xbb & file_bit[file + 1]) {
907 if (side)
908 i = bit_scan_rev(xbb & file_bit[file + 1]);
909 else
910 i = bit_scan(xbb & file_bit[file + 1]);
911 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
915 king_score[OPENING][xside] += (attack_penalty_op * king_attacks[side] *
916 attack_scale[king_attackers[side]]) / 16;
918 position_score[OPENING][side] += king_square_op[side][square];
919 position_score[ENDGAME][side] += king_square_eg[square];
922 static int blocked_rook = -50;
923 static int trapped_bishop = -100;
925 static void
926 evaluate_blocked_pieces(int side)
928 int xside = 1 ^ side;
929 int side_inc = side * (A8 - A1);
931 /* rook */
932 if (square64[F1 + side_inc] == KING || square64[G1 + side_inc] == KING) {
933 if (square64[G1 + side_inc] == ROOK || square64[H1 + side_inc] == ROOK)
934 position_score[OPENING][side] += blocked_rook;
935 } else if (square64[C1 + side_inc] == KING || square64[B1 + side_inc] == KING) {
936 if (square64[A1 + side_inc] == ROOK || square64[B1 + side_inc] == ROOK)
937 position_score[OPENING][side] += blocked_rook;
940 int b_sq_a7 = side == WHITE? A7 : A2;
941 int b_sq_h7 = side == WHITE? H7 : H2;
942 int p_sq_b6 = side == WHITE? B6 : B3;
943 int p_sq_g6 = side == WHITE? G6 : G3;
945 if ((BISHOPS(side) & BIT(b_sq_a7)) && (PAWNS(xside) & BIT(p_sq_b6)) && \
946 SEE(SET_FROM(b_sq_a7) | SET_TO(p_sq_b6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
947 position_score[OPENING][side] += trapped_bishop;
948 position_score[ENDGAME][side] += trapped_bishop;
950 if ((BISHOPS(side) & BIT(b_sq_h7)) && (PAWNS(xside) & BIT(p_sq_g6)) && \
951 SEE(SET_FROM(b_sq_h7) | SET_TO(p_sq_g6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
952 position_score[OPENING][side] += trapped_bishop;
953 position_score[ENDGAME][side] += trapped_bishop;
957 /* clear scores */
958 static void
959 zero_scores(void)
961 king_attacks[WHITE] = 0;
962 king_attacks[BLACK] = 0;
963 king_attackers[WHITE] = 0;
964 king_attackers[BLACK] = 0;
966 king_score[OPENING][WHITE] = 0;
967 king_score[OPENING][BLACK] = 0;
968 king_score[ENDGAME][WHITE] = 0;
969 king_score[ENDGAME][BLACK] = 0;
971 mobility_score[OPENING][WHITE] = 0;
972 mobility_score[OPENING][BLACK] = 0;
973 mobility_score[ENDGAME][WHITE] = 0;
974 mobility_score[ENDGAME][BLACK] = 0;
976 pawn_score[OPENING][WHITE] = 0;
977 pawn_score[OPENING][BLACK] = 0;
978 pawn_score[ENDGAME][WHITE] = 0;
979 pawn_score[ENDGAME][BLACK] = 0;
981 position_score[OPENING][WHITE] = 0;
982 position_score[OPENING][BLACK] = 0;
983 position_score[ENDGAME][WHITE] = 0;
984 position_score[ENDGAME][BLACK] = 0;
987 static int simple_mate_squares[2][64] = {
989 160, 140, 120, 100, 100, 120, 140, 160,
990 140, 120, 100, 80, 80, 100, 120, 140,
991 120, 100, 80, 60, 60, 80, 100, 120,
992 100, 80, 60, 40, 40, 60, 80, 100,
993 100, 80, 60, 40, 40, 60, 80, 100,
994 120, 100, 80, 60, 60, 80, 100, 120,
995 140, 120, 100, 80, 80, 100, 120, 140,
996 160, 140, 120, 100, 100, 120, 140, 160
999 160, 140, 120, 100, 100, 120, 140, 160,
1000 140, 120, 100, 80, 80, 100, 120, 140,
1001 120, 100, 80, 60, 60, 80, 100, 120,
1002 100, 80, 60, 40, 40, 60, 80, 100,
1003 100, 80, 60, 40, 40, 60, 80, 100,
1004 120, 100, 80, 60, 60, 80, 100, 120,
1005 140, 120, 100, 80, 80, 100, 120, 140,
1006 160, 140, 120, 100, 100, 120, 140, 160
1010 /* for KING vs KING, KNIGHT, BISHOP */
1011 static int b_n_mate_dark_squares[64] = {
1012 99, 90, 80, 70, 60, 50, 40, 30,
1013 90, 80, 70, 60, 50, 40, 30, 40,
1014 80, 70, 60, 50, 40, 30, 40, 50,
1015 70, 60, 50, 40, 30, 40, 50, 60,
1016 60, 50, 40, 30, 40, 50, 60, 70,
1017 50, 40, 30, 40, 50, 60, 70, 80,
1018 40, 30, 40, 50, 60, 70, 80, 90,
1019 30, 40, 50, 60, 70, 80, 90, 99
1022 static int b_n_mate_light_squares[64] = {
1023 30, 40, 50, 60, 70, 80, 90, 99,
1024 40, 30, 40, 50, 60, 70, 80, 90,
1025 50, 40, 30, 40, 50, 60, 70, 80,
1026 60, 50, 40, 30, 40, 50, 60, 70,
1027 70, 60, 50, 40, 30, 40, 50, 60,
1028 80, 70, 60, 50, 40, 30, 40, 50,
1029 90, 80, 70, 60, 50, 40, 30, 40,
1030 99, 90, 80, 70, 60, 50, 40, 30
1033 static int
1034 evaluate_mate(int side)
1036 int score = 0;
1037 int xside = 1 ^ side;
1039 if (material_complete[side]) {
1040 score = material_complete[side] + 200;
1042 if (piece_count[side][KNIGHT] == 1 && piece_count[side][BISHOP] == 1) {
1043 if (BISHOPS(side) & BLACKSQUARES)
1044 score += b_n_mate_dark_squares[brd.kings[xside]];
1045 else
1046 score += b_n_mate_light_squares[brd.kings[xside]];
1047 } else {
1048 score += simple_mate_squares[side][brd.kings[xside]];
1049 score -= distance[brd.kings[side]][brd.kings[xside]] * 10;
1052 return score;
1055 static int evaluate_draw_pattern()
1057 /* TODO: add real draw code */
1058 return FALSE;
1061 static int bishop_pair = 50;
1062 static int bishop_pair_correction = 15;
1064 /* based on Larry Kaufman's paper */
1065 static void
1066 evaluate_material_imbalances(int side)
1068 /* TODO: more imbalances */
1070 int pc;
1072 /* bishop pair */
1073 if (piece_count[side][BISHOP] > 1) {
1074 side_score[OPENING][side] += bishop_pair;
1075 side_score[ENDGAME][side] += bishop_pair;
1077 /* how many pawns on the board? */
1078 pc = wpc + bpc;
1080 if (pc > 12) {
1081 side_score[OPENING][side] -= bishop_pair_correction;
1082 side_score[ENDGAME][side] -= bishop_pair_correction;
1083 } else if (pc < 8) {
1084 side_score[OPENING][side] += bishop_pair_correction;
1085 side_score[ENDGAME][side] += bishop_pair_correction;