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;
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
[side
];
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
) | KING(side
)) == side_boards
[side
]))) {
221 } else if (score
< 0 && !material_pawns
[xside
] && \
222 ((material_pieces
[xside
] < piece_value
[ROOK
]) || \
223 ((KNIGHTS(xside
) | KING(xside
)) == side_boards
[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, 50, 100, 0};
302 static int passer_score_eg
[8] = {0, 0, 20, 35, 90, 150, 200, 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
[9] = {0, 0, -35, -28, -23, -16, -12, -12, -12};
314 static int doubled_penalty_eg
[9] = {0, 0, -45, -39, -33, -28, -23, -16, -12};
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 int next_square
= side
? square
- 8 : square
+ 8;
362 if ((BIT(next_square
) & side_boards
[xside
]) ||
363 (pawn_moves
[side
][next_square
] & PAWNS(xside
)))
364 score_eg
-= passer_score_eg
[rank_flip
[side
][_RANK(square
)]] / 3;
366 SET(passers
[side
], square
);
370 } else if (!(forward_ray
[side
][square
] & PAWNS(xside
))) {
371 /* no opponent's pawns on the same file */
373 /* how many pawns defend our candidate */
374 side_defenders
= popcount(pawn_moves
[side
][square
] &
376 /* how many pawns attack our candidate */
377 xside_attackers
= popcount(pawn_moves
[side
][square
] & \
380 if (xside_attackers
<= side_defenders
) {
381 /* pawn is well protected */
383 /* how many pawns can support our candidate */
384 side_defenders
= popcount((passer_mask
[xside
][square
+ \
385 (side
== WHITE
? 8 : -8)] & \
386 isolated_mask
[_FILE(square
)]) & PAWNS(side
));
387 /* how many pawns can stop our candidate */
388 xside_attackers
= popcount(passer_mask
[side
][square
] & \
391 if (xside_attackers
<= side_defenders
) {
392 /* true passed pawn candidate */
393 score_op
+= can_passed_score_op
[rank_flip
[side
][_RANK(square
)]];
394 score_eg
+= can_passed_score_eg
[rank_flip
[side
][_RANK(square
)]];
399 if (isolated_mask
[_FILE(square
)] & PAWNS(side
)) {
400 /* pawn is not isolated, but maybe backward? */
401 if (!((passer_mask
[xside
][square
+ (side
== WHITE
? 8 : -8)] & \
402 isolated_mask
[_FILE(square
)]) & PAWNS(side
))) {
403 /* pawn is somewhat backward */
404 b
= pawn_moves
[side
][square
];
410 if (b
& PAWNS(xside
)) {
411 /* next square is attacked by opponents pawn */
412 score_op
+= backward_penalty_op
;
413 score_eg
+= backward_penalty_eg
;
415 /* backward on semiopen file */
416 if ((forward_ray
[side
][square
] & PAWNS(xside
)) == 0)
417 score_op
+= backward_penalty_op
;
422 /* pawn is isolated */
423 if (!(forward_ray
[side
][square
] & \
424 (PAWNS(side
) | PAWNS(xside
)))) {
425 /* isolated on semiopen file */
426 score_op
+= weak_isolated_penalty_op
[_FILE(square
)];
427 score_eg
+= weak_isolated_penalty_eg
[_FILE(square
)];
429 score_op
+= isolated_penalty_op
[_FILE(square
)];
430 score_eg
+= isolated_penalty_eg
[_FILE(square
)];
435 score_op
+= pawn_square_op
[side
][square
];
436 score_eg
+= pawn_square_eg
[side
][square
];
439 /* evaluate doubled pawns */
440 for (i
= 0; i
< 8; i
++) {
441 count
= popcount(file_bit
[i
] & PAWNS(side
));
443 score_op
+= doubled_penalty_op
[piece_count
[side
][PAWN
]] * (count
- 1);
444 score_eg
+= doubled_penalty_eg
[piece_count
[side
][PAWN
]] * (count
- 1);
448 /* store scores in hashtable */
449 if (e
.pawn_hash_enabled
) {
450 phe
->key
= brd
.hash_pawn_key
;
451 phe
->score_op
= score_op
;
452 phe
->score_eg
= score_eg
;
453 phe
->passers
= passers
[side
];
459 square
= bit_scan_clear(&bb
);
460 score_eg
+= 5 - distance
[square
][brd
.kings
[side
]] * 5 +
461 distance
[square
][brd
.kings
[xside
]] * 5;
464 pawn_score
[OPENING
][side
] += score_op
;
465 pawn_score
[ENDGAME
][side
] += score_eg
;
468 static int knight_square_op
[2][64] = {
470 -35, -25, -20, -15, -15, -20, -25, -35,
471 -20, -15, -10, -5, -5, -10, -15, -20,
472 -10, -5, 0, 5, 5, 0, -5, -10,
473 -5, 0, 5, 10, 10, 5, 0, -5,
474 -5, 5, 10, 15, 15, 10, 5, -5,
475 -3, 5, 10, 10, 10, 10, 5, -3,
476 -10, -5, 0, 5, 5, 0, -5, -10,
477 -25, -15, -10, -10, -10, -10, -15, -25
480 -25, -15, -10, -10, -10, -10, -15, -25,
481 -10, -5, 0, 5, 5, 0, -5, -10,
482 -3, 5, 10, 10, 10, 10, 5, -3,
483 -5, 5, 10, 15, 15, 10, 5, -5,
484 -5, 0, 5, 10, 10, 5, 0, -5,
485 -10, -5, 0, 5, 5, 0, -5, -10,
486 -20, -15, -10, -5, -5, -10, -15, -20,
487 -35, -25, -20, -15, -15, -20, -25, -35
491 static int knight_square_eg
[64] = {
492 -30, -20, -15, -10, -10, -15, -20, -30,
493 -20, -15, -10, -5, -5, -10, -15, -20,
494 -15, -10, 0, 5, 5, 0, -10, -15,
495 -10, -5, 5, 10, 10, 5, -5, -10,
496 -10, -5, 5, 10, 10, 5, -5, -10,
497 -15, -10, 0, 5, 5, 0, -10, -15,
498 -20, -15, -10, -5, -5, -10, -15, -20,
499 -30, -20, -15, -10, -10, -15, -20, -30
502 static int knight_outpost
[2][64] = {
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,
507 0, 5, 9, 15, 15, 9, 5, 0,
508 0, 5, 9, 18, 18, 9, 5, 0,
509 0, 0, 5, 9, 9, 5, 0, 0,
510 0, 0, 0, 0, 0, 0, 0, 0,
511 0, 0, 0, 0, 0, 0, 0, 0
514 0, 0, 0, 0, 0, 0, 0, 0,
515 0, 0, 0, 0, 0, 0, 0, 0,
516 0, 0, 5, 9, 9, 5, 0, 0,
517 0, 5, 9, 18, 18, 9, 5, 0,
518 0, 5, 9, 15, 15, 9, 5, 0,
519 0, 0, 0, 0, 0, 0, 0, 0,
520 0, 0, 0, 0, 0, 0, 0, 0,
521 0, 0, 0, 0, 0, 0, 0, 0
525 static int knight_mobility_op
[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
526 static int knight_mobility_eg
[9] = {-10, -4, 2, 8, 14, 18, 22, 24, 25};
527 static int knight_bonus
[17] = {-12, -11, -11, -10, -10, -8, -8, -5, -5, 0, 0,
530 /* evaluate knights */
532 evaluate_knights(int side
)
540 uint64_t mobility_xmask
;
543 xk
= brd
.kings
[xside
];
544 my_knights
= KNIGHTS(side
);
547 mobility_xmask
= ~(side_boards
[side
] | pawn_attacks
[xside
]);
550 square
= bit_scan_clear(&my_knights
);
552 /* piece square tables */
553 position_score
[OPENING
][side
] += knight_square_op
[side
][square
];
554 position_score
[ENDGAME
][side
] += knight_square_eg
[square
];
556 if (knight_outpost
[side
][square
])
557 /* is there enemy pawn that can potentially attack
559 if (!(PAWNS(xside
) & (passer_mask
[side
][square
] & \
560 isolated_mask
[_FILE(square
)])))
561 if (pawn_moves
[xside
][square
] & PAWNS(side
)) {
562 /* knight is supported by our pawn */
563 position_score
[OPENING
][side
] += knight_outpost
[side
][square
];
564 position_score
[ENDGAME
][side
] += knight_outpost
[side
][square
];
567 /* calculate mobility */
568 mobility
= popcount(piece_moves
[KNIGHT
][square
] & mobility_xmask
);
569 mobility_score
[OPENING
][side
] += knight_mobility_op
[mobility
];
570 mobility_score
[ENDGAME
][side
] += knight_mobility_eg
[mobility
];
572 /* value of the knight depending of the pawns count */
573 position_score
[OPENING
][side
] += knight_bonus
[wpc
+ bpc
];
574 position_score
[ENDGAME
][side
] += knight_bonus
[wpc
+ bpc
];
577 attack_count
= popcount((piece_moves
[KING
][xk
] | BIT(xk
)) &
578 piece_moves
[KNIGHT
][square
]);
580 king_attacks
[side
] += attack_count
;
581 king_attackers
[side
]++;
586 static int bishop_square_op
[2][64] = {
588 -10, -10, -10, -5, -5, -10, -10, -10,
589 -5, -5, -5, 0, 0, -5, -5, -5,
590 -3, -1, 2, 3, 3, 2, -1, -3,
591 -2, 0, 3, 5, 5, 3, 0, -2,
592 -2, 0, 3, 5, 5, 3, 0, -2,
593 -3, -1, 2, 5, 5, 2, -1, -2,
594 -5, -2, 0, 0, 0, 0, -2, -5,
595 -10, -10, -10, -10, -10, -10, -10, -10
598 -10, -10, -10, -10, -10, -10, -10, -10,
599 -5, -2, 0, 0, 0, 0, -2, -5,
600 -3, -1, 2, 5, 5, 2, -1, -2,
601 -2, 0, 3, 5, 5, 3, 0, -2,
602 -2, 0, 3, 5, 5, 3, 0, -2,
603 -3, -1, 2, 3, 3, 2, -1, -3,
604 -5, -5, -5, 0, 0, -5, -5, -5,
605 -10, -10, -10, -5, -5, -10, -10, -10
609 static int bishop_square_eg
[64] = {
610 -10, -10, -10, -5, -5, -10, -10, -10,
611 -5, -5, -5, 0, 0, -5, -5, -5,
612 -3, -1, 2, 3, 3, 2, -1, -3,
613 -2, 0, 3, 5, 5, 3, 0, -2,
614 -2, 0, 3, 5, 5, 3, 0, -2,
615 -3, -1, 2, 5, 5, 2, -1, -2,
616 -5, -5, -5, 0, 0, -5, -5, -5,
617 -10, -10, -10, -5, -5, -10, -10, -10
620 static int bishop_mobility_op
[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 49, 60, 60};
621 static int bishop_mobility_eg
[16] = {-20, -10, 0, 5, 10, 20, 30, 44, 48, 52, 54, 57, 58, 59, 60, 60};
623 /* evaluate bishops */
625 evaluate_bishops(int side
)
633 uint64_t mobility_xmask
;
637 xk
= brd
.kings
[xside
];
638 my_bishops
= BISHOPS(side
);
641 /* exclude these squares from mobility */
642 mobility_xmask
= ~(side_boards
[side
] | pawn_attacks
[xside
]);
645 square
= bit_scan_clear(&my_bishops
);
647 attacks
= BISHOP_ATTACKS(square
, complete
);
649 /* calculate mobility */
650 mobility
= popcount(attacks
& mobility_xmask
);
651 mobility_score
[OPENING
][side
] += bishop_mobility_op
[mobility
];
652 mobility_score
[ENDGAME
][side
] += bishop_mobility_eg
[mobility
];
654 position_score
[OPENING
][side
] += bishop_square_op
[side
][square
];
655 position_score
[ENDGAME
][side
] += bishop_square_eg
[square
];
658 attack_count
= popcount(BISHOP_ATTACKS(square
, complete
& ~attacks
) &
659 (piece_moves
[KING
][xk
] | BIT(xk
)));
661 king_attacks
[side
] += attack_count
;
662 king_attackers
[side
]++;
667 static int rook_on_semiopen_file_op
= 10;
668 static int rook_on_semiopen_file_eg
= 10;
670 static int rook_on_semiopen_file_near_king_op
= 15;
671 static int rook_on_semiopen_file_before_king_op
= 20;
673 static int rook_on_open_file_op
= 15;
674 static int rook_on_open_file_eg
= 15;
676 static int rook_on_seven_rank_op
= 20;
677 static int rook_on_seven_rank_eg
= 20;
679 static int rook_mobility_op
[] = {
680 -12, -8, -4, 0, 4, 8, 11, 14, 16, 18, 19, 20, 21, 22, 23, 24
682 static int rook_mobility_eg
[] = {
683 -20, -12, -4, 4, 12, 20, 28, 36, 44, 50, 54, 56, 57, 58, 59, 60
687 evaluate_rooks(int side
)
697 uint64_t mobility_xmask
;
699 my_rooks
= ROOKS(side
);
700 xside
= 1 ^ side
; /* opponent's color */
701 xk
= brd
.kings
[xside
]; /* location of opponent's king */
704 /* exclude these squares from mobility */
705 mobility_xmask
= ~(side_boards
[side
] | pawn_attacks
[xside
]);
708 square
= bit_scan_clear(&my_rooks
);
709 file
= _FILE(square
);
711 if (!(PAWNS(side
) & file_bit
[file
])) {
712 /* there are no our pawns on the rook's file */
713 if (PAWNS(xside
) & file_bit
[file
]) {
714 /* ... but there are opponent's pawns */
715 if (file
== (_FILE(xk
) - 1) || file
== (_FILE(xk
) + 1))
716 /* opponent's king is on the adjacent file */
717 position_score
[OPENING
][side
] += rook_on_semiopen_file_near_king_op
;
718 else if (file
== _FILE(xk
))
719 /* opponent's king is on the same file */
720 position_score
[OPENING
][side
] += rook_on_semiopen_file_before_king_op
;
722 /* rook on semiopen file */
723 position_score
[OPENING
][side
] += rook_on_semiopen_file_op
;
724 position_score
[ENDGAME
][side
] += rook_on_semiopen_file_eg
;
727 /* rook on open file */
728 position_score
[OPENING
][side
] += rook_on_open_file_op
;
729 position_score
[ENDGAME
][side
] += rook_on_open_file_eg
;
732 if (rank_flip
[side
][_RANK(square
)] == 6) {
733 /* rook on 7th rank */
734 position_score
[OPENING
][side
] += rook_on_seven_rank_op
;
735 position_score
[ENDGAME
][side
] += rook_on_seven_rank_eg
;
738 attacks
= ROOK_ATTACKS(square
, complete
);
739 /* calculate mobility */
740 mobility
= popcount(attacks
& mobility_xmask
);
741 mobility_score
[OPENING
][side
] += rook_mobility_op
[mobility
];
742 mobility_score
[ENDGAME
][side
] += rook_mobility_eg
[mobility
];
745 attack_count
= popcount(ROOK_ATTACKS(square
, complete
& ~attacks
) &
746 (piece_moves
[KING
][xk
] | BIT(xk
)));
748 king_attacks
[side
] += attack_count
* 2;
749 king_attackers
[side
]++;
754 /* queen evaluation */
756 evaluate_queens(int side
)
764 my_queens
= QUEENS(side
);
765 xk
= brd
.kings
[1 ^ side
];
768 square
= bit_scan_clear(&my_queens
);
770 attacks
= QUEEN_ATTACKS(square
, complete
);
771 attack_count
= popcount(QUEEN_ATTACKS(square
, complete
& ~attacks
) &
772 (piece_moves
[KING
][xk
] | BIT(xk
)));
774 king_attacks
[side
] += attack_count
* 4;
775 king_attackers
[side
]++;
780 static int king_square_op
[2][64] = {
782 40, 50, 30, 10, 10, 30, 50, 40,
783 30, 40, 20, 0, 0, 20, 40, 30,
784 10, 20, 0, -20, -20, 0, 20, 10,
785 0, 10, -10, -30, -30, -10, 10, 0,
786 -10, 0, -20, -40, -40, -20, 0, -10,
787 -20, -10, -30, -50, -50, -30, -10, -20,
788 -30, -20, -40, -60, -60, -40, -20, -30,
789 -40, -30, -50, -70, -70, -50, -30, -40
792 -40, -30, -50, -70, -70, -50, -30, -40,
793 -30, -20, -40, -60, -60, -40, -20, -30,
794 -20, -10, -30, -50, -50, -30, -10, -20,
795 -10, 0, -20, -40, -40, -20, 0, -10,
796 0, 10, -10, -30, -30, -10, 10, 0,
797 10, 20, 0, -20, -20, 0, 20, 10,
798 30, 40, 20, 0, 0, 20, 40, 30,
799 40, 50, 30, 10, 10, 30, 50, 40
803 static int king_square_eg
[64] = {
804 -72, -48, -36, -24, -24, -36, -48, -72,
805 -48, -24, -12, 0, 0, -12, -24, -48,
806 -36, -12, 0, 12, 12, 0, -12, -36,
807 -24, 0, 12, 24, 24, 12, 0, -24,
808 -24, 0, 12, 24, 24, 12, 0, -24,
809 -36, -12, 0, 12, 12, 0, -12, -36,
810 -48, -24, -12, 0, 0, -12, -24, -48,
811 -72, -48, -36, -24, -24, -36, -48, -72
814 static int attack_penalty_op
= -15;
815 static int attack_scale
[16] = {
816 0, 0, 8, 10, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
819 static const int side_offset
[2] = {-8, 8};
823 evaluate_king(int side
)
832 xside
= 1 ^ side
; /* opponent's side */
833 square
= brd
.kings
[side
];
835 file
= _FILE(square
);
836 rank
= _RANK(square
);
838 /* include adjacent pawns into mask */
839 if ((side
== WHITE
&& rank
!= 0) || (side
== BLACK
&& rank
!= 7))
840 i
= square
+ side_offset
[side
];
844 /* pawn shield and pawn attacks */
845 bb
= passer_mask
[side
][i
] & PAWNS(side
);
846 xbb
= passer_mask
[side
][i
] & PAWNS(xside
);
849 /* in case if there is no our pawn */
850 king_score
[OPENING
][side
] += -36;
852 if (bb
& file_bit
[file
- 1]) {
853 /* find nearest pawn */
855 i
= bit_scan_rev(bb
& file_bit
[file
- 1]);
857 i
= bit_scan(bb
& file_bit
[file
- 1]);
858 king_score
[OPENING
][side
] += (7 - rank_flip
[side
][_RANK(i
)]) * \
859 (7 - rank_flip
[side
][_RANK(i
)]);
863 if (xbb
& file_bit
[file
- 1]) {
865 i
= bit_scan_rev(xbb
& file_bit
[file
- 1]);
867 i
= bit_scan(xbb
& file_bit
[file
- 1]);
868 king_score
[OPENING
][side
] -= MAX(0, (5 - rank_flip
[side
][_RANK(i
)])) * 15;
872 /* in case if there is no our pawn in front of our king */
873 king_score
[OPENING
][side
] += -36;
875 if (bb
& file_bit
[file
]) {
877 i
= bit_scan_rev(bb
& file_bit
[file
]);
879 i
= bit_scan(bb
& file_bit
[file
]);
880 king_score
[OPENING
][side
] += (7 - rank_flip
[side
][_RANK(i
)]) * \
881 (7 - rank_flip
[side
][_RANK(i
)]);
884 if (xbb
& file_bit
[file
]) {
886 i
= bit_scan_rev(xbb
& file_bit
[file
]);
888 i
= bit_scan(xbb
& file_bit
[file
]);
889 king_score
[OPENING
][side
] -= MAX(0, (5 - rank_flip
[side
][_RANK(i
)])) * 15;
893 /* in case if there is no our pawn */
894 king_score
[OPENING
][side
] += -36;
895 if (bb
& file_bit
[file
+ 1]) {
896 /* find nearest pawn */
898 i
= bit_scan_rev(bb
& file_bit
[file
+ 1]);
900 i
= bit_scan(bb
& file_bit
[file
+ 1]);
901 king_score
[OPENING
][side
] += (7 - rank_flip
[side
][_RANK(i
)]) * \
902 (7 - rank_flip
[side
][_RANK(i
)]);
906 if (xbb
& file_bit
[file
+ 1]) {
908 i
= bit_scan_rev(xbb
& file_bit
[file
+ 1]);
910 i
= bit_scan(xbb
& file_bit
[file
+ 1]);
911 king_score
[OPENING
][side
] -= MAX(0, (5 - rank_flip
[side
][_RANK(i
)])) * 15;
915 king_score
[OPENING
][xside
] += (attack_penalty_op
* king_attacks
[side
] *
916 attack_scale
[king_attackers
[side
]]) / 16;
918 position_score
[OPENING
][side
] += king_square_op
[side
][square
];
919 position_score
[ENDGAME
][side
] += king_square_eg
[square
];
922 static int blocked_rook
= -50;
923 static int trapped_bishop
= -100;
926 evaluate_blocked_pieces(int side
)
928 int xside
= 1 ^ side
;
929 int side_inc
= side
* (A8
- A1
);
932 if (square64
[F1
+ side_inc
] == KING
|| square64
[G1
+ side_inc
] == KING
) {
933 if (square64
[G1
+ side_inc
] == ROOK
|| square64
[H1
+ side_inc
] == ROOK
)
934 position_score
[OPENING
][side
] += blocked_rook
;
935 } else if (square64
[C1
+ side_inc
] == KING
|| square64
[B1
+ side_inc
] == KING
) {
936 if (square64
[A1
+ side_inc
] == ROOK
|| square64
[B1
+ side_inc
] == ROOK
)
937 position_score
[OPENING
][side
] += blocked_rook
;
940 int b_sq_a7
= side
== WHITE
? A7
: A2
;
941 int b_sq_h7
= side
== WHITE
? H7
: H2
;
942 int p_sq_b6
= side
== WHITE
? B6
: B3
;
943 int p_sq_g6
= side
== WHITE
? G6
: G3
;
945 if ((BISHOPS(side
) & BIT(b_sq_a7
)) && (PAWNS(xside
) & BIT(p_sq_b6
)) && \
946 SEE(SET_FROM(b_sq_a7
) | SET_TO(p_sq_b6
) | SET_TYPE(TYPE_CAPTURE
)) < 0) {
947 position_score
[OPENING
][side
] += trapped_bishop
;
948 position_score
[ENDGAME
][side
] += trapped_bishop
;
950 if ((BISHOPS(side
) & BIT(b_sq_h7
)) && (PAWNS(xside
) & BIT(p_sq_g6
)) && \
951 SEE(SET_FROM(b_sq_h7
) | SET_TO(p_sq_g6
) | SET_TYPE(TYPE_CAPTURE
)) < 0) {
952 position_score
[OPENING
][side
] += trapped_bishop
;
953 position_score
[ENDGAME
][side
] += trapped_bishop
;
961 king_attacks
[WHITE
] = 0;
962 king_attacks
[BLACK
] = 0;
963 king_attackers
[WHITE
] = 0;
964 king_attackers
[BLACK
] = 0;
966 king_score
[OPENING
][WHITE
] = 0;
967 king_score
[OPENING
][BLACK
] = 0;
968 king_score
[ENDGAME
][WHITE
] = 0;
969 king_score
[ENDGAME
][BLACK
] = 0;
971 mobility_score
[OPENING
][WHITE
] = 0;
972 mobility_score
[OPENING
][BLACK
] = 0;
973 mobility_score
[ENDGAME
][WHITE
] = 0;
974 mobility_score
[ENDGAME
][BLACK
] = 0;
976 pawn_score
[OPENING
][WHITE
] = 0;
977 pawn_score
[OPENING
][BLACK
] = 0;
978 pawn_score
[ENDGAME
][WHITE
] = 0;
979 pawn_score
[ENDGAME
][BLACK
] = 0;
981 position_score
[OPENING
][WHITE
] = 0;
982 position_score
[OPENING
][BLACK
] = 0;
983 position_score
[ENDGAME
][WHITE
] = 0;
984 position_score
[ENDGAME
][BLACK
] = 0;
987 static int simple_mate_squares
[2][64] = {
989 160, 140, 120, 100, 100, 120, 140, 160,
990 140, 120, 100, 80, 80, 100, 120, 140,
991 120, 100, 80, 60, 60, 80, 100, 120,
992 100, 80, 60, 40, 40, 60, 80, 100,
993 100, 80, 60, 40, 40, 60, 80, 100,
994 120, 100, 80, 60, 60, 80, 100, 120,
995 140, 120, 100, 80, 80, 100, 120, 140,
996 160, 140, 120, 100, 100, 120, 140, 160
999 160, 140, 120, 100, 100, 120, 140, 160,
1000 140, 120, 100, 80, 80, 100, 120, 140,
1001 120, 100, 80, 60, 60, 80, 100, 120,
1002 100, 80, 60, 40, 40, 60, 80, 100,
1003 100, 80, 60, 40, 40, 60, 80, 100,
1004 120, 100, 80, 60, 60, 80, 100, 120,
1005 140, 120, 100, 80, 80, 100, 120, 140,
1006 160, 140, 120, 100, 100, 120, 140, 160
1010 /* for KING vs KING, KNIGHT, BISHOP */
1011 static int b_n_mate_dark_squares
[64] = {
1012 99, 90, 80, 70, 60, 50, 40, 30,
1013 90, 80, 70, 60, 50, 40, 30, 40,
1014 80, 70, 60, 50, 40, 30, 40, 50,
1015 70, 60, 50, 40, 30, 40, 50, 60,
1016 60, 50, 40, 30, 40, 50, 60, 70,
1017 50, 40, 30, 40, 50, 60, 70, 80,
1018 40, 30, 40, 50, 60, 70, 80, 90,
1019 30, 40, 50, 60, 70, 80, 90, 99
1022 static int b_n_mate_light_squares
[64] = {
1023 30, 40, 50, 60, 70, 80, 90, 99,
1024 40, 30, 40, 50, 60, 70, 80, 90,
1025 50, 40, 30, 40, 50, 60, 70, 80,
1026 60, 50, 40, 30, 40, 50, 60, 70,
1027 70, 60, 50, 40, 30, 40, 50, 60,
1028 80, 70, 60, 50, 40, 30, 40, 50,
1029 90, 80, 70, 60, 50, 40, 30, 40,
1030 99, 90, 80, 70, 60, 50, 40, 30
1034 evaluate_mate(int side
)
1037 int xside
= 1 ^ side
;
1039 if (material_complete
[side
]) {
1040 score
= material_complete
[side
] + 200;
1042 if (piece_count
[side
][KNIGHT
] == 1 && piece_count
[side
][BISHOP
] == 1) {
1043 if (BISHOPS(side
) & BLACKSQUARES
)
1044 score
+= b_n_mate_dark_squares
[brd
.kings
[xside
]];
1046 score
+= b_n_mate_light_squares
[brd
.kings
[xside
]];
1048 score
+= simple_mate_squares
[side
][brd
.kings
[xside
]];
1049 score
-= distance
[brd
.kings
[side
]][brd
.kings
[xside
]] * 10;
1055 static int evaluate_draw_pattern()
1057 /* TODO: add real draw code */
1061 static int bishop_pair
= 50;
1062 static int bishop_pair_correction
= 15;
1064 /* based on Larry Kaufman's paper */
1066 evaluate_material_imbalances(int side
)
1068 /* TODO: more imbalances */
1073 if (piece_count
[side
][BISHOP
] > 1) {
1074 side_score
[OPENING
][side
] += bishop_pair
;
1075 side_score
[ENDGAME
][side
] += bishop_pair
;
1077 /* how many pawns on the board? */
1081 side_score
[OPENING
][side
] -= bishop_pair_correction
;
1082 side_score
[ENDGAME
][side
] -= bishop_pair_correction
;
1083 } else if (pc
< 8) {
1084 side_score
[OPENING
][side
] += bishop_pair_correction
;
1085 side_score
[ENDGAME
][side
] += bishop_pair_correction
;