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