Fixed bug in the search, now no more near-mate values should randomly appear.
[rattatechess.git] / evaluate.cpp.old
blob4997c9cd0f3e884fd13bd3ea40fe78bc468e3f8a
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       11
29 #define DEFENDED_PAWN      4
30 #define PASSED_PAWN        30
31 #define BLOCKED_PASSER     12
32 #define BLOCKED_BACKWARD  -13
33 #define BLOCKED_ISULATED  -13
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     1,1,1,1,1,1,1,1,ENDL,
53     1,1,2,2,2,2,1,1,ENDL,
54     1,2,3,4,4,3,2,1,ENDL,
55     1,2,4,5,5,4,2,1,ENDL,
56     1,2,4,5,5,4,2,1,ENDL,
57     1,2,3,4,4,3,2,1,ENDL,
58     1,1,2,2,2,2,1,1,ENDL,
59     1,1,1,1,1,1,1,1,ENDL    };
61 int kn_val[128] =  {
62     285,289,295,300,300,295,289,285,ENDL,
63     295,307,307,307,307,307,307,295,ENDL,
64     297,307,311,311,311,311,307,297,ENDL,
65     299,307,311,312,312,311,307,299,ENDL,
66     299,307,311,312,312,311,307,299,ENDL,
67     297,307,311,311,311,311,307,297,ENDL,
68     295,307,307,307,307,307,307,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,5,12,24,24,12,5,1,ENDL,
90     2,6,14,26,26,14,6,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,8,8,4,1,-5,ENDL,
108     0,4,10,12,12,10,4,0,ENDL,
109     1,8,12,14,14,12,8,1,ENDL,
110     1,8,12,14,14,12,8,1,ENDL,
111     0,4,10,12,12,10,4,0,ENDL,
112     -5,1,4,8,8,4,1,-5,ENDL,
113     -5,-5,1,2,2,1,-5,-5,ENDL
114    };
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++)
167     {
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--)
179         {
180             int16_t v = 0;
181             uint8_t pos = mt[BISHOP].pos[i];
183             for(int i=3;i>=0;i--)
184             {
185                 register uint8_t currpos = pos;
186                 register uint8_t currinc = bishmoves[i];
188                 while(1)
189                 {
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++;
201                 }
202             }
204             v += 315;
205             evaluation[is_white] += v;
206         }
208         /* Evaluate rooks */
209         for(int i=mt[ROOK].count-1;i>=0;i--)
210         {
211             int16_t v = 0;
212             uint8_t pos = mt[ROOK].pos[i];
214             for(int i=3;i>=0;i--)
215             {
216                 register uint8_t currpos = pos;
217                 register uint8_t currinc = rookmoves[i];
219                 while(1)
220                 {
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++;
232                 }
233             }
235             v += 500;
236             evaluation[is_white] += v;
237         }
239         /* Evaluate queen(s) */
240         for(int i=mt[QUEEN].count-1;i>=0;i--)
241         {
242             int16_t v = 0;
243             uint8_t pos = mt[QUEEN].pos[i];
245             for(int i=7;i>=0;i--)
246             {
247                 register uint8_t currpos = pos;
248                 register uint8_t currinc = kingmoves[i];
250                 do
251                 {
252                     currpos += currinc;
253                     if(data[currpos])
254                         break;
256                     v += controlled_bonus[currpos];
257                 }
258                 while(!IS_OF_COLOR(data[currpos],othcol));
259             }
261             v += 960;
262             evaluation[is_white] += v;
263         }
265         /* Evaluate knights */
266         for(int i=mt[KNIGHT].count-1;i>=0;i--)
267         {
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--)
276             {
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)
285                 {
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;
293                 }
294                 else
295                     v++;
296             }
298             v += 310;
299             evaluation[is_white] += v;
300         }
302         /* Evaluate pawns */
303         for(int i=mt[PAWN].count-1;i>=0;i--)
304         {
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)
317             {
318                 if(COLOR_OF(up_dir[is_white]+pos) == othcol)
319                     v += 100;
320                 else
321                     v += 200;
322             }
323             evaluation[is_white] += v;
324         }
325     }
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++)
361     {
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--)
373         {
374             int16_t v = 0;
375             uint8_t pos = mat_tracking[BISHOP+mt].pos[i];
377             for(int i=3;i>=0;i--)
378             {
379                 register uint8_t currpos = pos;
380                 register uint8_t currinc = bishmoves[i];
382                 while(1)
383                 {
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++;
399                 }
401                 if(OUT_OF_BOARD(currpos))
402                     continue;
404                 if(COLOR_OF(data[currpos]) == othcol)
405                 {
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])];
417                 }
418                 else if(data[currpos] == mypawn)
419                 {
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)
429                     {
430                         v += DEFEND_PASSED_PAWN/2;
431                     }
432                 }
433             }
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;
452         }
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--)
459         {
460             int16_t v = 0;
461             uint8_t pos = mat_tracking[ROOK+mt].pos[i];
463             for(int i=3;i>=0;i--)
464             {
465                 register uint8_t currpos = pos;
466                 register uint8_t currinc = rookmoves[i];
468                 while(1)
469                 {
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++;
485                 }
487                 if(OUT_OF_BOARD(currpos))
488                     continue;
490                 if(COLOR_OF(data[currpos]) == othcol)
491                 {
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])];
504                 }
505                 else if(data[currpos] == mypawn)
506                 {
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)
516                     {
517                         v += DEFEND_PASSED_PAWN;
518                     }
519                 }
520                 else if((~BISHOP&data[currpos])==(ROOK|color))
521                     v += CONNECTED_ROOKS;
522             }
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)
531             {
532                 if(line_pawns[1-is_white][X(pos)].count == 0)
533                     v += ROOK_OPEN_FILE;
534                 else
535                     v += ROOK_SEMIOPEN_FILE;
536             }
537             if( ROW_OF(pos) == seventh_rank[is_white] )
538                 v += ROOK_SEVENTH;
540             v += 500;
541             tropism[is_white] += rook_tropism[distance(pos, king_pos[!is_white])];
543             evaluation[is_white] += v;
544         }
546         /* Evaluate queen(s) */
547         for(int i=mat_tracking[QUEEN+mt].count-1;i>=0;i--)
548         {
549             int16_t v = 0;
550             uint8_t pos = mat_tracking[QUEEN+mt].pos[i];
552             for(int i=7;i>=0;i--)
553             {
554                 register uint8_t currpos = pos;
555                 register uint8_t currinc = kingmoves[i];
557                 do
558                 {
559                     currpos += currinc;
561                     if(OUT_OF_BOARD(currpos))
562                         break;
563                     if(data[currpos])
564                         break;
566                     v += controlled_bonus[currpos];
567                 }
568                 while(!IS_OF_COLOR(data[currpos],othcol));
569             }
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)
577             {
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;
582             }
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;
592         }
594         /* Evaluate knights */
595         for(int i=mat_tracking[KNIGHT+mt].count-1;i>=0;i--)
596         {
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--)
605             {
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))
615                 {
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;
623                 }
624                 else
625                     v++;
627                 if(IS_OF_COLOR(data[currpos], othcol))
628                 {
629                     tropism[is_white] +=
630                             knight_attack_tropism[distance(currpos, king_pos[!is_white])];
631                 }
632                 else if(data[currpos] == mypawn)
633                 {
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)
643                     {
644                         v += DEFEND_PASSED_PAWN/2;
645                     }
646                 }
647             }
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;
663         }
665         /* Evaluate pawns */
666         for(int i=mat_tracking[PAWN+mt].count-1;i>=0;i--)
667         {
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) )
676             {
677                 v += ISULATED_PAWN;
678                 if(COLOR_OF(data[uint8_t(up+pos)]) == othcol)
679                     v += BLOCKED_ISULATED;
680             }
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) )
686             {
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;
693             }
695             if(x!=0 && data[LEFT_OF(pos)]==data[pos])
696                 v += MAX(y-2,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)
707             {
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;
712             }
714             /* doubled pawns */
715             if(line_pawns[is_white][x].count > 1)
716                 v += doubled_pawn[x];
718             evaluation[is_white] += v;
719         }
721         /* Evaluate king */
722         for(int i=mat_tracking[KING+mt].count-1;i>=0;i--)
723         {
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) )
730             {
731                 if(material[!is_white]>=1500)
732                 {
733                     v += king_safety[pos];
734                     if(x!=0)
735                     {
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;
742                     }
743                     if(x!=7)
744                     {
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;
751                     }
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;
763                 }
764                 if(material[!is_white]<2400)
765                     v += endgame_king_val[pos];
766             }
767             else
768                 v -= 65;
770             evaluation[is_white] += v;
771         }
772     }
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