Basic (experimental) lazy evaluation
[owl.git] / evaluate.c
blob2838088880d69c2529bbdef09690e005ecade748
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;
94 static int lazy_margin = 250;
96 static uint64_t pawn_attacks[2];
98 /* return TRUE if current position is DRAW */
99 int
100 evaluate_draw(void)
102 if (brd.fifty_rule >= 100)
103 return TRUE; /* draw by fifty rule */
105 if (material_pawns[WHITE] || material_pawns[BLACK])
106 return FALSE; /* there are some pawns on the board */
108 /* check for draw by insufficient material */
109 if (((material_complete[WHITE] < piece_value[ROOK]) || \
110 piece_count[WHITE][KNIGHT] == 2) && \
111 ((material_complete[BLACK] < piece_value[ROOK]) || \
112 piece_count[BLACK][KNIGHT] == 2))
113 return TRUE;
115 return FALSE;
118 /* evaluate current position */
119 int
120 evaluate(int alpha, int beta)
122 int score;
123 int mate_score;
124 int side;
125 int xside;
127 assert(alpha >= -MATE_VALUE && beta <= MATE_VALUE);
128 assert(beta > alpha);
130 /* we should find mate position */
131 if ((!material_pawns[WHITE] && !material_complete[BLACK]) || \
132 (!material_pawns[BLACK] && !material_complete[WHITE])) {
133 mate_score = evaluate_mate(WHITE) - evaluate_mate(BLACK);
134 if (mate_score)
135 return brd.wtm ? -mate_score : mate_score;
138 /* check for drawish endgame */
139 if (evaluate_draw_pattern())
140 return 0;
142 #ifdef STATISTIC_COUNTERS
143 counters.evaluations++;
144 #endif
145 zero_scores();
147 side_score[OPENING][WHITE] = material_complete[WHITE];
148 side_score[OPENING][BLACK] = material_complete[BLACK];
149 side_score[ENDGAME][WHITE] = material_complete[WHITE];
150 side_score[ENDGAME][BLACK] = material_complete[BLACK];
152 /* wtm bonus */
153 side_score[OPENING][brd.wtm] += wtm_bonus[OPENING];
154 side_score[ENDGAME][brd.wtm] += wtm_bonus[ENDGAME];
156 pawn_attacks[WHITE] = ((PAWNS(WHITE) & ~file_bit[7]) << 9) | \
157 ((PAWNS(WHITE) & ~file_bit[0]) << 7);
158 pawn_attacks[BLACK] = ((PAWNS(BLACK) & ~file_bit[0]) >> 9) | \
159 ((PAWNS(BLACK) & ~file_bit[7]) >> 7);
161 score = (OPENING_SCORE * (256 - GAME_PHASE) + \
162 ENDGAME_SCORE * GAME_PHASE) / 256;
164 int lazy_eval = FALSE;
165 if (alpha == beta - 1 && ((score - lazy_margin >= beta) || (score + lazy_margin <= alpha))) {
166 lazy_eval = TRUE;
167 counters.lazy_evaluations++;
170 for (side = WHITE; side <= BLACK; side++) {
171 evaluate_pawns(side);
172 evaluate_material_imbalances(side);
173 evaluate_blocked_pieces(side);
174 if (!lazy_eval) {
175 evaluate_knights(side);
176 evaluate_bishops(side);
177 evaluate_rooks(side);
178 evaluate_queens(side);
179 evaluate_king(side);
183 /* look for rook behind passer */
184 for (side = WHITE; side <= BLACK; side++) {
185 int square;
186 uint64_t pp;
187 uint64_t bb = ROOKS(side);
189 while (bb) {
190 square = bit_scan_clear(&bb);
191 pp = file_bit[_FILE(square)] & passers[side];
192 if (pp) {
193 if (side == WHITE) {
194 if (_RANK(bit_scan(pp)) > _RANK(square))
195 position_score[ENDGAME][side] += rook_behind_pp;
196 } else {
197 if (_RANK(bit_scan(pp)) < _RANK(square))
198 position_score[ENDGAME][side] += rook_behind_pp;
204 /* bonus for having more pawns if there are now pieces on the board */
205 if (!material_pieces[WHITE] && !material_pieces[BLACK])
206 side_score[ENDGAME][WHITE] += (wpc - bpc) * more_pawns_bonus;
208 append_scores();
210 /* bishop of opposite colours */
211 if (wqc + wrc + wnc + bqc + brc + bnc == 0 && wbc == 1 && \
212 bbc == 1 && abs(wpc - bpc) <= 2) {
213 if (popcount((BISHOPS(WHITE) | BISHOPS(BLACK)) & WHITESQUARES) == 1) {
214 side_score[ENDGAME][WHITE] /= 2;
215 side_score[ENDGAME][BLACK] /= 2;
219 /* get final score according to game phase */
220 score = (OPENING_SCORE * (256 - GAME_PHASE) + \
221 ENDGAME_SCORE * GAME_PHASE) / 256;
222 assert(score >= -MATE_VALUE && score <= MATE_VALUE);
224 side = brd.wtm;
225 xside = 1 ^ side;
227 /* can't win if we have two knights or a bishop and no pawns
228 (but theoretically we can, for example so called 'cooperative mate') */
229 if (score > 0 && !material_pawns[side] && \
230 ((material_pieces[side] < piece_value[ROOK]) || \
231 ((KNIGHTS(side) | KING(side)) == side_boards[side]))) {
232 score = 0;
233 } else if (score < 0 && !material_pawns[xside] && \
234 ((material_pieces[xside] < piece_value[ROOK]) || \
235 ((KNIGHTS(xside) | KING(xside)) == side_boards[xside]))) {
236 score = 0;
239 if (wqc == bqc && wrc == brc && abs(wbc + wnc - bbc - bnc) < 2) {
240 if (!wpc && !bpc) {
241 /* no pawns and one side is ahead by minor piece */
242 score /= 2;
243 } else {
244 if (score > 0) {
245 if (side == WHITE && (wbc + wnc - bbc - bnc == 1) && !wpc && bpc) {
246 score /= bpc + 1;
247 } else if (side == BLACK && (bbc + bnc - wbc - wnc == 1) && !bpc && wpc) {
248 score /= wpc + 1;
254 /* ROOK vs [KNIGHT|BISHOP] + (PAWN)? */
255 if ((material_pieces[WHITE] == piece_value[ROOK] && !wpc) && \
256 ((material_pieces[BLACK] == piece_value[KNIGHT] && bpc <= 1) || \
257 (material_pieces[BLACK] == piece_value[BISHOP] && bpc <= 1)))
258 score /= 8;
259 else if ((material_pieces[BLACK] == piece_value[ROOK] && !bpc) && \
260 ((material_pieces[WHITE] == piece_value[KNIGHT] && wpc <= 1) || \
261 (material_pieces[WHITE] == piece_value[BISHOP] && wpc <= 1)))
262 score /= 8;
264 return score;
267 static int pawn_square_op[2][64] = {
269 -15, -5, 0, 5, 5, 0, -5, -15,
270 -15, -5, 0, 5, 5, 0, -5, -15,
271 -15, -5, 0, 15, 15, 0, -5, -15,
272 -15, -5, 0, 25, 25, 0, -5, -15,
273 -15, -5, 0, 15, 15, 0, -5, -15,
274 -15, -5, 0, 5, 5, 0, -5, -15,
275 -15, -5, 0, 5, 5, 0, -5, -15,
276 -15, -5, 0, 5, 5, 0, -5, -15
279 -15, -5, 0, 5, 5, 0, -5, -15,
280 -15, -5, 0, 5, 5, 0, -5, -15,
281 -15, -5, 0, 5, 5, 0, -5, -15,
282 -15, -5, 0, 15, 15, 0, -5, -15,
283 -15, -5, 0, 25, 25, 0, -5, -15,
284 -15, -5, 0, 15, 15, 0, -5, -15,
285 -15, -5, 0, 5, 5, 0, -5, -15,
286 -15, -5, 0, 5, 5, 0, -5, -15
290 static int pawn_square_eg[2][64] = {
292 0, 0, 0, 0, 0, 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, 5, 5, 0, 0, 0,
296 0, 5, 5, 10, 10, 5, 5, 0,
297 0, 5, 5, 10, 10, 5, 5, 0,
298 5, 15, 15, 15, 15, 15, 15, 5,
299 0, 0, 0, 0, 0, 0, 0, 0
302 0, 0, 0, 0, 0, 0, 0, 0,
303 5, 15, 15, 15, 15, 15, 15, 5,
304 0, 5, 5, 10, 10, 5, 5, 0,
305 0, 5, 5, 10, 10, 5, 5, 0,
306 0, 0, 0, 5, 5, 0, 0, 0,
307 -1, 0, 0, 0, 0, 0, 0, -1,
308 -1, -0, -0, -0, -0, -0, -0, -1,
309 0, 0, 0, 0, 0, 0, 0, 0
312 /* bonus for passed pawns */
313 static int passer_score_op[8] = {0, 0, 10, 15, 30, 50, 100, 0};
314 static int passer_score_eg[8] = {0, 0, 20, 35, 90, 150, 200, 0};
315 /* bonus for candidate passers */
316 static int can_passed_score_op[8] = {0, 0, 5, 10, 20, 35, 50, 0};
317 static int can_passed_score_eg[8] = {0, 0, 10, 20, 40, 70, 100, 0};
318 /* penalty for isolated pawns */
319 static int isolated_penalty_op[8] = {-6, -8, -10, -12, -12, -10, -8, -6};
320 static int isolated_penalty_eg[8] = {-7, -10, -14, -20, -20, -14, -10, -7};
321 /* penalty for isolated pawns on open files */
322 static int weak_isolated_penalty_op[8] = {-9, -10, -12, -18, -18, -12, -10, -9};
323 static int weak_isolated_penalty_eg[8] = {-10, -12, -14, -20, -20, -14, -12, -10};
324 /* penalty for doubled pawns */
325 static int doubled_penalty_op[9] = {0, 0, -35, -28, -23, -16, -12, -12, -12};
326 static int doubled_penalty_eg[9] = {0, 0, -45, -39, -33, -28, -23, -16, -12};
327 /* penalty for backward pawns */
328 static int backward_penalty_op = -8;
329 static int backward_penalty_eg = -10;
331 static void
332 evaluate_pawns(int side)
334 uint64_t b, bb;
335 int i;
336 int count;
337 int square;
338 int score_op, score_eg;
339 int xside;
341 int passed;
342 int side_defenders, xside_attackers;
343 struct pawn_hash_entry_t *phe;
345 score_op = 0;
346 score_eg = 0;
347 xside = 1 ^ side;
348 passers[side] = 0ULL;
349 bb = PAWNS(side);
351 phe = pawn_hash[side] + (brd.hash_pawn_key & pawn_hash_mask);
353 if (e.pawn_hash_enabled && phe->key == brd.hash_pawn_key) {
354 score_op = phe->score_op;
355 score_eg = phe->score_eg;
356 passers[side] = phe->passers;
357 #ifdef STATISTIC_COUNTERS
358 counters.pawn_hash_evaluations++;
359 #endif
360 } else {
361 while (bb) {
362 passed = FALSE;
363 square = bit_scan_clear(&bb);
365 /* search passers */
366 if (!(forward_ray[side][square] & PAWNS(side))) {
367 /* this is most advanced pawn */
368 if (!(PAWNS(xside) & passer_mask[side][square])) {
369 /* no opponents pawns on adjacent files */
370 score_op += passer_score_op[rank_flip[side][_RANK(square)]];
371 score_eg += passer_score_eg[rank_flip[side][_RANK(square)]];
373 int next_square = side? square - 8 : square + 8;
374 if ((BIT(next_square) & side_boards[xside]) ||
375 (pawn_moves[side][next_square] & PAWNS(xside)))
376 score_eg -= passer_score_eg[rank_flip[side][_RANK(square)]] / 3;
378 SET(passers[side], square);
380 passed = TRUE;
382 } else if (!(forward_ray[side][square] & PAWNS(xside))) {
383 /* no opponent's pawns on the same file */
385 /* how many pawns defend our candidate */
386 side_defenders = popcount(pawn_moves[side][square] &
387 PAWNS(xside));
388 /* how many pawns attack our candidate */
389 xside_attackers = popcount(pawn_moves[side][square] & \
390 PAWNS(xside));
392 if (xside_attackers <= side_defenders) {
393 /* pawn is well protected */
395 /* how many pawns can support our candidate */
396 side_defenders = popcount((passer_mask[xside][square + \
397 (side == WHITE? 8 : -8)] & \
398 isolated_mask[_FILE(square)]) & PAWNS(side));
399 /* how many pawns can stop our candidate */
400 xside_attackers = popcount(passer_mask[side][square] & \
401 PAWNS(xside));
403 if (xside_attackers <= side_defenders) {
404 /* true passed pawn candidate */
405 score_op += can_passed_score_op[rank_flip[side][_RANK(square)]];
406 score_eg += can_passed_score_eg[rank_flip[side][_RANK(square)]];
411 if (isolated_mask[_FILE(square)] & PAWNS(side)) {
412 /* pawn is not isolated, but maybe backward? */
413 if (!((passer_mask[xside][square + (side == WHITE? 8 : -8)] & \
414 isolated_mask[_FILE(square)]) & PAWNS(side))) {
415 /* pawn is somewhat backward */
416 b = pawn_moves[side][square];
417 if (side == WHITE)
418 b <<= 8;
419 else
420 b >>= 8;
422 if (b & PAWNS(xside)) {
423 /* next square is attacked by opponents pawn */
424 score_op += backward_penalty_op;
425 score_eg += backward_penalty_eg;
427 /* backward on semiopen file */
428 if ((forward_ray[side][square] & PAWNS(xside)) == 0)
429 score_op += backward_penalty_op;
432 } else {
433 if (!passed) {
434 /* pawn is isolated */
435 if (!(forward_ray[side][square] & \
436 (PAWNS(side) | PAWNS(xside)))) {
437 /* isolated on semiopen file */
438 score_op += weak_isolated_penalty_op[_FILE(square)];
439 score_eg += weak_isolated_penalty_eg[_FILE(square)];
440 } else {
441 score_op += isolated_penalty_op[_FILE(square)];
442 score_eg += isolated_penalty_eg[_FILE(square)];
447 score_op += pawn_square_op[side][square];
448 score_eg += pawn_square_eg[side][square];
451 /* evaluate doubled pawns */
452 for (i = 0; i < 8; i++) {
453 count = popcount(file_bit[i] & PAWNS(side));
454 if (count > 1) {
455 score_op += doubled_penalty_op[piece_count[side][PAWN]] * (count - 1);
456 score_eg += doubled_penalty_eg[piece_count[side][PAWN]] * (count - 1);
460 /* store scores in hashtable */
461 if (e.pawn_hash_enabled) {
462 phe->key = brd.hash_pawn_key;
463 phe->score_op = score_op;
464 phe->score_eg = score_eg;
465 phe->passers = passers[side];
469 bb = passers[side];
470 while (bb) {
471 square = bit_scan_clear(&bb);
472 score_eg += 5 - distance[square][brd.kings[side]] * 5 +
473 distance[square][brd.kings[xside]] * 5;
476 pawn_score[OPENING][side] += score_op;
477 pawn_score[ENDGAME][side] += score_eg;
480 static int knight_square_op[2][64] = {
482 -35, -25, -20, -15, -15, -20, -25, -35,
483 -20, -15, -10, -5, -5, -10, -15, -20,
484 -10, -5, 0, 5, 5, 0, -5, -10,
485 -5, 0, 5, 10, 10, 5, 0, -5,
486 -5, 5, 10, 15, 15, 10, 5, -5,
487 -3, 5, 10, 10, 10, 10, 5, -3,
488 -10, -5, 0, 5, 5, 0, -5, -10,
489 -25, -15, -10, -10, -10, -10, -15, -25
492 -25, -15, -10, -10, -10, -10, -15, -25,
493 -10, -5, 0, 5, 5, 0, -5, -10,
494 -3, 5, 10, 10, 10, 10, 5, -3,
495 -5, 5, 10, 15, 15, 10, 5, -5,
496 -5, 0, 5, 10, 10, 5, 0, -5,
497 -10, -5, 0, 5, 5, 0, -5, -10,
498 -20, -15, -10, -5, -5, -10, -15, -20,
499 -35, -25, -20, -15, -15, -20, -25, -35
503 static int knight_square_eg[64] = {
504 -30, -20, -15, -10, -10, -15, -20, -30,
505 -20, -15, -10, -5, -5, -10, -15, -20,
506 -15, -10, 0, 5, 5, 0, -10, -15,
507 -10, -5, 5, 10, 10, 5, -5, -10,
508 -10, -5, 5, 10, 10, 5, -5, -10,
509 -15, -10, 0, 5, 5, 0, -10, -15,
510 -20, -15, -10, -5, -5, -10, -15, -20,
511 -30, -20, -15, -10, -10, -15, -20, -30
514 static int knight_outpost[2][64] = {
516 0, 0, 0, 0, 0, 0, 0, 0,
517 0, 0, 0, 0, 0, 0, 0, 0,
518 0, 0, 0, 0, 0, 0, 0, 0,
519 0, 5, 9, 15, 15, 9, 5, 0,
520 0, 5, 9, 18, 18, 9, 5, 0,
521 0, 0, 5, 9, 9, 5, 0, 0,
522 0, 0, 0, 0, 0, 0, 0, 0,
523 0, 0, 0, 0, 0, 0, 0, 0
526 0, 0, 0, 0, 0, 0, 0, 0,
527 0, 0, 0, 0, 0, 0, 0, 0,
528 0, 0, 5, 9, 9, 5, 0, 0,
529 0, 5, 9, 18, 18, 9, 5, 0,
530 0, 5, 9, 15, 15, 9, 5, 0,
531 0, 0, 0, 0, 0, 0, 0, 0,
532 0, 0, 0, 0, 0, 0, 0, 0,
533 0, 0, 0, 0, 0, 0, 0, 0
537 static int knight_mobility_op[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
538 static int knight_mobility_eg[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
539 static int knight_bonus[17] = {-12, -11, -11, -10, -10, -8, -8, -5, -5, 0, 0,
540 5, 5, 8, 8, 10, 10};
542 /* evaluate knights */
543 static void
544 evaluate_knights(int side)
546 int square;
547 int xside;
548 int xk;
549 int mobility;
550 int attack_count;
551 uint64_t my_knights;
552 uint64_t mobility_xmask;
554 xside = 1 ^ side;
555 xk = brd.kings[xside];
556 my_knights = KNIGHTS(side);
558 if (my_knights)
559 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
561 while (my_knights) {
562 square = bit_scan_clear(&my_knights);
564 /* piece square tables */
565 position_score[OPENING][side] += knight_square_op[side][square];
566 position_score[ENDGAME][side] += knight_square_eg[square];
568 if (knight_outpost[side][square])
569 /* is there enemy pawn that can potentially attack
570 our knight? */
571 if (!(PAWNS(xside) & (passer_mask[side][square] & \
572 isolated_mask[_FILE(square)])))
573 if (pawn_moves[xside][square] & PAWNS(side)) {
574 /* knight is supported by our pawn */
575 position_score[OPENING][side] += knight_outpost[side][square];
576 position_score[ENDGAME][side] += knight_outpost[side][square];
579 /* calculate mobility */
580 mobility = popcount(piece_moves[KNIGHT][square] & mobility_xmask);
581 mobility_score[OPENING][side] += knight_mobility_op[mobility];
582 mobility_score[ENDGAME][side] += knight_mobility_eg[mobility];
584 /* value of the knight depending of the pawns count */
585 position_score[OPENING][side] += knight_bonus[wpc + bpc];
586 position_score[ENDGAME][side] += knight_bonus[wpc + bpc];
588 /* king attacks */
589 attack_count = popcount((piece_moves[KING][xk] | BIT(xk)) &
590 piece_moves[KNIGHT][square]);
591 if (attack_count) {
592 king_attacks[side] += attack_count;
593 king_attackers[side]++;
598 static int bishop_square_op[2][64] = {
600 -10, -10, -10, -5, -5, -10, -10, -10,
601 -5, -5, -5, 0, 0, -5, -5, -5,
602 -3, -1, 2, 3, 3, 2, -1, -3,
603 -2, 0, 3, 5, 5, 3, 0, -2,
604 -2, 0, 3, 5, 5, 3, 0, -2,
605 -3, -1, 2, 5, 5, 2, -1, -2,
606 -5, -2, 0, 0, 0, 0, -2, -5,
607 -10, -10, -10, -10, -10, -10, -10, -10
610 -10, -10, -10, -10, -10, -10, -10, -10,
611 -5, -2, 0, 0, 0, 0, -2, -5,
612 -3, -1, 2, 5, 5, 2, -1, -2,
613 -2, 0, 3, 5, 5, 3, 0, -2,
614 -2, 0, 3, 5, 5, 3, 0, -2,
615 -3, -1, 2, 3, 3, 2, -1, -3,
616 -5, -5, -5, 0, 0, -5, -5, -5,
617 -10, -10, -10, -5, -5, -10, -10, -10
621 static int bishop_square_eg[64] = {
622 -10, -10, -10, -5, -5, -10, -10, -10,
623 -5, -5, -5, 0, 0, -5, -5, -5,
624 -3, -1, 2, 3, 3, 2, -1, -3,
625 -2, 0, 3, 5, 5, 3, 0, -2,
626 -2, 0, 3, 5, 5, 3, 0, -2,
627 -3, -1, 2, 5, 5, 2, -1, -2,
628 -5, -5, -5, 0, 0, -5, -5, -5,
629 -10, -10, -10, -5, -5, -10, -10, -10
632 static int bishop_mobility_op[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 49, 60, 60};
633 static int bishop_mobility_eg[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 59, 60, 60};
635 /* evaluate bishops */
636 static void
637 evaluate_bishops(int side)
639 int square;
640 int mobility;
641 int xk;
642 int xside;
643 int attack_count;
644 uint64_t attacks;
645 uint64_t mobility_xmask;
646 uint64_t my_bishops;
648 xside = 1 ^ side;
649 xk = brd.kings[xside];
650 my_bishops = BISHOPS(side);
652 if (my_bishops)
653 /* exclude these squares from mobility */
654 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
656 while (my_bishops) {
657 square = bit_scan_clear(&my_bishops);
659 attacks = BISHOP_ATTACKS(square, complete);
661 /* calculate mobility */
662 mobility = popcount(attacks & mobility_xmask);
663 mobility_score[OPENING][side] += bishop_mobility_op[mobility];
664 mobility_score[ENDGAME][side] += bishop_mobility_eg[mobility];
666 position_score[OPENING][side] += bishop_square_op[side][square];
667 position_score[ENDGAME][side] += bishop_square_eg[square];
669 /* king attacks */
670 attack_count = popcount(BISHOP_ATTACKS(square, complete & ~attacks) &
671 (piece_moves[KING][xk] | BIT(xk)));
672 if (attack_count) {
673 king_attacks[side] += attack_count;
674 king_attackers[side]++;
679 static int rook_on_semiopen_file_op = 10;
680 static int rook_on_semiopen_file_eg = 10;
682 static int rook_on_semiopen_file_near_king_op = 15;
683 static int rook_on_semiopen_file_before_king_op = 20;
685 static int rook_on_open_file_op = 15;
686 static int rook_on_open_file_eg = 15;
688 static int rook_on_seven_rank_op = 20;
689 static int rook_on_seven_rank_eg = 20;
691 static int rook_mobility_op[] = {
692 -12, -8, -4, 0, 4, 8, 11, 14, 16, 18, 19, 20, 21, 22, 23, 24
694 static int rook_mobility_eg[] = {
695 -20, -12, -4, 4, 12, 20, 28, 36, 44, 50, 54, 56, 57, 58, 59, 60
698 static void
699 evaluate_rooks(int side)
701 int xk;
702 int file;
703 int square;
704 int xside;
705 int mobility;
706 int attack_count;
707 uint64_t my_rooks;
708 uint64_t attacks;
709 uint64_t mobility_xmask;
711 my_rooks = ROOKS(side);
712 xside = 1 ^ side; /* opponent's color */
713 xk = brd.kings[xside]; /* location of opponent's king */
715 if (my_rooks)
716 /* exclude these squares from mobility */
717 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
719 while (my_rooks) {
720 square = bit_scan_clear(&my_rooks);
721 file = _FILE(square);
723 if (!(PAWNS(side) & file_bit[file])) {
724 /* there are no our pawns on the rook's file */
725 if (PAWNS(xside) & file_bit[file]) {
726 /* ... but there are opponent's pawns */
727 if (file == (_FILE(xk) - 1) || file == (_FILE(xk) + 1))
728 /* opponent's king is on the adjacent file */
729 position_score[OPENING][side] += rook_on_semiopen_file_near_king_op;
730 else if (file == _FILE(xk))
731 /* opponent's king is on the same file */
732 position_score[OPENING][side] += rook_on_semiopen_file_before_king_op;
733 else {
734 /* rook on semiopen file */
735 position_score[OPENING][side] += rook_on_semiopen_file_op;
736 position_score[ENDGAME][side] += rook_on_semiopen_file_eg;
738 } else {
739 /* rook on open file */
740 position_score[OPENING][side] += rook_on_open_file_op;
741 position_score[ENDGAME][side] += rook_on_open_file_eg;
744 if (rank_flip[side][_RANK(square)] == 6) {
745 /* rook on 7th rank */
746 position_score[OPENING][side] += rook_on_seven_rank_op;
747 position_score[ENDGAME][side] += rook_on_seven_rank_eg;
750 attacks = ROOK_ATTACKS(square, complete);
751 /* calculate mobility */
752 mobility = popcount(attacks & mobility_xmask);
753 mobility_score[OPENING][side] += rook_mobility_op[mobility];
754 mobility_score[ENDGAME][side] += rook_mobility_eg[mobility];
756 /* king attacks */
757 attack_count = popcount(ROOK_ATTACKS(square, complete & ~attacks) &
758 (piece_moves[KING][xk] | BIT(xk)));
759 if (attack_count) {
760 king_attacks[side] += attack_count * 2;
761 king_attackers[side]++;
766 /* queen evaluation */
767 static void
768 evaluate_queens(int side)
770 int xk;
771 int square;
772 int attack_count;
773 uint64_t attacks;
774 uint64_t my_queens;
776 my_queens = QUEENS(side);
777 xk = brd.kings[1 ^ side];
779 while (my_queens) {
780 square = bit_scan_clear(&my_queens);
781 /* king attacks */
782 attacks = QUEEN_ATTACKS(square, complete);
783 attack_count = popcount(QUEEN_ATTACKS(square, complete & ~attacks) &
784 (piece_moves[KING][xk] | BIT(xk)));
785 if (attack_count) {
786 king_attacks[side] += attack_count * 4;
787 king_attackers[side]++;
792 static int king_square_op[2][64] = {
794 40, 50, 30, 10, 10, 30, 50, 40,
795 30, 40, 20, 0, 0, 20, 40, 30,
796 10, 20, 0, -20, -20, 0, 20, 10,
797 0, 10, -10, -30, -30, -10, 10, 0,
798 -10, 0, -20, -40, -40, -20, 0, -10,
799 -20, -10, -30, -50, -50, -30, -10, -20,
800 -30, -20, -40, -60, -60, -40, -20, -30,
801 -40, -30, -50, -70, -70, -50, -30, -40
804 -40, -30, -50, -70, -70, -50, -30, -40,
805 -30, -20, -40, -60, -60, -40, -20, -30,
806 -20, -10, -30, -50, -50, -30, -10, -20,
807 -10, 0, -20, -40, -40, -20, 0, -10,
808 0, 10, -10, -30, -30, -10, 10, 0,
809 10, 20, 0, -20, -20, 0, 20, 10,
810 30, 40, 20, 0, 0, 20, 40, 30,
811 40, 50, 30, 10, 10, 30, 50, 40
815 static int king_square_eg[64] = {
816 -72, -48, -36, -24, -24, -36, -48, -72,
817 -48, -24, -12, 0, 0, -12, -24, -48,
818 -36, -12, 0, 12, 12, 0, -12, -36,
819 -24, 0, 12, 24, 24, 12, 0, -24,
820 -24, 0, 12, 24, 24, 12, 0, -24,
821 -36, -12, 0, 12, 12, 0, -12, -36,
822 -48, -24, -12, 0, 0, -12, -24, -48,
823 -72, -48, -36, -24, -24, -36, -48, -72
826 static int attack_penalty_op = -15;
827 static int attack_scale[16] = {
828 0, 0, 8, 10, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
831 static const int side_offset[2] = {-8, 8};
833 /* evaluate king */
834 static void
835 evaluate_king(int side)
837 int i;
838 int file;
839 int rank;
840 int square;
841 int xside;
842 uint64_t bb, xbb;
844 xside = 1 ^ side; /* opponent's side */
845 square = brd.kings[side];
847 file = _FILE(square);
848 rank = _RANK(square);
850 /* include adjacent pawns into mask */
851 if ((side == WHITE && rank != 0) || (side == BLACK && rank != 7))
852 i = square + side_offset[side];
853 else
854 i = square;
856 /* pawn shield and pawn attacks */
857 bb = passer_mask[side][i] & PAWNS(side);
858 xbb = passer_mask[side][i] & PAWNS(xside);
860 if (file != 0) {
861 /* in case if there is no our pawn */
862 king_score[OPENING][side] += -36;
864 if (bb & file_bit[file - 1]) {
865 /* find nearest pawn */
866 if (side == BLACK)
867 i = bit_scan_rev(bb & file_bit[file - 1]);
868 else
869 i = bit_scan(bb & file_bit[file - 1]);
870 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
871 (7 - rank_flip[side][_RANK(i)]);
874 /* pawn attack */
875 if (xbb & file_bit[file - 1]) {
876 if (side)
877 i = bit_scan_rev(xbb & file_bit[file - 1]);
878 else
879 i = bit_scan(xbb & file_bit[file - 1]);
880 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
884 /* in case if there is no our pawn in front of our king */
885 king_score[OPENING][side] += -36;
887 if (bb & file_bit[file]) {
888 if (side == BLACK)
889 i = bit_scan_rev(bb & file_bit[file]);
890 else
891 i = bit_scan(bb & file_bit[file]);
892 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
893 (7 - rank_flip[side][_RANK(i)]);
896 if (xbb & file_bit[file]) {
897 if (side)
898 i = bit_scan_rev(xbb & file_bit[file]);
899 else
900 i = bit_scan(xbb & file_bit[file]);
901 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
904 if (file != 7) {
905 /* in case if there is no our pawn */
906 king_score[OPENING][side] += -36;
907 if (bb & file_bit[file + 1]) {
908 /* find nearest pawn */
909 if (side)
910 i = bit_scan_rev(bb & file_bit[file + 1]);
911 else
912 i = bit_scan(bb & file_bit[file + 1]);
913 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
914 (7 - rank_flip[side][_RANK(i)]);
917 /* pawn attack */
918 if (xbb & file_bit[file + 1]) {
919 if (side)
920 i = bit_scan_rev(xbb & file_bit[file + 1]);
921 else
922 i = bit_scan(xbb & file_bit[file + 1]);
923 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
927 king_score[OPENING][xside] += (attack_penalty_op * king_attacks[side] *
928 attack_scale[king_attackers[side]]) / 16;
930 position_score[OPENING][side] += king_square_op[side][square];
931 position_score[ENDGAME][side] += king_square_eg[square];
934 static int blocked_rook = -50;
935 static int trapped_bishop = -100;
937 static void
938 evaluate_blocked_pieces(int side)
940 int xside = 1 ^ side;
941 int side_inc = side * (A8 - A1);
943 /* rook */
944 if (square64[F1 + side_inc] == KING || square64[G1 + side_inc] == KING) {
945 if (square64[G1 + side_inc] == ROOK || square64[H1 + side_inc] == ROOK)
946 position_score[OPENING][side] += blocked_rook;
947 } else if (square64[C1 + side_inc] == KING || square64[B1 + side_inc] == KING) {
948 if (square64[A1 + side_inc] == ROOK || square64[B1 + side_inc] == ROOK)
949 position_score[OPENING][side] += blocked_rook;
952 int b_sq_a7 = side == WHITE? A7 : A2;
953 int b_sq_h7 = side == WHITE? H7 : H2;
954 int p_sq_b6 = side == WHITE? B6 : B3;
955 int p_sq_g6 = side == WHITE? G6 : G3;
957 if ((BISHOPS(side) & BIT(b_sq_a7)) && (PAWNS(xside) & BIT(p_sq_b6)) && \
958 SEE(SET_FROM(b_sq_a7) | SET_TO(p_sq_b6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
959 position_score[OPENING][side] += trapped_bishop;
960 position_score[ENDGAME][side] += trapped_bishop;
962 if ((BISHOPS(side) & BIT(b_sq_h7)) && (PAWNS(xside) & BIT(p_sq_g6)) && \
963 SEE(SET_FROM(b_sq_h7) | SET_TO(p_sq_g6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
964 position_score[OPENING][side] += trapped_bishop;
965 position_score[ENDGAME][side] += trapped_bishop;
969 /* clear scores */
970 static void
971 zero_scores(void)
973 king_attacks[WHITE] = 0;
974 king_attacks[BLACK] = 0;
975 king_attackers[WHITE] = 0;
976 king_attackers[BLACK] = 0;
978 king_score[OPENING][WHITE] = 0;
979 king_score[OPENING][BLACK] = 0;
980 king_score[ENDGAME][WHITE] = 0;
981 king_score[ENDGAME][BLACK] = 0;
983 mobility_score[OPENING][WHITE] = 0;
984 mobility_score[OPENING][BLACK] = 0;
985 mobility_score[ENDGAME][WHITE] = 0;
986 mobility_score[ENDGAME][BLACK] = 0;
988 pawn_score[OPENING][WHITE] = 0;
989 pawn_score[OPENING][BLACK] = 0;
990 pawn_score[ENDGAME][WHITE] = 0;
991 pawn_score[ENDGAME][BLACK] = 0;
993 position_score[OPENING][WHITE] = 0;
994 position_score[OPENING][BLACK] = 0;
995 position_score[ENDGAME][WHITE] = 0;
996 position_score[ENDGAME][BLACK] = 0;
999 static int simple_mate_squares[2][64] = {
1001 160, 140, 120, 100, 100, 120, 140, 160,
1002 140, 120, 100, 80, 80, 100, 120, 140,
1003 120, 100, 80, 60, 60, 80, 100, 120,
1004 100, 80, 60, 40, 40, 60, 80, 100,
1005 100, 80, 60, 40, 40, 60, 80, 100,
1006 120, 100, 80, 60, 60, 80, 100, 120,
1007 140, 120, 100, 80, 80, 100, 120, 140,
1008 160, 140, 120, 100, 100, 120, 140, 160
1011 160, 140, 120, 100, 100, 120, 140, 160,
1012 140, 120, 100, 80, 80, 100, 120, 140,
1013 120, 100, 80, 60, 60, 80, 100, 120,
1014 100, 80, 60, 40, 40, 60, 80, 100,
1015 100, 80, 60, 40, 40, 60, 80, 100,
1016 120, 100, 80, 60, 60, 80, 100, 120,
1017 140, 120, 100, 80, 80, 100, 120, 140,
1018 160, 140, 120, 100, 100, 120, 140, 160
1022 /* for KING vs KING, KNIGHT, BISHOP */
1023 static int b_n_mate_dark_squares[64] = {
1024 99, 90, 80, 70, 60, 50, 40, 30,
1025 90, 80, 70, 60, 50, 40, 30, 40,
1026 80, 70, 60, 50, 40, 30, 40, 50,
1027 70, 60, 50, 40, 30, 40, 50, 60,
1028 60, 50, 40, 30, 40, 50, 60, 70,
1029 50, 40, 30, 40, 50, 60, 70, 80,
1030 40, 30, 40, 50, 60, 70, 80, 90,
1031 30, 40, 50, 60, 70, 80, 90, 99
1034 static int b_n_mate_light_squares[64] = {
1035 30, 40, 50, 60, 70, 80, 90, 99,
1036 40, 30, 40, 50, 60, 70, 80, 90,
1037 50, 40, 30, 40, 50, 60, 70, 80,
1038 60, 50, 40, 30, 40, 50, 60, 70,
1039 70, 60, 50, 40, 30, 40, 50, 60,
1040 80, 70, 60, 50, 40, 30, 40, 50,
1041 90, 80, 70, 60, 50, 40, 30, 40,
1042 99, 90, 80, 70, 60, 50, 40, 30
1045 static int
1046 evaluate_mate(int side)
1048 int score = 0;
1049 int xside = 1 ^ side;
1051 if (material_complete[side]) {
1052 score = material_complete[side] + 200;
1054 if (piece_count[side][KNIGHT] == 1 && piece_count[side][BISHOP] == 1) {
1055 if (BISHOPS(side) & BLACKSQUARES)
1056 score += b_n_mate_dark_squares[brd.kings[xside]];
1057 else
1058 score += b_n_mate_light_squares[brd.kings[xside]];
1059 } else {
1060 score += simple_mate_squares[side][brd.kings[xside]];
1061 score -= distance[brd.kings[side]][brd.kings[xside]] * 10;
1064 return score;
1067 static int evaluate_draw_pattern()
1069 /* TODO: add real draw code */
1070 return FALSE;
1073 static int bishop_pair = 50;
1074 static int bishop_pair_correction = 15;
1076 /* based on Larry Kaufman's paper */
1077 static void
1078 evaluate_material_imbalances(int side)
1080 /* TODO: more imbalances */
1082 int pc;
1084 /* bishop pair */
1085 if (piece_count[side][BISHOP] > 1) {
1086 side_score[OPENING][side] += bishop_pair;
1087 side_score[ENDGAME][side] += bishop_pair;
1089 /* how many pawns on the board? */
1090 pc = wpc + bpc;
1092 if (pc > 12) {
1093 side_score[OPENING][side] -= bishop_pair_correction;
1094 side_score[ENDGAME][side] -= bishop_pair_correction;
1095 } else if (pc < 8) {
1096 side_score[OPENING][side] += bishop_pair_correction;
1097 side_score[ENDGAME][side] += bishop_pair_correction;