Modified king attacks
[owl.git] / evaluate.c
blob52e4e6532c5ad6c36aa0479285809efa6a981b7a
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 uint64_t my_knights;
551 uint64_t mobility_xmask;
553 xside = 1 ^ side;
554 xk = brd.kings[xside];
555 my_knights = KNIGHTS(side);
557 if (my_knights)
558 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
560 while (my_knights) {
561 square = bit_scan_clear(&my_knights);
563 /* piece square tables */
564 position_score[OPENING][side] += knight_square_op[side][square];
565 position_score[ENDGAME][side] += knight_square_eg[square];
567 if (knight_outpost[side][square])
568 /* is there enemy pawn that can potentially attack
569 our knight? */
570 if (!(PAWNS(xside) & (passer_mask[side][square] & \
571 isolated_mask[_FILE(square)])))
572 if (pawn_moves[xside][square] & PAWNS(side)) {
573 /* knight is supported by our pawn */
574 position_score[OPENING][side] += knight_outpost[side][square];
575 position_score[ENDGAME][side] += knight_outpost[side][square];
578 /* calculate mobility */
579 mobility = popcount(piece_moves[KNIGHT][square] & mobility_xmask);
580 mobility_score[OPENING][side] += knight_mobility_op[mobility];
581 mobility_score[ENDGAME][side] += knight_mobility_eg[mobility];
583 /* value of the knight depending of the pawns count */
584 position_score[OPENING][side] += knight_bonus[wpc + bpc];
585 position_score[ENDGAME][side] += knight_bonus[wpc + bpc];
587 /* king attacks */
588 if ((piece_moves[KING][xk] | BIT(xk)) &
589 piece_moves[KNIGHT][square]) {
590 king_attacks[side]++;
591 king_attackers[side]++;
596 static int bishop_square_op[2][64] = {
598 -10, -10, -10, -5, -5, -10, -10, -10,
599 -5, -5, -5, 0, 0, -5, -5, -5,
600 -3, -1, 2, 3, 3, 2, -1, -3,
601 -2, 0, 3, 5, 5, 3, 0, -2,
602 -2, 0, 3, 5, 5, 3, 0, -2,
603 -3, -1, 2, 5, 5, 2, -1, -2,
604 -5, -2, 0, 0, 0, 0, -2, -5,
605 -10, -10, -10, -10, -10, -10, -10, -10
608 -10, -10, -10, -10, -10, -10, -10, -10,
609 -5, -2, 0, 0, 0, 0, -2, -5,
610 -3, -1, 2, 5, 5, 2, -1, -2,
611 -2, 0, 3, 5, 5, 3, 0, -2,
612 -2, 0, 3, 5, 5, 3, 0, -2,
613 -3, -1, 2, 3, 3, 2, -1, -3,
614 -5, -5, -5, 0, 0, -5, -5, -5,
615 -10, -10, -10, -5, -5, -10, -10, -10
619 static int bishop_square_eg[64] = {
620 -10, -10, -10, -5, -5, -10, -10, -10,
621 -5, -5, -5, 0, 0, -5, -5, -5,
622 -3, -1, 2, 3, 3, 2, -1, -3,
623 -2, 0, 3, 5, 5, 3, 0, -2,
624 -2, 0, 3, 5, 5, 3, 0, -2,
625 -3, -1, 2, 5, 5, 2, -1, -2,
626 -5, -5, -5, 0, 0, -5, -5, -5,
627 -10, -10, -10, -5, -5, -10, -10, -10
630 static int bishop_mobility_op[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 59, 60, 60};
631 static int bishop_mobility_eg[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 59, 60, 60};
633 /* evaluate bishops */
634 static void
635 evaluate_bishops(int side)
637 int square;
638 int mobility;
639 int xk;
640 int xside;
641 uint64_t attacks;
642 uint64_t mobility_xmask;
643 uint64_t my_bishops;
645 xside = 1 ^ side;
646 xk = brd.kings[xside];
647 my_bishops = BISHOPS(side);
649 if (my_bishops)
650 /* exclude these squares from mobility */
651 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
653 while (my_bishops) {
654 square = bit_scan_clear(&my_bishops);
656 attacks = BISHOP_ATTACKS(square, complete);
658 /* calculate mobility */
659 mobility = popcount(attacks & mobility_xmask);
660 mobility_score[OPENING][side] += bishop_mobility_op[mobility];
661 mobility_score[ENDGAME][side] += bishop_mobility_eg[mobility];
663 position_score[OPENING][side] += bishop_square_op[side][square];
664 position_score[ENDGAME][side] += bishop_square_eg[square];
666 /* king attacks */
667 if (attacks & (piece_moves[KING][xk] | BIT(xk))) {
668 king_attacks[side]++;
669 king_attackers[side]++;
674 static int rook_on_semiopen_file_op = 10;
675 static int rook_on_semiopen_file_eg = 10;
677 static int rook_on_semiopen_file_near_king_op = 15;
678 static int rook_on_semiopen_file_before_king_op = 20;
680 static int rook_on_open_file_op = 15;
681 static int rook_on_open_file_eg = 15;
683 static int rook_on_seven_rank_op = 20;
684 static int rook_on_seven_rank_eg = 20;
686 static int rook_mobility_op[] = {
687 -12, -8, -4, 0, 4, 8, 11, 14, 16, 18, 19, 20, 21, 22, 23, 24
689 static int rook_mobility_eg[] = {
690 -20, -12, -4, 4, 12, 20, 28, 36, 44, 50, 54, 56, 57, 58, 59, 60
693 static void
694 evaluate_rooks(int side)
696 int xk;
697 int file;
698 int square;
699 int xside;
700 int mobility;
701 uint64_t my_rooks;
702 uint64_t attacks;
703 uint64_t mobility_xmask;
705 my_rooks = ROOKS(side);
706 xside = 1 ^ side; /* opponent's color */
707 xk = brd.kings[xside]; /* location of opponent's king */
709 if (my_rooks)
710 /* exclude these squares from mobility */
711 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
713 while (my_rooks) {
714 square = bit_scan_clear(&my_rooks);
715 file = _FILE(square);
717 if (!(PAWNS(side) & file_bit[file])) {
718 /* there are no our pawns on the rook's file */
719 if (PAWNS(xside) & file_bit[file]) {
720 /* ... but there are opponent's pawns */
721 if (file == (_FILE(xk) - 1) || file == (_FILE(xk) + 1))
722 /* opponent's king is on the adjacent file */
723 position_score[OPENING][side] += rook_on_semiopen_file_near_king_op;
724 else if (file == _FILE(xk))
725 /* opponent's king is on the same file */
726 position_score[OPENING][side] += rook_on_semiopen_file_before_king_op;
727 else {
728 /* rook on semiopen file */
729 position_score[OPENING][side] += rook_on_semiopen_file_op;
730 position_score[ENDGAME][side] += rook_on_semiopen_file_eg;
732 } else {
733 /* rook on open file */
734 position_score[OPENING][side] += rook_on_open_file_op;
735 position_score[ENDGAME][side] += rook_on_open_file_eg;
738 if (rank_flip[side][_RANK(square)] == 6) {
739 /* rook on 7th rank */
740 position_score[OPENING][side] += rook_on_seven_rank_op;
741 position_score[ENDGAME][side] += rook_on_seven_rank_eg;
744 attacks = ROOK_ATTACKS(square, complete);
745 /* calculate mobility */
746 mobility = popcount(attacks & mobility_xmask);
747 mobility_score[OPENING][side] += rook_mobility_op[mobility];
748 mobility_score[ENDGAME][side] += rook_mobility_eg[mobility];
750 /* king attacks */
751 if (attacks & (piece_moves[KING][xk] | BIT(xk))) {
752 king_attacks[side] += 2;
753 king_attackers[side]++;
758 /* queen evaluation */
759 static void
760 evaluate_queens(int side)
762 int xk;
763 int square;
764 uint64_t attacks;
765 uint64_t my_queens;
767 my_queens = QUEENS(side);
768 xk = brd.kings[1 ^ side];
770 while (my_queens) {
771 square = bit_scan_clear(&my_queens);
772 /* king attacks */
773 attacks = QUEEN_ATTACKS(square, complete);
774 if (attacks & (piece_moves[KING][xk] | BIT(xk))) {
775 king_attacks[side] += 4;
776 king_attackers[side]++;
781 static int king_square_op[2][64] = {
783 40, 50, 30, 10, 10, 30, 50, 40,
784 30, 40, 20, 0, 0, 20, 40, 30,
785 10, 20, 0, -20, -20, 0, 20, 10,
786 0, 10, -10, -30, -30, -10, 10, 0,
787 -10, 0, -20, -40, -40, -20, 0, -10,
788 -20, -10, -30, -50, -50, -30, -10, -20,
789 -30, -20, -40, -60, -60, -40, -20, -30,
790 -40, -30, -50, -70, -70, -50, -30, -40
793 -40, -30, -50, -70, -70, -50, -30, -40,
794 -30, -20, -40, -60, -60, -40, -20, -30,
795 -20, -10, -30, -50, -50, -30, -10, -20,
796 -10, 0, -20, -40, -40, -20, 0, -10,
797 0, 10, -10, -30, -30, -10, 10, 0,
798 10, 20, 0, -20, -20, 0, 20, 10,
799 30, 40, 20, 0, 0, 20, 40, 30,
800 40, 50, 30, 10, 10, 30, 50, 40
804 static int king_square_eg[64] = {
805 -72, -48, -36, -24, -24, -36, -48, -72,
806 -48, -24, -12, 0, 0, -12, -24, -48,
807 -36, -12, 0, 12, 12, 0, -12, -36,
808 -24, 0, 12, 24, 24, 12, 0, -24,
809 -24, 0, 12, 24, 24, 12, 0, -24,
810 -36, -12, 0, 12, 12, 0, -12, -36,
811 -48, -24, -12, 0, 0, -12, -24, -48,
812 -72, -48, -36, -24, -24, -36, -48, -72
815 static int attack_penalty_op = -20;
816 static int attack_scale[16] = {
817 0, 0, 8, 10, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
820 static const int side_offset[2] = {-8, 8};
822 /* evaluate king */
823 static void
824 evaluate_king(int side)
826 int i;
827 int file;
828 int rank;
829 int square;
830 int xside;
831 uint64_t bb, xbb;
833 xside = 1 ^ side; /* opponent's side */
834 square = brd.kings[side];
836 file = _FILE(square);
837 rank = _RANK(square);
839 /* include adjacent pawns into mask */
840 if ((side == WHITE && rank != 0) || (side == BLACK && rank != 7))
841 i = square + side_offset[side];
842 else
843 i = square;
845 /* pawn shield and pawn attacks */
846 bb = passer_mask[side][i] & PAWNS(side);
847 xbb = passer_mask[side][i] & PAWNS(xside);
849 if (file != 0) {
850 /* in case if there is no our pawn */
851 king_score[OPENING][side] += -36;
853 if (bb & file_bit[file - 1]) {
854 /* find nearest pawn */
855 if (side == BLACK)
856 i = bit_scan_rev(bb & file_bit[file - 1]);
857 else
858 i = bit_scan(bb & file_bit[file - 1]);
859 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
860 (7 - rank_flip[side][_RANK(i)]);
863 /* pawn attack */
864 if (xbb & file_bit[file - 1]) {
865 if (side)
866 i = bit_scan_rev(xbb & file_bit[file - 1]);
867 else
868 i = bit_scan(xbb & file_bit[file - 1]);
869 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
873 /* in case if there is no our pawn in front of our king */
874 king_score[OPENING][side] += -36;
876 if (bb & file_bit[file]) {
877 if (side == BLACK)
878 i = bit_scan_rev(bb & file_bit[file]);
879 else
880 i = bit_scan(bb & file_bit[file]);
881 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
882 (7 - rank_flip[side][_RANK(i)]);
885 if (xbb & file_bit[file]) {
886 if (side)
887 i = bit_scan_rev(xbb & file_bit[file]);
888 else
889 i = bit_scan(xbb & file_bit[file]);
890 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
893 if (file != 7) {
894 /* in case if there is no our pawn */
895 king_score[OPENING][side] += -36;
896 if (bb & file_bit[file + 1]) {
897 /* find nearest pawn */
898 if (side)
899 i = bit_scan_rev(bb & file_bit[file + 1]);
900 else
901 i = bit_scan(bb & file_bit[file + 1]);
902 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
903 (7 - rank_flip[side][_RANK(i)]);
906 /* pawn attack */
907 if (xbb & file_bit[file + 1]) {
908 if (side)
909 i = bit_scan_rev(xbb & file_bit[file + 1]);
910 else
911 i = bit_scan(xbb & file_bit[file + 1]);
912 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
916 king_score[OPENING][xside] += (attack_penalty_op * king_attacks[side] *
917 attack_scale[king_attackers[side]]) / 16;
919 position_score[OPENING][side] += king_square_op[side][square];
920 position_score[ENDGAME][side] += king_square_eg[square];
923 static int blocked_rook = -50;
924 static int trapped_bishop = -100;
926 static void
927 evaluate_blocked_pieces(int side)
929 int xside = 1 ^ side;
930 int side_inc = side * (A8 - A1);
932 /* rook */
933 if (square64[F1 + side_inc] == KING || square64[G1 + side_inc] == KING) {
934 if (square64[G1 + side_inc] == ROOK || square64[H1 + side_inc] == ROOK)
935 position_score[OPENING][side] += blocked_rook;
936 } else if (square64[C1 + side_inc] == KING || square64[B1 + side_inc] == KING) {
937 if (square64[A1 + side_inc] == ROOK || square64[B1 + side_inc] == ROOK)
938 position_score[OPENING][side] += blocked_rook;
941 int b_sq_a7 = side == WHITE? A7 : A2;
942 int b_sq_h7 = side == WHITE? H7 : H2;
943 int p_sq_b6 = side == WHITE? B6 : B3;
944 int p_sq_g6 = side == WHITE? G6 : G3;
946 if ((BISHOPS(side) & BIT(b_sq_a7)) && (PAWNS(xside) & BIT(p_sq_b6)) && \
947 SEE(SET_FROM(b_sq_a7) | SET_TO(p_sq_b6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
948 position_score[OPENING][side] += trapped_bishop;
949 position_score[ENDGAME][side] += trapped_bishop;
951 if ((BISHOPS(side) & BIT(b_sq_h7)) && (PAWNS(xside) & BIT(p_sq_g6)) && \
952 SEE(SET_FROM(b_sq_h7) | SET_TO(p_sq_g6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
953 position_score[OPENING][side] += trapped_bishop;
954 position_score[ENDGAME][side] += trapped_bishop;
958 /* clear scores */
959 static void
960 zero_scores(void)
962 king_attacks[WHITE] = 0;
963 king_attacks[BLACK] = 0;
964 king_attackers[WHITE] = 0;
965 king_attackers[BLACK] = 0;
967 king_score[OPENING][WHITE] = 0;
968 king_score[OPENING][BLACK] = 0;
969 king_score[ENDGAME][WHITE] = 0;
970 king_score[ENDGAME][BLACK] = 0;
972 mobility_score[OPENING][WHITE] = 0;
973 mobility_score[OPENING][BLACK] = 0;
974 mobility_score[ENDGAME][WHITE] = 0;
975 mobility_score[ENDGAME][BLACK] = 0;
977 pawn_score[OPENING][WHITE] = 0;
978 pawn_score[OPENING][BLACK] = 0;
979 pawn_score[ENDGAME][WHITE] = 0;
980 pawn_score[ENDGAME][BLACK] = 0;
982 position_score[OPENING][WHITE] = 0;
983 position_score[OPENING][BLACK] = 0;
984 position_score[ENDGAME][WHITE] = 0;
985 position_score[ENDGAME][BLACK] = 0;
988 static int simple_mate_squares[2][64] = {
990 160, 140, 120, 100, 100, 120, 140, 160,
991 140, 120, 100, 80, 80, 100, 120, 140,
992 120, 100, 80, 60, 60, 80, 100, 120,
993 100, 80, 60, 40, 40, 60, 80, 100,
994 100, 80, 60, 40, 40, 60, 80, 100,
995 120, 100, 80, 60, 60, 80, 100, 120,
996 140, 120, 100, 80, 80, 100, 120, 140,
997 160, 140, 120, 100, 100, 120, 140, 160
1000 160, 140, 120, 100, 100, 120, 140, 160,
1001 140, 120, 100, 80, 80, 100, 120, 140,
1002 120, 100, 80, 60, 60, 80, 100, 120,
1003 100, 80, 60, 40, 40, 60, 80, 100,
1004 100, 80, 60, 40, 40, 60, 80, 100,
1005 120, 100, 80, 60, 60, 80, 100, 120,
1006 140, 120, 100, 80, 80, 100, 120, 140,
1007 160, 140, 120, 100, 100, 120, 140, 160
1011 /* for KING vs KING, KNIGHT, BISHOP */
1012 static int b_n_mate_dark_squares[64] = {
1013 99, 90, 80, 70, 60, 50, 40, 30,
1014 90, 80, 70, 60, 50, 40, 30, 40,
1015 80, 70, 60, 50, 40, 30, 40, 50,
1016 70, 60, 50, 40, 30, 40, 50, 60,
1017 60, 50, 40, 30, 40, 50, 60, 70,
1018 50, 40, 30, 40, 50, 60, 70, 80,
1019 40, 30, 40, 50, 60, 70, 80, 90,
1020 30, 40, 50, 60, 70, 80, 90, 99
1023 static int b_n_mate_light_squares[64] = {
1024 30, 40, 50, 60, 70, 80, 90, 99,
1025 40, 30, 40, 50, 60, 70, 80, 90,
1026 50, 40, 30, 40, 50, 60, 70, 80,
1027 60, 50, 40, 30, 40, 50, 60, 70,
1028 70, 60, 50, 40, 30, 40, 50, 60,
1029 80, 70, 60, 50, 40, 30, 40, 50,
1030 90, 80, 70, 60, 50, 40, 30, 40,
1031 99, 90, 80, 70, 60, 50, 40, 30
1034 static int
1035 evaluate_mate(int side)
1037 int score = 0;
1038 int xside = 1 ^ side;
1040 if (material_complete[side]) {
1041 score = material_complete[side] + 200;
1043 if (piece_count[side][KNIGHT] == 1 && piece_count[side][BISHOP] == 1) {
1044 if (BISHOPS(side) & BLACKSQUARES)
1045 score += b_n_mate_dark_squares[brd.kings[xside]];
1046 else
1047 score += b_n_mate_light_squares[brd.kings[xside]];
1048 } else {
1049 score += simple_mate_squares[side][brd.kings[xside]];
1050 score -= distance[brd.kings[side]][brd.kings[xside]] * 10;
1053 return score;
1056 static int evaluate_draw_pattern()
1058 /* TODO: add real draw code */
1059 return FALSE;
1062 static int bishop_pair = 50;
1063 static int bishop_pair_correction = 15;
1065 /* based on Larry Kaufman's paper */
1066 static void
1067 evaluate_material_imbalances(int side)
1069 /* TODO: more imbalances */
1071 int pc;
1073 /* bishop pair */
1074 if (piece_count[side][BISHOP] > 1) {
1075 side_score[OPENING][side] += bishop_pair;
1076 side_score[ENDGAME][side] += bishop_pair;
1078 /* how many pawns on the board? */
1079 pc = wpc + bpc;
1081 if (pc > 12) {
1082 side_score[OPENING][side] -= bishop_pair_correction;
1083 side_score[ENDGAME][side] -= bishop_pair_correction;
1084 } else if (pc < 8) {
1085 side_score[OPENING][side] += bishop_pair_correction;
1086 side_score[ENDGAME][side] += bishop_pair_correction;