Improve hashtable, add replacement strategies
[owl.git] / evaluate.c
blob75721e2cc913d756f2973144313dd8f2132771d0
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_score[2][2];
44 static int mobility_score[2][2];
45 static int pawn_score[2][2];
46 static int position_score[2][2];
47 static int side_score[2][2];
49 /* passed pawns bitboard */
50 static uint64_t passers[2];
52 /* bonus for side to move */
53 static int wtm_bonus[2] = {10, 10};
55 /* forward declarations of functions */
56 static void append_scores(void);
57 static void evaluate_pawns(int side);
58 static void evaluate_knights(int side);
59 static void evaluate_bishops(int side);
60 static void evaluate_rooks(int side);
61 static void evaluate_queens(int side);
62 static void evaluate_king(int side);
63 static int evaluate_draw_pattern(void);
64 static int evaluate_mate(int side);
65 static void evaluate_material_imbalances(int side);
66 static void evaluate_blocked_pieces(int side);
67 static void zero_scores(void);
69 static inline void
70 append_scores(void)
72 side_score[OPENING][WHITE] += king_score[OPENING][WHITE] + \
73 mobility_score[OPENING][WHITE] + pawn_score[OPENING][WHITE] + \
74 position_score[OPENING][WHITE];
75 side_score[OPENING][BLACK] += king_score[OPENING][BLACK] +
76 mobility_score[OPENING][BLACK] + pawn_score[OPENING][BLACK] + \
77 position_score[OPENING][BLACK];
78 side_score[ENDGAME][WHITE] += king_score[ENDGAME][WHITE] + \
79 mobility_score[ENDGAME][WHITE] + pawn_score[ENDGAME][WHITE] + \
80 position_score[ENDGAME][WHITE];
81 side_score[ENDGAME][BLACK] += king_score[ENDGAME][BLACK] + \
82 mobility_score[ENDGAME][BLACK] + pawn_score[ENDGAME][BLACK] + \
83 position_score[ENDGAME][BLACK];
86 /* bonus for rook behind passed pawn */
87 static int rook_behind_pp = 30;
89 /* bonus for having more pawns in endgame if there are no pieces
90 on the board */
91 static int more_pawns_bonus = 15;
93 static uint64_t pawn_attacks[2];
95 /* return TRUE if current position is DRAW */
96 int
97 evaluate_draw(void)
99 if (brd.fifty_rule >= 100)
100 return TRUE; /* draw by fifty rule */
102 if (material_pawns[WHITE] || material_pawns[BLACK])
103 return FALSE; /* there are some pawns on the board */
105 /* check for draw by insufficient material */
106 if (((material_complete[WHITE] < piece_value[ROOK]) || \
107 piece_count[WHITE][KNIGHT] == 2) && \
108 ((material_complete[BLACK] < piece_value[ROOK]) || \
109 piece_count[BLACK][KNIGHT] == 2))
110 return TRUE;
112 return FALSE;
115 /* evaluate current position */
116 int
117 evaluate(int alpha, int beta)
119 int score;
120 int mate_score;
121 int side;
122 int xside;
124 assert(alpha >= -MATE_VALUE && beta <= MATE_VALUE);
125 assert(beta > alpha);
127 /* we should find mate position */
128 if ((!material_pawns[WHITE] && !material_complete[BLACK]) || \
129 (!material_pawns[BLACK] && !material_complete[WHITE])) {
130 mate_score = evaluate_mate(WHITE) - evaluate_mate(BLACK);
131 if (mate_score)
132 return brd.wtm ? -mate_score : mate_score;
135 /* check for drawish endgame */
136 if (evaluate_draw_pattern())
137 return 0;
139 #ifdef STATISTIC_COUNTERS
140 counters.evaluations++;
141 #endif
142 zero_scores();
144 side_score[OPENING][WHITE] = material_complete[WHITE];
145 side_score[OPENING][BLACK] = material_complete[BLACK];
146 side_score[ENDGAME][WHITE] = material_complete[WHITE];
147 side_score[ENDGAME][BLACK] = material_complete[BLACK];
149 /* wtm bonus */
150 side_score[OPENING][brd.wtm] += wtm_bonus[OPENING];
151 side_score[ENDGAME][brd.wtm] += wtm_bonus[ENDGAME];
153 pawn_attacks[WHITE] = ((PAWNS(WHITE) & ~file_bit[7]) << 9) | \
154 ((PAWNS(WHITE) & ~file_bit[0]) << 7);
155 pawn_attacks[BLACK] = ((PAWNS(BLACK) & ~file_bit[0]) >> 9) | \
156 ((PAWNS(BLACK) & ~file_bit[7]) >> 7);
158 for (side = WHITE; side <= BLACK; side++) {
159 evaluate_pawns(side);
160 evaluate_knights(side);
161 evaluate_bishops(side);
162 evaluate_rooks(side);
163 evaluate_queens(side);
164 evaluate_king(side);
165 evaluate_material_imbalances(side);
166 evaluate_blocked_pieces(side);
169 /* look for rook behind passer */
170 for (side = WHITE; side <= BLACK; side++) {
171 int square;
172 uint64_t pp;
173 uint64_t bb = ROOKS(side);
175 while (bb) {
176 square = bit_scan_clear(&bb);
177 pp = file_bit[_FILE(square)] & (passers[WHITE] | passers[BLACK]);
178 if (pp) {
179 if (side == WHITE) {
180 if (_RANK(bit_scan(pp)) > _RANK(square))
181 position_score[ENDGAME][side] += rook_behind_pp;
182 } else {
183 if (_RANK(bit_scan(pp)) < _RANK(square))
184 position_score[ENDGAME][side] += rook_behind_pp;
190 /* bonus for having more pawns if there are now pieces on the board */
191 if (!material_pieces[WHITE] && !material_pieces[BLACK])
192 side_score[ENDGAME][WHITE] += (wpc - bpc) * more_pawns_bonus;
194 append_scores();
196 /* bishop of opposite colours */
197 if (wqc + wrc + wnc + bqc + brc + bnc == 0 && wbc == 1 && \
198 bbc == 1 && abs(wpc - bpc) <= 2) {
199 if (popcount((BISHOPS(WHITE) | BISHOPS(BLACK)) & WHITESQUARES) == 1) {
200 side_score[ENDGAME][WHITE] /= 2;
201 side_score[ENDGAME][BLACK] /= 2;
205 /* get final score according to game phase */
206 score = (OPENING_SCORE * (256 - GAME_PHASE) + \
207 ENDGAME_SCORE * GAME_PHASE) / 256;
208 assert(score >= -MATE_VALUE && score <= MATE_VALUE);
210 side = brd.wtm;
211 xside = 1 ^ side;
213 /* can't win if we have two knights or a bishop and no pawns
214 (but theoretically we can, for example so called 'cooperative mate') */
215 if (score > 0 && !material_pawns[side] && \
216 ((material_pieces[side] < piece_value[ROOK]) || \
217 (KNIGHTS(side) == r_pieces[side]))) {
218 score = 0;
219 } else if (score < 0 && !material_pawns[xside] && \
220 ((material_pieces[xside] < piece_value[ROOK]) || \
221 (KNIGHTS(xside) == r_pieces[xside]))) {
222 score = 0;
225 if (wqc == bqc && wrc == brc && abs(wbc + wnc - bbc - bnc) < 2) {
226 if (!wpc && !bpc) {
227 /* no pawns and one side is ahead by minor piece */
228 score /= 2;
229 } else {
230 if (score > 0) {
231 if (side == WHITE && (wbc + wnc - bbc - bnc == 1) && !wpc && bpc) {
232 score /= bpc + 1;
233 } else if (side == BLACK && (bbc + bnc - wbc - wnc == 1) && !bpc && wpc) {
234 score /= wpc + 1;
240 /* ROOK vs [KNIGHT|BISHOP] + (PAWN)? */
241 if ((material_pieces[WHITE] == piece_value[ROOK] && !wpc) && \
242 ((material_pieces[BLACK] == piece_value[KNIGHT] && bpc <= 1) || \
243 (material_pieces[BLACK] == piece_value[BISHOP] && bpc <= 1)))
244 score /= 8;
245 else if ((material_pieces[BLACK] == piece_value[ROOK] && !bpc) && \
246 ((material_pieces[WHITE] == piece_value[KNIGHT] && wpc <= 1) || \
247 (material_pieces[WHITE] == piece_value[BISHOP] && wpc <= 1)))
248 score /= 8;
250 return score;
253 static int pawn_square_op[2][64] = {
255 -15, -5, 0, 5, 5, 0, -5, -15,
256 -15, -5, 0, 5, 5, 0, -5, -15,
257 -15, -5, 0, 15, 15, 0, -5, -15,
258 -15, -5, 0, 25, 25, 0, -5, -15,
259 -15, -5, 0, 15, 15, 0, -5, -15,
260 -15, -5, 0, 5, 5, 0, -5, -15,
261 -15, -5, 0, 5, 5, 0, -5, -15,
262 -15, -5, 0, 5, 5, 0, -5, -15
265 -15, -5, 0, 5, 5, 0, -5, -15,
266 -15, -5, 0, 5, 5, 0, -5, -15,
267 -15, -5, 0, 5, 5, 0, -5, -15,
268 -15, -5, 0, 15, 15, 0, -5, -15,
269 -15, -5, 0, 25, 25, 0, -5, -15,
270 -15, -5, 0, 15, 15, 0, -5, -15,
271 -15, -5, 0, 5, 5, 0, -5, -15,
272 -15, -5, 0, 5, 5, 0, -5, -15
276 static int pawn_square_eg[2][64] = {
278 0, 0, 0, 0, 0, 0, 0, 0,
279 -1, -0, -0, -0, -0, -0, -0, -1,
280 -1, 0, 0, 0, 0, 0, 0, -1,
281 0, 0, 0, 5, 5, 0, 0, 0,
282 0, 5, 5, 10, 10, 5, 5, 0,
283 0, 5, 5, 10, 10, 5, 5, 0,
284 5, 15, 15, 15, 15, 15, 15, 5,
285 0, 0, 0, 0, 0, 0, 0, 0
288 0, 0, 0, 0, 0, 0, 0, 0,
289 5, 15, 15, 15, 15, 15, 15, 5,
290 0, 5, 5, 10, 10, 5, 5, 0,
291 0, 5, 5, 10, 10, 5, 5, 0,
292 0, 0, 0, 5, 5, 0, 0, 0,
293 -1, 0, 0, 0, 0, 0, 0, -1,
294 -1, -0, -0, -0, -0, -0, -0, -1,
295 0, 0, 0, 0, 0, 0, 0, 0
298 /* bonus for passed pawns */
299 static int passer_score_op[8] = {0, 0, 10, 15, 30, 45, 80, 0};
300 static int passer_score_eg[8] = {0, 0, 20, 35, 60, 10, 160, 0};
301 /* bonus for candidate passers */
302 static int can_passed_score_op[8] = {0, 0, 5, 10, 20, 35, 50, 0};
303 static int can_passed_score_eg[8] = {0, 0, 10, 20, 40, 70, 100, 0};
304 /* penalty for isolated pawns */
305 static int isolated_penalty_op[8] = {-6, -8, -10, -12, -12, -10, -8, -6};
306 static int isolated_penalty_eg[8] = {-7, -10, -14, -20, -20, -14, -10, -7};
307 /* penalty for isolated pawns on open files */
308 static int weak_isolated_penalty_op[8] = {-9, -10, -12, -18, -18, -12, -10, -9};
309 static int weak_isolated_penalty_eg[8] = {-10, -12, -14, -20, -20, -14, -12, -10};
310 /* penalty for doubled pawns */
311 static int doubled_penalty_op[8] = {-6, -8, -10, -12, -12, -10, -8, -6};
312 static int doubled_penalty_eg[8] = {-7, -10, -14, -20, -20, -14, -10, -7};
313 /* penalty for backward pawns */
314 static int backward_penalty_op = -8;
315 static int backward_penalty_eg = -10;
317 static void
318 evaluate_pawns(int side)
320 uint64_t b, bb;
321 int i;
322 int count;
323 int square;
324 int score_op, score_eg;
325 int xside;
327 int passed;
328 int side_defenders, xside_attackers;
329 struct pawn_hash_entry_t *phe;
331 score_op = 0;
332 score_eg = 0;
333 xside = 1 ^ side;
334 passers[side] = 0ULL;
335 bb = PAWNS(side);
337 phe = pawn_hash[side] + (brd.hash_pawn_key & pawn_hash_mask);
339 if (e.pawn_hash_enabled && phe->key == brd.hash_pawn_key) {
340 score_op = phe->score_op;
341 score_eg = phe->score_eg;
342 passers[side] = phe->passers;
343 #ifdef STATISTIC_COUNTERS
344 counters.pawn_hash_evaluations++;
345 #endif
346 } else {
347 while (bb) {
348 passed = FALSE;
349 square = bit_scan_clear(&bb);
351 /* search passers */
352 if (!(forward_ray[side][square] & PAWNS(side))) {
353 /* this is most advanced pawn */
354 if (!(PAWNS(xside) & passer_mask[side][square])) {
355 /* no opponents pawns on adjacent files */
356 score_op += passer_score_op[rank_flip[side][_RANK(square)]];
357 score_eg += passer_score_eg[rank_flip[side][_RANK(square)]];
359 SET(passers[side], square);
361 passed = TRUE;
363 } else if (!(forward_ray[side][square] & PAWNS(xside))) {
364 /* no opponent's pawns on the same file */
366 /* how many pawns defend our candidate */
367 side_defenders = popcount(pawn_moves[side][square] &
368 PAWNS(xside));
369 /* how many pawns attack our candidate */
370 xside_attackers = popcount(pawn_moves[side][square] & \
371 PAWNS(xside));
373 if (xside_attackers <= side_defenders) {
374 /* pawn is well protected */
376 /* how many pawns can support our candidate */
377 side_defenders = popcount((passer_mask[xside][square + \
378 (side == WHITE? 8 : -8)] & \
379 isolated_mask[_FILE(square)]) & PAWNS(side));
380 /* how many pawns can stop our candidate */
381 xside_attackers = popcount(passer_mask[side][square] & \
382 PAWNS(xside));
384 if (xside_attackers <= side_defenders)
385 /* true passed pawn candidate */
386 score_op += can_passed_score_op[rank_flip[side][_RANK(square)]];
387 score_eg += can_passed_score_eg[rank_flip[side][_RANK(square)]];
391 if (isolated_mask[_FILE(square)] & PAWNS(side)) {
392 /* pawn is not isolated, but maybe backward? */
393 if (!((passer_mask[xside][square + (side == WHITE? 8 : -8)] & \
394 isolated_mask[_FILE(square)]) & PAWNS(side)) && \
395 (rank_flip[side][square] != 1)) {
396 /* pawn is somewhat backward */
397 b = pawn_moves[side][square];
398 if (side == WHITE)
399 b <<= 8;
400 else
401 b >>= 8;
403 if (b & PAWNS(xside)) {
404 /* next square is attacked by opponents pawn */
405 score_op += backward_penalty_op;
406 score_eg += backward_penalty_eg;
408 /* backward on semiopen file */
409 if ((forward_ray[side][square] & PAWNS(xside)) == 0)
410 score_op += backward_penalty_op;
413 } else {
414 if (!passed) {
415 /* pawn is isolated */
416 if (!(forward_ray[side][square] & \
417 (PAWNS(side) | PAWNS(xside)))) {
418 /* isolated on semiopen file */
419 score_op += weak_isolated_penalty_op[_FILE(square)];
420 score_eg += weak_isolated_penalty_eg[_FILE(square)];
421 } else {
422 score_op += isolated_penalty_op[_FILE(square)];
423 score_eg += isolated_penalty_eg[_FILE(square)];
428 score_op += pawn_square_op[side][square];
429 score_eg += pawn_square_eg[side][square];
431 /* store scores in hashtable */
432 if (e.pawn_hash_enabled) {
433 phe->key = brd.hash_pawn_key;
434 phe->score_op = score_op;
435 phe->score_eg = score_eg;
436 phe->passers = passers[side];
440 /* evaluate doubled pawns */
441 for (i = 0; i < 8; i++) {
442 count = popcount(file_bit[i] & PAWNS(side));
443 if (count > 1) {
444 score_op += doubled_penalty_op[i] * (count - 1);
445 score_eg += doubled_penalty_eg[i] * (count - 1);
449 pawn_score[OPENING][side] += score_op;
450 pawn_score[ENDGAME][side] += score_eg;
453 static int knight_square_op[2][64] = {
455 -35, -25, -20, -15, -15, -20, -25, -35,
456 -20, -15, -10, -5, -5, -10, -15, -20,
457 -10, -5, 0, 5, 5, 0, -5, -10,
458 -5, 0, 5, 10, 10, 5, 0, -5,
459 -5, 5, 10, 15, 15, 10, 5, -5,
460 -3, 5, 10, 10, 10, 10, 5, -3,
461 -10, -5, 0, 5, 5, 0, -5, -10,
462 -25, -15, -10, -10, -10, -10, -15, -25
465 -25, -15, -10, -10, -10, -10, -15, -25,
466 -10, -5, 0, 5, 5, 0, -5, -10,
467 -3, 5, 10, 10, 10, 10, 5, -3,
468 -5, 5, 10, 15, 15, 10, 5, -5,
469 -5, 0, 5, 10, 10, 5, 0, -5,
470 -10, -5, 0, 5, 5, 0, -5, -10,
471 -20, -15, -10, -5, -5, -10, -15, -20,
472 -35, -25, -20, -15, -15, -20, -25, -35
476 static int knight_square_eg[64] = {
477 -30, -20, -15, -10, -10, -15, -20, -30,
478 -20, -15, -10, -5, -5, -10, -15, -20,
479 -15, -10, 0, 5, 5, 0, -10, -15,
480 -10, -5, 5, 10, 10, 5, -5, -10,
481 -10, -5, 5, 10, 10, 5, -5, -10,
482 -15, -10, 0, 5, 5, 0, -10, -15,
483 -20, -15, -10, -5, -5, -10, -15, -20,
484 -30, -20, -15, -10, -10, -15, -20, -30
487 static int knight_outpost[2][64] = {
489 0, 0, 0, 0, 0, 0, 0, 0,
490 0, 0, 0, 0, 0, 0, 0, 0,
491 0, 0, 0, 0, 0, 0, 0, 0,
492 0, 5, 9, 15, 15, 9, 5, 0,
493 0, 5, 9, 18, 18, 9, 5, 0,
494 0, 0, 5, 9, 9, 5, 0, 0,
495 0, 0, 0, 0, 0, 0, 0, 0,
496 0, 0, 0, 0, 0, 0, 0, 0
499 0, 0, 0, 0, 0, 0, 0, 0,
500 0, 0, 0, 0, 0, 0, 0, 0,
501 0, 0, 5, 9, 9, 5, 0, 0,
502 0, 5, 9, 18, 18, 9, 5, 0,
503 0, 5, 9, 15, 15, 9, 5, 0,
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
510 static int knight_mobility_op[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
511 static int knight_mobility_eg[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
513 /* evaluate knights */
514 static void
515 evaluate_knights(int side)
517 int square;
518 int xside;
519 int mobility;
520 uint64_t my_knights;
521 uint64_t mobility_xmask;
523 xside = 1 ^ side;
524 my_knights = KNIGHTS(side);
526 if (my_knights)
527 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
529 while (my_knights) {
530 square = bit_scan_clear(&my_knights);
532 /* piece square tables */
533 position_score[OPENING][side] += knight_square_op[side][square];
534 position_score[ENDGAME][side] += knight_square_eg[square];
536 if (knight_outpost[side][square])
537 /* is there enemy pawn that can potentially attack
538 our knight? */
539 if (!(PAWNS(xside) & (passer_mask[side][square] & \
540 isolated_mask[_FILE(square)])))
541 if (pawn_moves[xside][square] & PAWNS(side)) {
542 /* knight is supported by our pawn */
543 position_score[OPENING][side] += knight_outpost[side][square];
544 position_score[ENDGAME][side] += knight_outpost[side][square];
547 /* calculate mobility */
548 mobility = popcount(piece_moves[KNIGHT][square] & mobility_xmask);
549 mobility_score[OPENING][side] += knight_mobility_op[mobility];
550 mobility_score[ENDGAME][side] += knight_mobility_eg[mobility];
554 static int bishop_square_op[2][64] = {
556 -10, -10, -10, -5, -5, -10, -10, -10,
557 -5, -5, -5, 0, 0, -5, -5, -5,
558 -3, -1, 2, 3, 3, 2, -1, -3,
559 -2, 0, 3, 5, 5, 3, 0, -2,
560 -2, 0, 3, 5, 5, 3, 0, -2,
561 -3, -1, 2, 5, 5, 2, -1, -2,
562 -5, -2, 0, 0, 0, 0, -2, -5,
563 -10, -10, -10, -10, -10, -10, -10, -10
566 -10, -10, -10, -10, -10, -10, -10, -10,
567 -5, -2, 0, 0, 0, 0, -2, -5,
568 -3, -1, 2, 5, 5, 2, -1, -2,
569 -2, 0, 3, 5, 5, 3, 0, -2,
570 -2, 0, 3, 5, 5, 3, 0, -2,
571 -3, -1, 2, 3, 3, 2, -1, -3,
572 -5, -5, -5, 0, 0, -5, -5, -5,
573 -10, -10, -10, -5, -5, -10, -10, -10
577 static int bishop_square_eg[64] = {
578 -10, -10, -10, -5, -5, -10, -10, -10,
579 -5, -5, -5, 0, 0, -5, -5, -5,
580 -3, -1, 2, 3, 3, 2, -1, -3,
581 -2, 0, 3, 5, 5, 3, 0, -2,
582 -2, 0, 3, 5, 5, 3, 0, -2,
583 -3, -1, 2, 5, 5, 2, -1, -2,
584 -5, -5, -5, 0, 0, -5, -5, -5,
585 -10, -10, -10, -5, -5, -10, -10, -10
588 static int bishop_mobility_op[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 49, 60, 60};
589 static int bishop_mobility_eg[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 59, 60, 60};
591 /* evaluate bishops */
592 static void
593 evaluate_bishops(int side)
595 int square;
596 int mobility;
597 int xk;
598 int xside;
599 uint64_t attacks;
600 uint64_t mobility_xmask;
601 uint64_t my_bishops;
603 xside = 1 ^ side;
604 xk = brd.kings[xside];
605 my_bishops = BISHOPS(side);
607 if (my_bishops)
608 /* exclude these squares from mobility */
609 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
611 while (my_bishops) {
612 square = bit_scan_clear(&my_bishops);
614 attacks = BISHOP_ATTACKS(square, complete);
616 /* calculate mobility */
617 mobility = popcount(attacks & mobility_xmask);
618 mobility_score[OPENING][side] += bishop_mobility_op[mobility];
619 mobility_score[ENDGAME][side] += bishop_mobility_eg[mobility];
621 position_score[OPENING][side] += bishop_square_op[side][square];
622 position_score[ENDGAME][side] += bishop_square_eg[square];
626 static int rook_on_semiopen_file_op = 10;
627 static int rook_on_semiopen_file_eg = 10;
629 static int rook_on_semiopen_file_near_king_op = 15;
630 static int rook_on_semiopen_file_before_king_op = 20;
632 static int rook_on_open_file_op = 15;
633 static int rook_on_open_file_eg = 15;
635 static int rook_on_seven_rank_op = 20;
636 static int rook_on_seven_rank_eg = 20;
638 static int rook_mobility_op[] = {
639 -12, -8, -4, 0, 4, 8, 11, 14, 16, 18, 19, 20, 21, 22, 23, 24
641 static int rook_mobility_eg[] = {
642 -20, -12, -4, 4, 12, 20, 28, 36, 44, 50, 54, 56, 57, 58, 59, 60
645 static void
646 evaluate_rooks(int side)
648 int xk;
649 int file;
650 int square;
651 int xside;
652 int mobility;
653 uint64_t my_rooks;
654 uint64_t attacks;
655 uint64_t mobility_xmask;
657 my_rooks = ROOKS(side);
658 xside = 1 ^ side; /* opponent's color */
659 xk = brd.kings[xside]; /* location of opponent's king */
661 if (my_rooks)
662 /* exclude these squares from mobility */
663 mobility_xmask = ~(side_boards[side] | pawn_attacks[xside]);
665 while (my_rooks) {
666 square = bit_scan_clear(&my_rooks);
667 file = _FILE(square);
669 if (!(PAWNS(side) & file_bit[file])) {
670 /* there are no our pawns on the rook's file */
671 if (PAWNS(xside) & file_bit[file]) {
672 /* ... but there are opponent's pawns */
673 if (file == (_FILE(xk) - 1) || file == (_FILE(xk) + 1))
674 /* opponent's king is on the adjacent file */
675 position_score[OPENING][side] += rook_on_semiopen_file_near_king_op;
676 else if (file == _FILE(xk))
677 /* opponent's king is on the same file */
678 position_score[OPENING][side] += rook_on_semiopen_file_before_king_op;
679 else {
680 /* rook on semiopen file */
681 position_score[OPENING][side] += rook_on_semiopen_file_op;
682 position_score[ENDGAME][side] += rook_on_semiopen_file_eg;
684 } else {
685 /* rook on open file */
686 position_score[OPENING][side] += rook_on_open_file_op;
687 position_score[ENDGAME][side] += rook_on_open_file_eg;
690 if (rank_flip[side][_RANK(square)] == 6) {
691 /* rook on 7th rank */
692 position_score[OPENING][side] += rook_on_seven_rank_op;
693 position_score[ENDGAME][side] += rook_on_seven_rank_eg;
696 attacks = ROOK_ATTACKS(square, complete);
697 /* calculate mobility */
698 mobility = popcount(attacks & mobility_xmask);
699 mobility_score[OPENING][side] += rook_mobility_op[mobility];
700 mobility_score[ENDGAME][side] += rook_mobility_eg[mobility];
704 /* queen evaluation */
705 static void
706 evaluate_queens(int side)
708 /* TODO: mobility, attacks */
711 static int king_square_op[2][64] = {
713 40, 50, 30, 10, 10, 30, 50, 40,
714 30, 40, 20, 0, 0, 20, 40, 30,
715 10, 20, 0, -20, -20, 0, 20, 10,
716 0, 10, -10, -30, -30, -10, 10, 0,
717 -10, 0, -20, -40, -40, -20, 0, -10,
718 -20, -10, -30, -50, -50, -30, -10, -20,
719 -30, -20, -40, -60, -60, -40, -20, -30,
720 -40, -30, -50, -70, -70, -50, -30, -40
723 -40, -30, -50, -70, -70, -50, -30, -40,
724 -30, -20, -40, -60, -60, -40, -20, -30,
725 -20, -10, -30, -50, -50, -30, -10, -20,
726 -10, 0, -20, -40, -40, -20, 0, -10,
727 0, 10, -10, -30, -30, -10, 10, 0,
728 10, 20, 0, -20, -20, 0, 20, 10,
729 30, 40, 20, 0, 0, 20, 40, 30,
730 40, 50, 30, 10, 10, 30, 50, 40
734 static int king_square_eg[64] = {
735 -72, -48, -36, -24, -24, -36, -48, -72,
736 -48, -24, -12, 0, 0, -12, -24, -48,
737 -36, -12, 0, 12, 12, 0, -12, -36,
738 -24, 0, 12, 24, 24, 12, 0, -24,
739 -24, 0, 12, 24, 24, 12, 0, -24,
740 -36, -12, 0, 12, 12, 0, -12, -36,
741 -48, -24, -12, 0, 0, -12, -24, -48,
742 -72, -48, -36, -24, -24, -36, -48, -72
745 /* evaluate king */
746 static void
747 evaluate_king(int side)
749 int i;
750 int file;
751 int square;
752 int xside;
753 uint64_t bb, xbb;
755 xside = 1 ^ side; /* opponent's side */
756 square = brd.kings[side];
757 file = _FILE(square);
759 /* pawn shield and pawn attacks */
760 bb = passer_mask[side][square] & PAWNS(side);
761 xbb = passer_mask[side][square] & PAWNS(xside);
763 if (file != 0) {
764 /* in case if there is no our pawn */
765 king_score[OPENING][side] += -36;
767 if (bb & file_bit[file - 1]) {
768 /* find nearest pawn */
769 if (side == BLACK)
770 i = bit_scan_rev(bb & file_bit[file - 1]);
771 else
772 i = bit_scan(bb & file_bit[file - 1]);
773 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
774 (7 - rank_flip[side][_RANK(i)]);
777 /* pawn attack */
778 if (xbb & file_bit[file - 1]) {
779 if (side)
780 i = bit_scan_rev(xbb & file_bit[file - 1]);
781 else
782 i = bit_scan(xbb & file_bit[file - 1]);
783 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
787 /* in case if there is no our pawn in front of our king */
788 king_score[OPENING][side] += -36;
790 if (bb & file_bit[file]) {
791 if (side == BLACK)
792 i = bit_scan_rev(bb & file_bit[file]);
793 else
794 i = bit_scan(bb & file_bit[file]);
795 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
796 (7 - rank_flip[side][_RANK(i)]);
799 if (xbb & file_bit[file]) {
800 if (side)
801 i = bit_scan_rev(xbb & file_bit[file]);
802 else
803 i = bit_scan(xbb & file_bit[file]);
804 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
807 if (file != 7) {
808 /* in case if there is no our pawn */
809 king_score[OPENING][side] += -36;
810 if (bb & file_bit[file + 1]) {
811 /* find nearest pawn */
812 if (side)
813 i = bit_scan_rev(bb & file_bit[file + 1]);
814 else
815 i = bit_scan(bb & file_bit[file + 1]);
816 king_score[OPENING][side] += (7 - rank_flip[side][_RANK(i)]) * \
817 (7 - rank_flip[side][_RANK(i)]);
820 /* pawn attack */
821 if (xbb & file_bit[file + 1]) {
822 if (side)
823 i = bit_scan_rev(xbb & file_bit[file + 1]);
824 else
825 i = bit_scan(xbb & file_bit[file + 1]);
826 king_score[OPENING][side] -= MAX(0, (5 - rank_flip[side][_RANK(i)])) * 15;
830 position_score[OPENING][side] += king_square_op[side][square];
831 position_score[ENDGAME][side] += king_square_eg[square];
834 static int blocked_rook = -50;
835 static int trapped_bishop = -100;
837 static void
838 evaluate_blocked_pieces(int side)
840 int xside = 1 ^ side;
841 int side_inc = side * (A8 - A1);
843 /* rook */
844 if (square64[F1 + side_inc] == KING || square64[G1 + side_inc] == KING) {
845 if (square64[G1 + side_inc] == ROOK || square64[H1 + side_inc] == ROOK)
846 position_score[OPENING][side] += blocked_rook;
847 } else if (square64[C1 + side_inc] == KING || square64[B1 + side_inc] == KING) {
848 if (square64[A1 + side_inc] == ROOK || square64[B1 + side_inc] == ROOK)
849 position_score[OPENING][side] += blocked_rook;
852 int b_sq_a7 = side == WHITE? A7 : A2;
853 int b_sq_h7 = side == WHITE? H7 : H2;
854 int p_sq_b6 = side == WHITE? B6 : B3;
855 int p_sq_g6 = side == WHITE? G6 : G3;
857 if ((BISHOPS(side) & BIT(b_sq_a7)) && (PAWNS(xside) & BIT(p_sq_b6)) && \
858 SEE(SET_FROM(b_sq_a7) | SET_TO(p_sq_b6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
859 position_score[OPENING][side] += trapped_bishop;
860 position_score[ENDGAME][side] += trapped_bishop;
862 if ((BISHOPS(side) & BIT(b_sq_h7)) && (PAWNS(xside) & BIT(p_sq_g6)) && \
863 SEE(SET_FROM(b_sq_h7) | SET_TO(p_sq_g6) | SET_TYPE(TYPE_CAPTURE)) < 0) {
864 position_score[OPENING][side] += trapped_bishop;
865 position_score[ENDGAME][side] += trapped_bishop;
869 /* clear scores */
870 static void
871 zero_scores(void)
873 king_score[OPENING][WHITE] = 0;
874 king_score[OPENING][BLACK] = 0;
875 king_score[ENDGAME][WHITE] = 0;
876 king_score[ENDGAME][BLACK] = 0;
878 mobility_score[OPENING][WHITE] = 0;
879 mobility_score[OPENING][BLACK] = 0;
880 mobility_score[ENDGAME][WHITE] = 0;
881 mobility_score[ENDGAME][BLACK] = 0;
883 pawn_score[OPENING][WHITE] = 0;
884 pawn_score[OPENING][BLACK] = 0;
885 pawn_score[ENDGAME][WHITE] = 0;
886 pawn_score[ENDGAME][BLACK] = 0;
888 position_score[OPENING][WHITE] = 0;
889 position_score[OPENING][BLACK] = 0;
890 position_score[ENDGAME][WHITE] = 0;
891 position_score[ENDGAME][BLACK] = 0;
894 static int simple_mate_squares[2][64] = {
896 160, 140, 120, 100, 100, 120, 140, 160,
897 140, 120, 100, 80, 80, 100, 120, 140,
898 120, 100, 80, 60, 60, 80, 100, 120,
899 100, 80, 60, 40, 40, 60, 80, 100,
900 100, 80, 60, 40, 40, 60, 80, 100,
901 120, 100, 80, 60, 60, 80, 100, 120,
902 140, 120, 100, 80, 80, 100, 120, 140,
903 160, 140, 120, 100, 100, 120, 140, 160
906 160, 140, 120, 100, 100, 120, 140, 160,
907 140, 120, 100, 80, 80, 100, 120, 140,
908 120, 100, 80, 60, 60, 80, 100, 120,
909 100, 80, 60, 40, 40, 60, 80, 100,
910 100, 80, 60, 40, 40, 60, 80, 100,
911 120, 100, 80, 60, 60, 80, 100, 120,
912 140, 120, 100, 80, 80, 100, 120, 140,
913 160, 140, 120, 100, 100, 120, 140, 160
917 /* for KING vs KING, KNIGHT, BISHOP */
918 static int b_n_mate_dark_squares[64] = {
919 99, 90, 80, 70, 60, 50, 40, 30,
920 90, 80, 70, 60, 50, 40, 30, 40,
921 80, 70, 60, 50, 40, 30, 40, 50,
922 70, 60, 50, 40, 30, 40, 50, 60,
923 60, 50, 40, 30, 40, 50, 60, 70,
924 50, 40, 30, 40, 50, 60, 70, 80,
925 40, 30, 40, 50, 60, 70, 80, 90,
926 30, 40, 50, 60, 70, 80, 90, 99
929 static int b_n_mate_light_squares[64] = {
930 30, 40, 50, 60, 70, 80, 90, 99,
931 40, 30, 40, 50, 60, 70, 80, 90,
932 50, 40, 30, 40, 50, 60, 70, 80,
933 60, 50, 40, 30, 40, 50, 60, 70,
934 70, 60, 50, 40, 30, 40, 50, 60,
935 80, 70, 60, 50, 40, 30, 40, 50,
936 90, 80, 70, 60, 50, 40, 30, 40,
937 99, 90, 80, 70, 60, 50, 40, 30
940 static int
941 evaluate_mate(int side)
943 int score = 0;
944 int xside = 1 ^ side;
946 if (material_complete[side]) {
947 score = material_complete[side] + 200;
949 if (piece_count[side][KNIGHT] == 1 && piece_count[side][BISHOP] == 1) {
950 if (BISHOPS(side) & BLACKSQUARES)
951 score += b_n_mate_dark_squares[brd.kings[xside]];
952 else
953 score += b_n_mate_light_squares[brd.kings[xside]];
954 } else {
955 score += simple_mate_squares[side][brd.kings[xside]];
956 score -= distance[brd.kings[side]][brd.kings[xside]] * 10;
959 return score;
962 static int evaluate_draw_pattern()
964 /* TODO: add real draw code */
965 return FALSE;
968 static int bishop_pair = 50;
969 static int bishop_pair_correction = 15;
971 /* based on Larry Kaufman's paper */
972 static void
973 evaluate_material_imbalances(int side)
975 /* TODO: more imbalances */
977 int pc;
979 /* bishop pair */
980 if (piece_count[side][BISHOP] > 1) {
981 side_score[OPENING][side] += bishop_pair;
982 side_score[ENDGAME][side] += bishop_pair;
984 /* how many pawns on the board? */
985 pc = wpc + bpc;
987 if (pc > 12) {
988 side_score[OPENING][side] -= bishop_pair_correction;
989 side_score[ENDGAME][side] -= bishop_pair_correction;
990 } else if (pc < 8) {
991 side_score[OPENING][side] += bishop_pair_correction;
992 side_score[ENDGAME][side] += bishop_pair_correction;