Tuned null move and history prun... ops, late move reduction :)
[rattatechess.git] / evaluate.cpp
blob5c9c3248ce49495063957f6b305911d679a6f848
1 /***************************************************************************
2 evaluate.cpp - description
3 -------------------
4 begin : Wed Mar 13 2002
5 copyright : (C) 2002-2005 by Maurizio Monge
6 email : monge@linuz.sns.it
7 ***************************************************************************/
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
18 #include "board.h"
19 #include "evaluations.h"
21 #define ROOK_SEVENTH 19
22 #define ROOK_OPEN_FILE 14
23 #define ROOK_SEMIOPEN_FILE 9
24 #define ISULATED_PAWN -10
25 #define DOUBLED_PAWN -8
26 #define BACKWARD_PAWN -3
27 #define BACKWARD_OPEN_FILE_PAWN -10
28 #define COUPLED_PAWN 15
29 #define DEFENDED_PAWN 4
30 #define PASSED_PAWN 30
31 #define BLOCKED_PASSER 12
32 #define BLOCKED_BACKWARD -13
33 #define BLOCKED_ISULATED -17
34 #define PASSED_PIECE 9
35 #define ATTACKING_PIECE 7
36 #define ATTACKING_PAWN 4
37 #define DEFEND_PASSED_PAWN 13
38 #define CONNECTED_ROOKS 15
39 #define UNDEVELOPED 10
40 #define TWO_BISHOPS 13
42 #define VERY_UNSAFE_KING_LATERAL -16
43 #define UNSAFE_KING_LATERAL -10
44 #define VERY_UNSAFE_KING -23
45 #define UNSAFE_KING -14
47 //------------------------------------------------------
49 int coupled_pawns[7] = { 2, 4, 8, 10, 8, 4, 2 };
51 int controlled_bonus[128] = {
52 2,2,2,2,2,2,2,2,ENDL,
53 2,2,3,3,3,3,2,2,ENDL,
54 2,3,4,5,5,4,3,2,ENDL,
55 2,3,5,6,6,5,3,2,ENDL,
56 2,3,5,6,6,5,3,2,ENDL,
57 2,3,4,5,5,4,3,2,ENDL,
58 2,2,3,3,3,3,2,2,ENDL,
59 2,2,2,2,2,2,2,2,ENDL };
61 int kn_val[128] = {
62 285,289,295,300,300,295,289,285,ENDL,
63 295,303,303,303,303,303,303,295,ENDL,
64 297,303,307,307,307,307,303,297,ENDL,
65 299,303,307,309,309,307,303,299,ENDL,
66 299,303,307,309,309,307,303,299,ENDL,
67 297,303,307,307,307,307,303,297,ENDL,
68 295,303,303,303,303,303,303,295,ENDL,
69 285,289,295,300,300,295,289,285,ENDL
72 int bsh_val[128] = {
73 312,298,300,307,307,300,298,312,ENDL,
74 311,314,311,311,311,311,314,311,ENDL,
75 312,313,315,314,314,315,313,312,ENDL,
76 312,313,314,315,315,314,313,312,ENDL,
77 312,313,314,315,315,314,313,312,ENDL,
78 312,313,315,314,314,315,313,312,ENDL,
79 311,314,311,311,311,311,314,311,ENDL,
80 312,298,300,307,307,300,298,312,ENDL
83 int paw_val[128] = {
84 0,0,0,0,0,0,0,0,ENDL,
85 -3,0,1,-15,-15,1,0,-3,ENDL,
86 -2,1,3, 7, 7,3,1,-2,ENDL,
87 -1,2,9,16,16,9,2,-1,ENDL,
88 0,4,11,22,22,11,4,0,ENDL,
89 1,6,13,24,24,13,6,1,ENDL,
90 2,8,15,26,26,15,8,2,ENDL,
91 0,0,0,0,0,0,0,0,ENDL
94 int king_safety[128] = {
95 0,0,-2,-30,-30,-25,0,0,ENDL,
96 -1,-4,-20,-100,-100,-20,-4,-1,ENDL,
97 -300,-300,-300,-300,-300,-300,-300,-300,ENDL,
98 -300,-300,-300,-300,-300,-300,-300,-300,ENDL,
99 -300,-300,-300,-300,-300,-300,-300,-300,ENDL,
100 -300,-300,-300,-300,-300,-300,-300,-300,ENDL,
101 -1,-4,-20,-100,-100,-20,-4,-1,ENDL,
102 0,0,-2,-30,-30,-25,0,0,ENDL
105 int endgame_king_val[128] = {
106 -5,-5,1,2,2,1,-5,-5,ENDL,
107 -5,1,4,6,6,4,1,-5,ENDL,
108 0,4,10,12,12,10,4,0,ENDL,
109 1,6,12,14,14,12,6,1,ENDL,
110 1,6,12,14,14,12,6,1,ENDL,
111 0,4,10,12,12,10,4,0,ENDL,
112 -5,1,4,6,6,4,1,-5,ENDL,
113 -5,-5,1,2,2,1,-5,-5,ENDL
116 int backward_pawn[8] = { -1, -2, -3, -5, -5, -3, -2, -1 };
117 int doubled_pawn[8] = { -6, -5, -4, -2, -2, -4, -5, -6 };
119 int queen_tropism[8] = { 0, 51, 70, 40, 10, 0, 0, 0};
120 int rook_tropism[8] = { 0, 3, 2, 1, 0, 0, 0, 0};
121 int knight_tropism[8] = { 0, 10, 7, 5, 2, 0, 0, 0};
122 int bishop_tropism[8] = { 0, 3, 3, 2, 1, 0, 0, 0};
123 int rook_attack_tropism[8] = { 0, 5, 3, 0, 0, 0, 0, 0};
124 int knight_attack_tropism[8] = { 0, 5, 3, 0, 0, 0, 0, 0};
125 int bishop_attack_tropism[8] = { 0, 5, 3, 0, 0, 0, 0, 0};
127 int piece_val[] = { 500, 325, 1000, 325, 100, 0 };
129 inline int distance(uint8_t a, uint8_t b)
131 return MAX(ABS(X(a)-X(b)), ABS(Y(a)-Y(b)));
134 int16_t Board::dummy_evaluate()
136 int material[2] = { 0, 0 };
138 int p=0;
139 for(int col=0;col<2;col++)
140 for(int i=0;i<6;i++)
141 material[col] += mat_tracking[p++].count * piece_val[i];
143 return material[IS_WHITE(color_to_move)] -
144 material[IS_WHITE(other_color)];
147 #if 0
148 //5x5?
149 int16_t Board::evaluate(uint8_t eng_color, int16_t alpha, int16_t beta)
151 //return 0;
153 int material[2] = { 0, 0 };
154 int evaluation[2] = { 0, 0 };
155 int king_danger[2] = { 0, 0 };
156 int tropism[2] = { 0,0 };
158 int p=0;
159 for(int col=0;col<2;col++)
160 for(int i=0;i<6;i++)
161 material[col] += mat_tracking[p++].count * piece_val[i];
163 //return material[IS_WHITE(color_to_move)] -
164 // material[IS_WHITE(other_color)];
166 for(int is_white=0;is_white<2;is_white++)
168 uint8_t color = is_white ? WHITE : BLACK;
169 uint8_t othcol = OTHER_COLOR(color);
170 uint8_t up = up_dir[is_white];
171 uint8_t up_left = up+LEFT;
172 uint8_t up_right = up+RIGHT;
173 uint8_t othpawn = PAWN|othcol;
174 uint8_t mypawn = PAWN|color;
175 MatTrack *mt = (is_white ? mat_tracking+5 : mat_tracking-1);
177 /* Evaluate bishops */
178 for(int i=mt[BISHOP].count-1;i>=0;i--)
180 int16_t v = 0;
181 uint8_t pos = mt[BISHOP].pos[i];
183 for(int i=3;i>=0;i--)
185 register uint8_t currpos = pos;
186 register uint8_t currinc = bishmoves[i];
188 while(1)
190 currpos += currinc;
192 if(data[currpos])
193 break;
195 uint8_t p1 = currpos + up_left;
196 uint8_t p2 = currpos + up_right;
197 if( data[p1]!=othpawn && data[p2]!=othpawn )
198 v += controlled_bonus[currpos];
199 else
200 v++;
204 v += 315;
205 evaluation[is_white] += v;
208 /* Evaluate rooks */
209 for(int i=mt[ROOK].count-1;i>=0;i--)
211 int16_t v = 0;
212 uint8_t pos = mt[ROOK].pos[i];
214 for(int i=3;i>=0;i--)
216 register uint8_t currpos = pos;
217 register uint8_t currinc = rookmoves[i];
219 while(1)
221 currpos += currinc;
223 if(data[currpos])
224 break;
226 uint8_t p1 = currpos + up_left;
227 uint8_t p2 = currpos + up_right;
228 if( data[p1]!=othpawn && data[p2]!=othpawn )
229 v += controlled_bonus[currpos];
230 else
231 v++;
235 v += 500;
236 evaluation[is_white] += v;
239 /* Evaluate queen(s) */
240 for(int i=mt[QUEEN].count-1;i>=0;i--)
242 int16_t v = 0;
243 uint8_t pos = mt[QUEEN].pos[i];
245 for(int i=7;i>=0;i--)
247 register uint8_t currpos = pos;
248 register uint8_t currinc = kingmoves[i];
252 currpos += currinc;
253 if(data[currpos])
254 break;
256 v += controlled_bonus[currpos];
258 while(!IS_OF_COLOR(data[currpos],othcol));
261 v += 960;
262 evaluation[is_white] += v;
265 /* Evaluate knights */
266 for(int i=mt[KNIGHT].count-1;i>=0;i--)
268 //evaluation[is_white] += 325;
269 //continue;
271 int16_t v = 0;
272 uint8_t pos = mt[KNIGHT].pos[i];
273 KnightMove* hm = &knightmoves[pos];
275 for(int i=hm->numm;i>=0;i--)
277 register uint8_t currpos = hm->jump[i];
278 if(IS_OF_COLOR(data[currpos], color))
279 continue;
281 uint8_t p1 = currpos + up_left;
282 uint8_t p2 = currpos + up_right;
284 if(data[p1]!=othpawn && data[p2]!=othpawn)
286 v += controlled_bonus[currpos];
288 /* give a bonus activity value if attacking a pawn/piece
289 that is not defended by an enemy pawn */
290 if(IS_OF_COLOR(data[currpos], othcol))
291 v += PIECE_OF(data[currpos])==PAWN
292 ? ATTACKING_PAWN : ATTACKING_PIECE;
294 else
295 v++;
298 v += 310;
299 evaluation[is_white] += v;
302 /* Evaluate pawns */
303 for(int i=mt[PAWN].count-1;i>=0;i--)
305 int16_t v = 0;
306 uint8_t pos = mt[PAWN].pos[i];
307 uint8_t x = X(pos);
308 uint8_t y = is_white ? Y(pos) : 7-Y(pos);
310 /* passed pawn */
311 v = 100;
312 if( (x==0||!line_pawns[1-is_white][x-1].count ||
313 line_pawns[1-is_white][x-1].pos[0]>=7-y) &&
314 (x==4||!line_pawns[1-is_white][x+1].count ||
315 line_pawns[1-is_white][x+1].pos[0]>=7-y) &&
316 !line_pawns[1-is_white][x].count)
318 if(COLOR_OF(up_dir[is_white]+pos) == othcol)
319 v += 100;
320 else
321 v += 200;
323 evaluation[is_white] += v;
328 /*evaluation[0] += (1500*(evaluation[0]-evaluation[1]))/
329 (2000+material[0]+material[1]);
330 evaluation[0] += tropism[0] * 200 / MAX(200 + king_danger[1], 70);
331 evaluation[1] += tropism[1] * 200 / MAX(200 + king_danger[0], 70);*/
333 int16_t retv = /*5 +*/ evaluation[IS_WHITE(color_to_move)] -
334 evaluation[IS_WHITE(other_color)];
335 return retv;
337 #else
338 //CHESS
339 int16_t Board::evaluate(uint8_t eng_color, int16_t alpha, int16_t beta)
341 int material[2] = { 0, 0 };
342 int evaluation[2] = { 0, 0 };
343 int king_danger[2] = { 0, 0 };
344 int tropism[2] = { 0, 0 };
346 int p=0;
347 for(int col=0;col<2;col++)
348 for(int i=0;i<6;i++)
349 material[col] += mat_tracking[p++].count * piece_val[i];
351 /*return material[IS_WHITE(color_to_move)] -
352 material[IS_WHITE(other_color)];*/
353 /*int16_t approx = 5+material[IS_WHITE(color_to_move)] -
354 material[IS_WHITE(other_color)];
355 if(approx > beta+400)
356 return beta;
357 if(approx < alpha-400)
358 return alpha;*/
360 for(int is_white=0;is_white<2;is_white++)
362 uint8_t color = is_white ? WHITE : BLACK;
363 uint8_t othcol = OTHER_COLOR(color);
364 uint8_t up = up_dir[is_white];
365 uint8_t up_left = up+LEFT;
366 uint8_t up_right = up+RIGHT;
367 uint8_t othpawn = PAWN|othcol;
368 uint8_t mypawn = PAWN|color;
369 int mt = (is_white ? +5 : -1);
371 /* Evaluate bishops */
372 for(int i=mat_tracking[BISHOP+mt].count-1;i>=0;i--)
374 int16_t v = 0;
375 uint8_t pos = mat_tracking[BISHOP+mt].pos[i];
377 for(int i=3;i>=0;i--)
379 register uint8_t currpos = pos;
380 register uint8_t currinc = bishmoves[i];
382 while(1)
384 currpos += currinc;
386 if(OUT_OF_BOARD(currpos))
387 break;
389 if(data[currpos])
390 break;
392 uint8_t p1 = currpos + up_left;
393 uint8_t p2 = currpos + up_right;
394 if( (OUT_OF_BOARD(p1) || data[p1]!=othpawn)
395 && (OUT_OF_BOARD(p2) || data[p2]!=othpawn) )
396 v += controlled_bonus[currpos];
397 else
398 v++;
401 if(OUT_OF_BOARD(currpos))
402 continue;
404 if(COLOR_OF(data[currpos]) == othcol)
406 uint8_t p1 = currpos + up_left;
407 uint8_t p2 = currpos + up_right;
409 /* give a bonus activity value if attacking a pawn/piece
410 that is not defended by an enemy pawn */
411 if( (OUT_OF_BOARD(p1) || data[p1]!=othpawn)
412 && (OUT_OF_BOARD(p2) || data[p2]!=othpawn) )
413 v += PIECE_OF(data[currpos])==PAWN
414 ? ATTACKING_PAWN : ATTACKING_PIECE;
415 tropism[is_white] +=
416 bishop_attack_tropism[distance(currpos, king_pos[1-is_white])];
418 else if(data[currpos] == mypawn)
420 uint8_t x = X(currpos);
421 uint8_t y = is_white ? Y(currpos) : 7-Y(currpos);
423 /* give a bonus for defending passed pawns */
424 if( (x==0||!line_pawns[1-is_white][x-1].count ||
425 line_pawns[1-is_white][x-1].pos[0]>=7-y) &&
426 (x==7||!line_pawns[1-is_white][x+1].count ||
427 line_pawns[1-is_white][x+1].pos[0]>=7-y) &&
428 !line_pawns[1-is_white][x].count)
430 v += DEFEND_PASSED_PAWN/2;
434 if(v<UNDEVELOPED)
435 v = v*2 - UNDEVELOPED;
437 v += bsh_val[pos];
438 tropism[is_white] += bishop_tropism[distance(pos, king_pos[1-is_white])];
440 /* penalize the bishop if there are a lot of pawns around */
441 //v -= 2*(mat_tracking[PAWN-1].count + mat_tracking[PAWN+5].count);
443 uint8_t x = X(pos);
444 uint8_t y = is_white ? Y(pos) : 7-Y(pos);
445 if( (x==0||!line_pawns[!is_white][x-1].count ||
446 line_pawns[!is_white][x-1].pos[0]>=7-y) &&
447 (x==7||!line_pawns[!is_white][x+1].count ||
448 line_pawns[!is_white][x+1].pos[0]>=7-y) )
449 v += PASSED_PIECE;
451 evaluation[is_white] += v;
453 /* bonus for having both bishops */
454 if(mat_tracking[BISHOP+mt].count == 2)
455 evaluation[is_white] += TWO_BISHOPS;
457 /* Evaluate rooks */
458 for(int i=mat_tracking[ROOK+mt].count-1;i>=0;i--)
460 int16_t v = 0;
461 uint8_t pos = mat_tracking[ROOK+mt].pos[i];
463 for(int i=3;i>=0;i--)
465 register uint8_t currpos = pos;
466 register uint8_t currinc = rookmoves[i];
468 while(1)
470 currpos += currinc;
472 if(OUT_OF_BOARD(currpos))
473 break;
475 if(data[currpos])
476 break;
478 uint8_t p1 = currpos + up_left;
479 uint8_t p2 = currpos + up_right;
480 if( (OUT_OF_BOARD(p1) || data[p1]!=othpawn)
481 && (OUT_OF_BOARD(p2) || data[p2]!=othpawn) )
482 v += controlled_bonus[currpos];
483 else
484 v++;
487 if(OUT_OF_BOARD(currpos))
488 continue;
490 if(COLOR_OF(data[currpos]) == othcol)
492 uint8_t p1 = currpos + up_left;
493 uint8_t p2 = currpos + up_right;
495 /* give a bonus activity value if attacking a pawn/piece
496 that is not defended by an enemy pawn */
497 if( (OUT_OF_BOARD(p1) || data[p1]!=othpawn)
498 && (OUT_OF_BOARD(p2) || data[p2]!=othpawn) )
499 v += PIECE_OF(data[currpos])==PAWN
500 ? ATTACKING_PAWN : ATTACKING_PIECE;
502 tropism[is_white] +=
503 rook_attack_tropism[distance(currpos, king_pos[1-is_white])];
505 else if(data[currpos] == mypawn)
507 uint8_t x = X(currpos);
508 uint8_t y = is_white ? Y(currpos) : 7-Y(currpos);
510 /* give a bonus for defending passed pawns */
511 if( (x==0||!line_pawns[1-is_white][x-1].count ||
512 line_pawns[1-is_white][x-1].pos[0]>=7-y) &&
513 (x==7||!line_pawns[1-is_white][x+1].count ||
514 line_pawns[1-is_white][x+1].pos[0]>=7-y) &&
515 !line_pawns[1-is_white][x].count)
517 v += DEFEND_PASSED_PAWN;
520 else if((~BISHOP&data[currpos])==(ROOK|color))
521 v += CONNECTED_ROOKS;
523 if(v<UNDEVELOPED)
524 v = v*2 - UNDEVELOPED;
526 /* evaluate less rook activity (more important is
527 if it is on a open/close file)*/
528 v /= 4;
530 if(line_pawns[is_white][X(pos)].count == 0)
532 if(line_pawns[1-is_white][X(pos)].count == 0)
533 v += ROOK_OPEN_FILE;
534 else
535 v += ROOK_SEMIOPEN_FILE;
537 if( ROW_OF(pos) == seventh_rank[is_white] )
538 v += ROOK_SEVENTH;
540 v += 485;
541 tropism[is_white] += rook_tropism[distance(pos, king_pos[!is_white])];
543 evaluation[is_white] += v;
546 /* Evaluate queen(s) */
547 for(int i=mat_tracking[QUEEN+mt].count-1;i>=0;i--)
549 int16_t v = 0;
550 uint8_t pos = mat_tracking[QUEEN+mt].pos[i];
552 for(int i=7;i>=0;i--)
554 register uint8_t currpos = pos;
555 register uint8_t currinc = kingmoves[i];
559 currpos += currinc;
561 if(OUT_OF_BOARD(currpos))
562 break;
563 if(data[currpos])
564 break;
566 v += controlled_bonus[currpos];
568 while(!IS_OF_COLOR(data[currpos],othcol));
571 /* evaluate less queen activity, so ratta won't go
572 around with the queen all the time */
573 v /= 16;
575 /* bonus for 7th or open file */
576 if(line_pawns[is_white][X(pos)].count == 0)
578 if(line_pawns[1-is_white][X(pos)].count == 0)
579 v += ROOK_OPEN_FILE/2;
580 else
581 v += ROOK_SEMIOPEN_FILE/2;
583 if(Y(pos) == (color==WHITE?6:1))
584 v += ROOK_SEVENTH/2;
586 v += 960;
587 tropism[is_white] += queen_tropism[distance(pos, king_pos[1-is_white])];
589 if(color == eng_color) v += 17;
591 evaluation[is_white] += v;
594 /* Evaluate knights */
595 for(int i=mat_tracking[KNIGHT+mt].count-1;i>=0;i--)
597 //evaluation[is_white] += 325;
598 //continue;
600 int16_t v = 0;
601 uint8_t pos = mat_tracking[KNIGHT+mt].pos[i];
602 KnightMove* hm = &knightmoves[pos];
604 for(int i=hm->numm;i>=0;i--)
606 register uint8_t currpos = hm->jump[i];
607 if(IS_OF_COLOR(data[currpos], color))
608 continue;
610 uint8_t p1 = currpos + up_left;
611 uint8_t p2 = currpos + up_right;
613 if((OUT_OF_BOARD(p1) || data[p1]!=othpawn) &&
614 (OUT_OF_BOARD(p2) || data[p2]!=othpawn))
616 v += controlled_bonus[currpos];
618 /* give a bonus activity value if attacking a pawn/piece
619 that is not defended by an enemy pawn */
620 if(IS_OF_COLOR(data[currpos], othcol))
621 v += PIECE_OF(data[currpos])==PAWN
622 ? ATTACKING_PAWN : ATTACKING_PIECE;
624 else
625 v++;
627 if(IS_OF_COLOR(data[currpos], othcol))
629 tropism[is_white] +=
630 knight_attack_tropism[distance(currpos, king_pos[!is_white])];
632 else if(data[currpos] == mypawn)
634 uint8_t x = X(currpos);
635 uint8_t y = is_white ? Y(currpos) : 7-Y(currpos);
637 /* give a bonus for defending passed pawns */
638 if( (x==0||!line_pawns[1-is_white][x-1].count ||
639 line_pawns[1-is_white][x-1].pos[0]>=7-y) &&
640 (x==7||!line_pawns[1-is_white][x+1].count ||
641 line_pawns[1-is_white][x+1].pos[0]>=7-y) &&
642 !line_pawns[1-is_white][x].count)
644 v += DEFEND_PASSED_PAWN/2;
648 if(v<UNDEVELOPED)
649 v = v*2 - UNDEVELOPED;
651 v += kn_val[pos];
652 tropism[is_white] += knight_tropism[distance(pos, king_pos[!is_white])];
654 uint8_t x = X(pos);
655 uint8_t y = is_white ? Y(pos) : 7-Y(pos);
656 if( (x==0||!line_pawns[!is_white][x-1].count ||
657 line_pawns[!is_white][x-1].pos[0]>=7-y) &&
658 (x==7||!line_pawns[!is_white][x+1].count ||
659 line_pawns[!is_white][x+1].pos[0]<=7-y) )
660 v += PASSED_PIECE;
662 evaluation[is_white] += v;
665 /* Evaluate pawns */
666 for(int i=mat_tracking[PAWN+mt].count-1;i>=0;i--)
668 int16_t v = 0;
669 uint8_t pos = mat_tracking[PAWN+mt].pos[i];
670 uint8_t x = X(pos);
671 uint8_t y = is_white ? Y(pos) : 7-Y(pos);
673 v += (100 + paw_val[POS_XY(x,y)]);
674 if( (x == 0 || line_pawns[is_white][x-1].count == 0) &&
675 (x == 7 || line_pawns[is_white][x+1].count == 0) )
677 v += ISULATED_PAWN;
678 if(COLOR_OF(data[uint8_t(up+pos)]) == othcol)
679 v += BLOCKED_ISULATED;
682 if( (x == 0 || line_pawns[is_white][x-1].count == 0
683 || line_pawns[is_white][x-1].pos[0] > y) &&
684 (x == 7 || line_pawns[is_white][x+1].count == 0
685 || line_pawns[is_white][x+1].pos[0] > y) )
687 v += backward_pawn[x];
688 if(!line_pawns[1-is_white][x].count)
689 v += BACKWARD_OPEN_FILE_PAWN;
690 if(COLOR_OF(data[uint8_t(up+pos)]) == othcol
691 && PIECE_OF(data[uint8_t(up+pos)]) != PAWN)
692 v += BLOCKED_BACKWARD;
695 if(x!=0 && data[LEFT_OF(pos)]==data[pos])
696 v += MAX(y-1,0)*coupled_pawns[x];
697 if(x!=0 && (data[LEFTUP_OF(pos)]==data[pos] ||
698 data[LEFTDOWN_OF(pos)]==data[pos]))
699 v += DEFENDED_PAWN;
701 /* passed pawn */
702 if( (x==0||!line_pawns[1-is_white][x-1].count ||
703 line_pawns[1-is_white][x-1].pos[0]>=7-y) &&
704 (x==7||!line_pawns[1-is_white][x+1].count ||
705 line_pawns[1-is_white][x+1].pos[0]>=7-y) &&
706 !line_pawns[1-is_white][x].count)
708 if(COLOR_OF(up_dir[is_white]+pos) == othcol)
709 v += MAX(y-2,1)*BLOCKED_PASSER;
710 else
711 v += MAX(y-2,1)*PASSED_PAWN;
714 /* doubled pawns */
715 if(line_pawns[is_white][x].count > 1)
716 v += doubled_pawn[x];
718 evaluation[is_white] += v;
721 /* Evaluate king */
722 for(int i=mat_tracking[KING+mt].count-1;i>=0;i--)
724 int16_t v = 0;
725 uint8_t pos = mat_tracking[KING+mt].pos[i];
726 uint8_t x = X(pos);
728 if( is_white ? !(castle_passing_mask & 0x30) :
729 !(castle_passing_mask & 0xc0) )
731 if(material[!is_white]>=1500)
733 v += king_safety[pos];
734 if(x!=0)
736 if((!line_pawns[1-is_white][x-1].count) ||
737 line_pawns[1-is_white][x-1].pos[0]>=3)
738 v += VERY_UNSAFE_KING_LATERAL;
739 if(!line_pawns[is_white][x-1].count ||
740 line_pawns[is_white][x-1].pos[0]>=2)
741 v += UNSAFE_KING_LATERAL;
743 if(x!=7)
745 if((!line_pawns[1-is_white][x+1].count) ||
746 line_pawns[1-is_white][x+1].pos[0]>=3)
747 v += VERY_UNSAFE_KING_LATERAL;
748 if(!line_pawns[is_white][x+1].count ||
749 line_pawns[is_white][x+1].pos[0]>=2)
750 v += UNSAFE_KING_LATERAL;
752 if((!line_pawns[1-is_white][x].count) ||
753 line_pawns[1-is_white][x].pos[0]>=3)
754 v += VERY_UNSAFE_KING;
755 if(!line_pawns[is_white][x].count ||
756 line_pawns[is_white][x].pos[0]>=2)
757 v += UNSAFE_KING;
759 v = v * (material[!is_white]-1500)/1500;
760 if(color == eng_color)
761 v *= 2;
762 king_danger[is_white] = v;
764 if(material[!is_white]<2400)
765 v += endgame_king_val[pos];
767 else
768 v -= 65;
770 evaluation[is_white] += v;
775 evaluation[0] += (1500*(evaluation[0]-evaluation[1]))/
776 (2000+material[0]+material[1]);
777 evaluation[0] += tropism[0] * 200 / MAX(200 + king_danger[1], 70);
778 evaluation[1] += tropism[1] * 200 / MAX(200 + king_danger[0], 70);
780 int16_t retv = 5 + evaluation[IS_WHITE(color_to_move)] -
781 evaluation[IS_WHITE(other_color)];
783 if(mat_tracking[PAWN-1].count + mat_tracking[PAWN+5].count >= 15)
784 retv += color_to_move == eng_color ? -15 : 15;
785 else if(mat_tracking[PAWN-1].count + mat_tracking[PAWN+5].count >= 15)
786 retv += color_to_move == eng_color ? -8 : 8;
788 return retv;
790 #endif