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] = {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);
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;
94 static int lazy_margin
= 250;
96 static uint64_t pawn_attacks
[2];
98 /* return TRUE if current position is DRAW */
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))
118 /* evaluate current position */
120 evaluate(int alpha
, int beta
)
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
);
135 return brd
.wtm
? -mate_score
: mate_score
;
138 /* check for drawish endgame */
139 if (evaluate_draw_pattern())
142 #ifdef STATISTIC_COUNTERS
143 counters
.evaluations
++;
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
];
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
))) {
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
);
175 evaluate_knights(side
);
176 evaluate_bishops(side
);
177 evaluate_rooks(side
);
178 evaluate_queens(side
);
183 /* look for rook behind passer */
184 for (side
= WHITE
; side
<= BLACK
; side
++) {
187 uint64_t bb
= ROOKS(side
);
190 square
= bit_scan_clear(&bb
);
191 pp
= file_bit
[_FILE(square
)] & passers
[side
];
194 if (_RANK(bit_scan(pp
)) > _RANK(square
))
195 position_score
[ENDGAME
][side
] += rook_behind_pp
;
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
;
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
);
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
]))) {
233 } else if (score
< 0 && !material_pawns
[xside
] && \
234 ((material_pieces
[xside
] < piece_value
[ROOK
]) || \
235 ((KNIGHTS(xside
) | KING(xside
)) == side_boards
[xside
]))) {
239 if (wqc
== bqc
&& wrc
== brc
&& abs(wbc
+ wnc
- bbc
- bnc
) < 2) {
241 /* no pawns and one side is ahead by minor piece */
245 if (side
== WHITE
&& (wbc
+ wnc
- bbc
- bnc
== 1) && !wpc
&& bpc
) {
247 } else if (side
== BLACK
&& (bbc
+ bnc
- wbc
- wnc
== 1) && !bpc
&& wpc
) {
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)))
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)))
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
= -9;
320 static int isolated_penalty_eg
= -18;
321 /* penalty for isolated pawns on open files */
322 static int weak_isolated_penalty_op
= -18;
323 static int weak_isolated_penalty_eg
= -18;
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;
332 evaluate_pawns(int side
)
338 int score_op
, score_eg
;
342 int side_defenders
, xside_attackers
;
343 struct pawn_hash_entry_t
*phe
;
348 passers
[side
] = 0ULL;
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
++;
363 square
= bit_scan_clear(&bb
);
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
) & complete
) ||
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
);
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
] &
388 /* how many pawns attack our candidate */
389 xside_attackers
= popcount(pawn_moves
[side
][square
] & \
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
] & \
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
];
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
;
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
;
439 score_eg
+= weak_isolated_penalty_eg
;
441 score_op
+= isolated_penalty_op
;
442 score_eg
+= isolated_penalty_eg
;
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
));
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
];
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] = {-15, -10, -5, 0, 4, 8, 12, 16, 20};
538 static int knight_mobility_eg
[9] = {-15, -10, -5, 0, 4, 8, 12, 16, 20};
539 static int knight_bonus
[17] = {-12, -11, -11, -10, -10, -8, -8, -5, -5, 0, 0,
542 /* evaluate knights */
544 evaluate_knights(int side
)
551 uint64_t mobility_xmask
;
554 xk
= brd
.kings
[xside
];
555 my_knights
= KNIGHTS(side
);
558 mobility_xmask
= ~(side_boards
[side
] | (pawn_attacks
[xside
] & ~complete
));
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
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
];
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] = {-25, -19, -13, -7, 0, 7, 13, 19, 25, 30, 35, 40, 45, 47, 49, 50};
631 static int bishop_mobility_eg
[16] = {-25, -19, -13, -7, 0, 7, 13, 19, 25, 30, 35, 40, 45, 47, 49, 50};
633 /* evaluate bishops */
635 evaluate_bishops(int side
)
642 uint64_t mobility_xmask
;
646 xk
= brd
.kings
[xside
];
647 my_bishops
= BISHOPS(side
);
650 /* exclude these squares from mobility */
651 mobility_xmask
= ~(side_boards
[side
] | (pawn_attacks
[xside
] & ~complete
));
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
];
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, -9, -6, -3, 0, 3, 6, 9, 12, 14, 16, 18, 20, 21, 22, 23
689 static int rook_mobility_eg
[] = {
690 -24, -18, -12, -6, 0, 6, 12, 18, 24, 28, 32, 36, 40, 42, 44, 46
694 evaluate_rooks(int side
)
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 */
710 /* exclude these squares from mobility */
711 mobility_xmask
= ~(side_boards
[side
] | (pawn_attacks
[xside
] & ~complete
));
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
;
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
;
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
];
751 if (attacks
& (piece_moves
[KING
][xk
] | BIT(xk
))) {
752 king_attacks
[side
] += 2;
753 king_attackers
[side
]++;
758 /* queen evaluation */
760 evaluate_queens(int side
)
767 my_queens
= QUEENS(side
);
768 xk
= brd
.kings
[1 ^ side
];
771 square
= bit_scan_clear(&my_queens
);
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};
824 evaluate_king(int side
)
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
];
845 /* pawn shield and pawn attacks */
846 bb
= passer_mask
[side
][i
] & PAWNS(side
);
847 xbb
= passer_mask
[side
][i
] & PAWNS(xside
);
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 */
856 i
= bit_scan_rev(bb
& file_bit
[file
- 1]);
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
)]);
864 /* in case if there is no our pawn in front of our king */
865 king_score
[OPENING
][side
] += -36;
867 if (bb
& file_bit
[file
]) {
869 i
= bit_scan_rev(bb
& file_bit
[file
]);
871 i
= bit_scan(bb
& file_bit
[file
]);
872 king_score
[OPENING
][side
] += (7 - rank_flip
[side
][_RANK(i
)]) * \
873 (7 - rank_flip
[side
][_RANK(i
)]);
877 /* in case if there is no our pawn */
878 king_score
[OPENING
][side
] += -36;
879 if (bb
& file_bit
[file
+ 1]) {
880 /* find nearest pawn */
882 i
= bit_scan_rev(bb
& file_bit
[file
+ 1]);
884 i
= bit_scan(bb
& file_bit
[file
+ 1]);
885 king_score
[OPENING
][side
] += (7 - rank_flip
[side
][_RANK(i
)]) * \
886 (7 - rank_flip
[side
][_RANK(i
)]);
890 king_score
[OPENING
][xside
] += (attack_penalty_op
* king_attacks
[side
] *
891 attack_scale
[king_attackers
[side
]]) / 16;
893 position_score
[OPENING
][side
] += king_square_op
[side
][square
];
894 position_score
[ENDGAME
][side
] += king_square_eg
[square
];
897 static int blocked_rook
= -50;
898 static int trapped_bishop
= -100;
901 evaluate_blocked_pieces(int side
)
903 int xside
= 1 ^ side
;
904 int side_inc
= side
* (A8
- A1
);
907 if (square64
[F1
+ side_inc
] == KING
|| square64
[G1
+ side_inc
] == KING
) {
908 if (square64
[G1
+ side_inc
] == ROOK
|| square64
[H1
+ side_inc
] == ROOK
)
909 position_score
[OPENING
][side
] += blocked_rook
;
910 } else if (square64
[C1
+ side_inc
] == KING
|| square64
[B1
+ side_inc
] == KING
) {
911 if (square64
[A1
+ side_inc
] == ROOK
|| square64
[B1
+ side_inc
] == ROOK
)
912 position_score
[OPENING
][side
] += blocked_rook
;
915 int b_sq_a7
= side
== WHITE
? A7
: A2
;
916 int b_sq_h7
= side
== WHITE
? H7
: H2
;
917 int p_sq_b6
= side
== WHITE
? B6
: B3
;
918 int p_sq_g6
= side
== WHITE
? G6
: G3
;
920 if ((BISHOPS(side
) & BIT(b_sq_a7
)) && (PAWNS(xside
) & BIT(p_sq_b6
)) && \
921 SEE(SET_FROM(b_sq_a7
) | SET_TO(p_sq_b6
) | SET_TYPE(TYPE_CAPTURE
)) < 0) {
922 position_score
[OPENING
][side
] += trapped_bishop
;
923 position_score
[ENDGAME
][side
] += trapped_bishop
;
925 if ((BISHOPS(side
) & BIT(b_sq_h7
)) && (PAWNS(xside
) & BIT(p_sq_g6
)) && \
926 SEE(SET_FROM(b_sq_h7
) | SET_TO(p_sq_g6
) | SET_TYPE(TYPE_CAPTURE
)) < 0) {
927 position_score
[OPENING
][side
] += trapped_bishop
;
928 position_score
[ENDGAME
][side
] += trapped_bishop
;
936 king_attacks
[WHITE
] = 0;
937 king_attacks
[BLACK
] = 0;
938 king_attackers
[WHITE
] = 0;
939 king_attackers
[BLACK
] = 0;
941 king_score
[OPENING
][WHITE
] = 0;
942 king_score
[OPENING
][BLACK
] = 0;
943 king_score
[ENDGAME
][WHITE
] = 0;
944 king_score
[ENDGAME
][BLACK
] = 0;
946 mobility_score
[OPENING
][WHITE
] = 0;
947 mobility_score
[OPENING
][BLACK
] = 0;
948 mobility_score
[ENDGAME
][WHITE
] = 0;
949 mobility_score
[ENDGAME
][BLACK
] = 0;
951 pawn_score
[OPENING
][WHITE
] = 0;
952 pawn_score
[OPENING
][BLACK
] = 0;
953 pawn_score
[ENDGAME
][WHITE
] = 0;
954 pawn_score
[ENDGAME
][BLACK
] = 0;
956 position_score
[OPENING
][WHITE
] = 0;
957 position_score
[OPENING
][BLACK
] = 0;
958 position_score
[ENDGAME
][WHITE
] = 0;
959 position_score
[ENDGAME
][BLACK
] = 0;
962 static int simple_mate_squares
[2][64] = {
964 160, 140, 120, 100, 100, 120, 140, 160,
965 140, 120, 100, 80, 80, 100, 120, 140,
966 120, 100, 80, 60, 60, 80, 100, 120,
967 100, 80, 60, 40, 40, 60, 80, 100,
968 100, 80, 60, 40, 40, 60, 80, 100,
969 120, 100, 80, 60, 60, 80, 100, 120,
970 140, 120, 100, 80, 80, 100, 120, 140,
971 160, 140, 120, 100, 100, 120, 140, 160
974 160, 140, 120, 100, 100, 120, 140, 160,
975 140, 120, 100, 80, 80, 100, 120, 140,
976 120, 100, 80, 60, 60, 80, 100, 120,
977 100, 80, 60, 40, 40, 60, 80, 100,
978 100, 80, 60, 40, 40, 60, 80, 100,
979 120, 100, 80, 60, 60, 80, 100, 120,
980 140, 120, 100, 80, 80, 100, 120, 140,
981 160, 140, 120, 100, 100, 120, 140, 160
985 /* for KING vs KING, KNIGHT, BISHOP */
986 static int b_n_mate_dark_squares
[64] = {
987 99, 90, 80, 70, 60, 50, 40, 30,
988 90, 80, 70, 60, 50, 40, 30, 40,
989 80, 70, 60, 50, 40, 30, 40, 50,
990 70, 60, 50, 40, 30, 40, 50, 60,
991 60, 50, 40, 30, 40, 50, 60, 70,
992 50, 40, 30, 40, 50, 60, 70, 80,
993 40, 30, 40, 50, 60, 70, 80, 90,
994 30, 40, 50, 60, 70, 80, 90, 99
997 static int b_n_mate_light_squares
[64] = {
998 30, 40, 50, 60, 70, 80, 90, 99,
999 40, 30, 40, 50, 60, 70, 80, 90,
1000 50, 40, 30, 40, 50, 60, 70, 80,
1001 60, 50, 40, 30, 40, 50, 60, 70,
1002 70, 60, 50, 40, 30, 40, 50, 60,
1003 80, 70, 60, 50, 40, 30, 40, 50,
1004 90, 80, 70, 60, 50, 40, 30, 40,
1005 99, 90, 80, 70, 60, 50, 40, 30
1009 evaluate_mate(int side
)
1012 int xside
= 1 ^ side
;
1014 if (material_complete
[side
]) {
1015 score
= material_complete
[side
] + 200;
1017 if (piece_count
[side
][KNIGHT
] == 1 && piece_count
[side
][BISHOP
] == 1) {
1018 if (BISHOPS(side
) & BLACKSQUARES
)
1019 score
+= b_n_mate_dark_squares
[brd
.kings
[xside
]];
1021 score
+= b_n_mate_light_squares
[brd
.kings
[xside
]];
1023 score
+= simple_mate_squares
[side
][brd
.kings
[xside
]];
1024 score
-= distance
[brd
.kings
[side
]][brd
.kings
[xside
]] * 10;
1030 static int evaluate_draw_pattern()
1032 /* TODO: add real draw code */
1036 static int bishop_pair
= 50;
1037 static int bishop_pair_correction_more
= 5;
1038 static int bishop_pair_correction_less
= 2;
1040 /* based on Larry Kaufman's paper */
1042 evaluate_material_imbalances(int side
)
1044 /* TODO: more imbalances */
1049 if (piece_count
[side
][BISHOP
] > 1) {
1050 side_score
[OPENING
][side
] += bishop_pair
;
1051 side_score
[ENDGAME
][side
] += bishop_pair
;
1053 /* how many pawns on the board? */
1057 side_score
[OPENING
][side
] -= (4 - (16 - pc
)) * bishop_pair_correction_more
;
1058 side_score
[ENDGAME
][side
] -= (4 - (16 - pc
)) * bishop_pair_correction_more
;
1059 } else if (pc
< 8) {
1060 side_score
[OPENING
][side
] += (8 - pc
) * bishop_pair_correction_less
;
1061 side_score
[ENDGAME
][side
] += (8 - pc
) * bishop_pair_correction_less
;