execute
[rattatechess.git] / evaluate.cpp
blobf157bc2d9ad08f6aefe0325c0fa68310bdf78b7b
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 <string.h>
19 #include "board.h"
22 #define PASSED_PAWN 30
23 #define BLOCKED_PASSER 12
24 #define PASSED_PIECE 11
25 #define ATTACKING_PIECE 7
26 #define ATTACKING_PAWN 5
27 #define DEFEND_PASSED_PAWN 13
28 #define CONNECTED_ROOKS 21
29 #define UNDEVELOPED 10
30 #define TWO_BISHOPS 45
32 #define VERY_UNSAFE_KING_LATERAL -16
33 #define UNSAFE_KING_LATERAL -10
34 #define VERY_UNSAFE_KING -23
35 #define UNSAFE_KING -14
37 //------------------------------------------------------
39 const int king_still_to_castle = -120;
41 const int pawn_chain = 5;
42 const int pawn_insula = -18;
43 const int pawn_isulated = -10;
44 const int pawn_isulated_blocked = -17;
45 const int pawn_backward_open_file = -6;
46 const int pawn_backward_blocked = -9;
47 const int pawn_backward[8] = { -2, -3, -5, -7, -7, -5, -3, -2 };
48 const int pawn_doubled[8] = { -7, -5, -3, -2, -2, -3, -5, -7 }; //counted twice
49 const int pawn_duo[7] = { 2, 3, 4, 5, 4, 3, 2 }; //counted x the row, x2, x3, etc
51 const int queen_value = 975;
52 const int queen_seventh = 9;
53 const int queen_open_file = 7;
54 const int queen_semiopen_file = 5;
56 const int rook_value = 500;
57 const int rook_seventh = 19;
58 const int rook_open_file = 14;
59 const int rook_semiopen_file = 10;
63 const int pawn_value[128] = {
64 0,0,0,0,0,0,0,0,ENDL,
65 -3,0,1,-15,-15,1,0,-3,ENDL,
66 -2,1,3, 7, 7,3,1,-2,ENDL,
67 -1,2,9,16,16,9,2,-1,ENDL,
68 0,4,11,22,22,11,4,0,ENDL,
69 1,6,13,24,24,13,6,1,ENDL,
70 2,8,15,26,26,15,8,2,ENDL,
71 0,0,0,0,0,0,0,0,ENDL
74 const int endgame_king_val[128] = {
75 0, 2, 7, 7, 7, 7, 2, 0, ENDL,
76 2, 11, 19, 19, 19, 19, 11, 2, ENDL,
77 7, 19, 23, 25, 25, 23, 19, 7, ENDL,
78 7, 19, 25, 27, 27, 25, 19, 7, ENDL,
79 7, 19, 25, 27, 27, 25, 19, 7, ENDL,
80 7, 19, 23, 25, 25, 23, 19, 7, ENDL,
81 2, 11, 19, 19, 19, 19, 11, 2, ENDL,
82 0, 2, 7, 7, 7, 7, 2, 0, ENDL
86 const int queen_tropism[8] = { 0, 51, 70, 40, 10, 0, 0, 0};
87 const int rook_tropism[8] = { 0, 3, 2, 1, 0, 0, 0, 0};
88 const int knight_tropism[8] = { 0, 10, 7, 5, 2, 0, 0, 0};
89 const int bishop_tropism[8] = { 0, 3, 3, 2, 1, 0, 0, 0};
90 const int rook_attack_tropism[8] = { 0, 5, 3, 0, 0, 0, 0, 0};
91 const int knight_attack_tropism[8] = { 0, 5, 3, 0, 0, 0, 0, 0};
92 const int bishop_attack_tropism[8] = { 0, 5, 3, 0, 0, 0, 0, 0};
94 const int piece_val[] = { 500, 325, 975, 325, 100, 0 };
96 inline int distance(uint8_t a, uint8_t b)
98 return MAX(ABS(X(a)-X(b)), ABS(Y(a)-Y(b)));
101 int16_t Board::dummy_evaluate()
103 int material[2] = { 0, 0 };
105 int p=0;
106 for(int col=0;col<2;col++)
107 for(int i=0;i<6;i++)
108 material[col] += mat_tracking[p++].count * piece_val[i];
110 return material[IS_WHITE(color_to_move)] -
111 material[IS_WHITE(other_color)];
114 //--------------------------------------------------------------------------
116 const int piece_value[] = { 0, 500, 325, 975, 325, 100, 0 };
118 const int controlled_bonus[128] =
120 3, 3, 3, 3, 3, 3, 3, 3, ENDL,
121 3, 4, 4, 4, 4, 4, 4, 3, ENDL,
122 3, 4, 5, 5, 5, 5, 4, 3, ENDL,
123 3, 4, 5, 5, 5, 5, 4, 3, ENDL,
124 3, 4, 5, 5, 5, 5, 4, 3, ENDL,
125 3, 4, 5, 5, 5, 5, 4, 3, ENDL,
126 3, 4, 4, 4, 4, 4, 4, 3, ENDL,
127 3, 3, 3, 3, 3, 3, 3, 3, ENDL
130 const int bishop_pair = 50;
132 const int bishop_base = 24;
133 const int bishop_middle = 20;
134 const int bishop_end = 20;
135 const uint16_t bishop_attack = (1<<10)+1;
137 const int knight_base = 16;
138 const int knight_middle = 16;
139 const int knight_end = 16;
140 const uint16_t knight_attack = (1<<10)+1;
142 const int rook_base = 28;
143 const int rook_middle = 8;
144 const int rook_end = 16;
145 const uint16_t rook_attack = (1<<10)+1;
147 const int queen_base = 52;
148 const int queen_middle = 4;
149 const int queen_end = 8;
150 const uint16_t queen_attack = (1<<7)+1;
152 const uint16_t pawn_attack = (1<<14)+1;
154 const uint16_t king_attack = (1<<6)+1;
156 int16_t Board::evaluate(uint8_t eng_color, int16_t alpha, int16_t beta)
158 int evaluation[2] = { 0, 0 };
159 int king_danger[2] = { 0, 0 };
160 int tropism[2] = { 0, 0 };
162 int material[2] = {
163 mat_tracking[PAWN-1].count * piece_value[PAWN] +
164 mat_tracking[QUEEN-1].count * piece_value[QUEEN] +
165 mat_tracking[BISHOP-1].count * piece_value[BISHOP] + ((mat_tracking[BISHOP-1].count >= 2) ? bishop_pair : 0) +
166 mat_tracking[ROOK-1].count * (piece_value[ROOK] + (10 - mat_tracking[PAWN-1].count - mat_tracking[PAWN+5].count)*100/16) +
167 mat_tracking[KNIGHT-1].count * (piece_value[KNIGHT] - (10 - mat_tracking[PAWN-1].count - mat_tracking[PAWN+5].count)*100/32),
168 mat_tracking[PAWN+5].count * piece_value[PAWN] +
169 mat_tracking[QUEEN+5].count * piece_value[QUEEN] +
170 mat_tracking[BISHOP+5].count * piece_value[BISHOP] + ((mat_tracking[BISHOP+5].count >= 2) ? bishop_pair : 0) +
171 mat_tracking[ROOK+5].count * (piece_value[ROOK] + (10 - mat_tracking[PAWN-1].count - mat_tracking[PAWN+5].count)*100/16) +
172 mat_tracking[KNIGHT+5].count * (piece_value[KNIGHT] - (10 - mat_tracking[PAWN-1].count - mat_tracking[PAWN+5].count)*100/32)
174 int activity_middle[2] = { 0, 0 };
175 int activity_end[2] = { 0, 0 };
177 union { uint16_t white[128]; struct { uint16_t pad[8]; uint16_t black[120]; }; } attacks_data;
178 uint16_t* attacks[2] = { attacks_data.white, attacks_data.black };
179 memset(attacks_data.white, 0, 128*sizeof(uint16_t));
181 for(int is_white=0;is_white<2;is_white++)
183 int is_black = !is_white;
184 uint8_t color = is_white ? WHITE : BLACK;
185 uint8_t othcol = OTHER_COLOR(color);
186 uint8_t up = up_dir[is_white];
187 uint8_t up_left = up+LEFT;
188 uint8_t up_right = up+RIGHT;
189 uint8_t othpawn = PAWN|othcol;
190 uint8_t mypawn = PAWN|color;
191 int mt = (is_white ? +5 : -1);
194 /* Evaluate bishops */
195 for(int i=mat_tracking[BISHOP+mt].count-1;i>=0;i--)
197 int16_t v = -bishop_base;
198 uint8_t pos = mat_tracking[BISHOP+mt].pos[i];
200 for(int i=3;i>=0;i--)
202 register uint8_t currpos = pos;
203 register uint8_t currinc = bishmoves[i];
205 while(1)
207 currpos += currinc;
209 if(!OUT_OF_BOARD(currpos))
210 attacks[is_white][currpos] += bishop_attack;
212 if(OUT_OF_BOARD(currpos) || COLOR_OF(data[currpos]) == color)
213 break;
215 v += controlled_bonus[currpos];
217 if(data[currpos])
218 break;
221 if(OUT_OF_BOARD(currpos))
222 continue;
225 activity_middle[is_white] += v * bishop_middle;
226 activity_end[is_white] += v * bishop_end;
230 /* Evaluate rooks */
231 for(int i=mat_tracking[ROOK+mt].count-1;i>=0;i--)
233 int16_t v = -rook_base;
234 uint8_t pos = mat_tracking[ROOK+mt].pos[i];
236 for(int i=3;i>=0;i--)
238 register uint8_t currpos = pos;
239 register uint8_t currinc = rookmoves[i];
241 while(1)
243 currpos += currinc;
245 if(!OUT_OF_BOARD(currpos))
246 attacks[is_white][currpos] += rook_attack;
248 if(OUT_OF_BOARD(currpos) || COLOR_OF(data[currpos]) == color)
249 break;
251 v += controlled_bonus[currpos];
253 if(data[currpos])
254 break;
257 if(OUT_OF_BOARD(currpos))
258 continue;
261 activity_middle[is_white] += v * rook_middle;
262 activity_end[is_white] += v * rook_end;
266 /* Evaluate queens */
267 for(int i=mat_tracking[QUEEN+mt].count-1;i>=0;i--)
269 int16_t v = -queen_base;
270 uint8_t pos = mat_tracking[QUEEN+mt].pos[i];
272 for(int i=7;i>=0;i--)
274 register uint8_t currpos = pos;
275 register uint8_t currinc = kingmoves[i];
277 while(1)
279 currpos += currinc;
281 if(!OUT_OF_BOARD(currpos))
282 attacks[is_white][currpos] += queen_attack;
284 if(OUT_OF_BOARD(currpos) || COLOR_OF(data[currpos]) == color)
285 break;
287 v += controlled_bonus[currpos];
289 if(data[currpos])
290 break;
293 if(OUT_OF_BOARD(currpos))
294 continue;
297 activity_middle[is_white] += v * queen_middle;
298 activity_end[is_white] += v * queen_end;
302 /* Evaluate knights */
303 for(int i=mat_tracking[KNIGHT+mt].count-1;i>=0;i--)
305 int16_t v = -knight_base;
306 uint8_t pos = mat_tracking[KNIGHT+mt].pos[i];
307 KnightMove* hm = &knightmoves[pos];
309 for(int i=hm->numm;i>=0;i--)
311 register uint8_t currpos = hm->jump[i];
313 attacks[is_white][currpos] += knight_attack;
315 if(IS_OF_COLOR(data[currpos], color))
316 continue;
318 v += controlled_bonus[currpos];
321 activity_middle[is_white] += v * knight_middle;
322 activity_end[is_white] += v * knight_end;
325 for(int i=mat_tracking[PAWN+mt].count-1;i>=0;i--)
327 uint8_t pos = mat_tracking[PAWN+mt].pos[i];
328 int x = X(pos);
330 if(x<7)
331 attacks[is_white][I(pos+up_right)] += pawn_attack;
332 if(x>0)
333 attacks[is_white][I(pos+up_left)] += pawn_attack;
336 for(int i=mat_tracking[KING+mt].count-1;i>=0;i--)
338 uint8_t pos = mat_tracking[KING+mt].pos[i];
340 for(int i=7;i>=0;i--)
342 register uint8_t currpos = pos + kingmoves[i];
343 if(!OUT_OF_BOARD(currpos))
344 attacks[is_white][currpos] += king_attack;
349 #if 0
350 for(int y=7;y>=0;y--)
352 for(int is_white = 0;is_white<2;is_white++)
354 for(int x=0;x<8;x++)
355 printf(" % 4x", attacks[is_white][POS_XY(x,y)]);
356 printf("%s", is_white ? "\n" : " ");
359 #endif
361 int loss[2][2] = { { 0, 0 }, { 0, 0 } };
362 int loss_soft[2][2] = { { 0, 0 }, { 0, 0 } };
363 int attackings[2] = { 0, 0 };
364 #if 1
366 #define UPDATE_LOSS(_x) ({int x = (_x); \
367 if(x >= loss[is_white][0]) { loss[is_white][1] = loss[is_white][0]; loss[is_white][0] = x; } \
368 else if(x > loss[is_white][1]) { loss[is_white][1] = x; } })
369 #define UPDATE_LOSS_SOFT(_x) ({int x = (_x); \
370 if(x >= loss_soft[is_white][0]) { loss_soft[is_white][1] = loss_soft[is_white][0]; loss_soft[is_white][0] = x; } \
371 else if(x > loss_soft[is_white][1]) { loss_soft[is_white][1] = x; } })
372 #define BC(_x) ({int x = _x, c; for(c=0; x; c++, x &= x-1); c; })
373 #define N(x) ((x) & 0x1f)
375 for(int is_white=0; is_white<2; is_white++)
377 int on_move = IS_WHITE(color_to_move) == is_white;
378 int is_black = !is_white;
379 int mt = (is_white ? +5 : -1);
381 int malus1 = on_move ? -32 : -39;
382 int malus2 = on_move ? -10 : -13;
383 int bonus1 = +5;
385 int malus = on_move ? -20 : -35;
387 /* Evaluate knights */
388 for(int i=mat_tracking[KNIGHT+mt].count-1;i>=0;i--)
390 uint8_t pos = mat_tracking[KNIGHT+mt].pos[i];
391 if(attacks[is_black][pos] >= pawn_attack)
392 UPDATE_LOSS(attacks[is_white][pos]>=attacks[is_black][pos] ? 270 : 325);
393 else if(!attacks[is_white][pos] && attacks[is_black][pos])
394 UPDATE_LOSS_SOFT(325);
395 else if(attacks[is_black][pos] > attacks[is_white][pos] + bishop_attack)
396 UPDATE_LOSS_SOFT(325);
397 else if(attacks[is_black][pos] && attacks[is_black][pos] >= attacks[is_white][pos])
398 attackings[is_white] += malus;
401 /* Evaluate bishops */
402 for(int i=mat_tracking[BISHOP+mt].count-1;i>=0;i--)
404 uint8_t pos = mat_tracking[BISHOP+mt].pos[i];
405 if(attacks[is_black][pos] >= pawn_attack)
406 UPDATE_LOSS(attacks[is_white][pos]>=attacks[is_black][pos] ? 270 : 325);
407 else if(!attacks[is_white][pos] && attacks[is_black][pos])
408 UPDATE_LOSS_SOFT(325);
409 else if(attacks[is_black][pos] > attacks[is_white][pos] + bishop_attack)
410 UPDATE_LOSS_SOFT(325);
411 else if(attacks[is_black][pos] && attacks[is_black][pos] >= attacks[is_white][pos])
412 attackings[is_white] += malus;
415 /* Evaluate rooks */
416 for(int i=mat_tracking[ROOK+mt].count-1;i>=0;i--)
418 uint8_t pos = mat_tracking[ROOK+mt].pos[i];
419 if(attacks[is_black][pos] >= pawn_attack)
420 UPDATE_LOSS(attacks[is_white][pos]>=attacks[is_black][pos] ? 430 : 500);
421 else if(!attacks[is_white][pos] && attacks[is_black][pos])
422 UPDATE_LOSS_SOFT(500);
423 else if(attacks[is_black][pos] > attacks[is_white][pos] + bishop_attack)
424 UPDATE_LOSS_SOFT(400);
425 else if(attacks[is_black][pos] && attacks[is_black][pos] >= attacks[is_white][pos])
426 attackings[is_white] += malus;
429 /* Evaluate QUEEN */
430 for(int i=mat_tracking[QUEEN+mt].count-1;i>=0;i--)
432 uint8_t pos = mat_tracking[QUEEN+mt].pos[i];
433 if(attacks[is_black][pos] >= pawn_attack)
434 UPDATE_LOSS(attacks[is_white][pos]>=attacks[is_black][pos] ? 830 : 900);
435 else if(!attacks[is_white][pos] && attacks[is_black][pos])
436 UPDATE_LOSS_SOFT(1000);
437 else if(attacks[is_black][pos] > attacks[is_white][pos] + bishop_attack)
438 UPDATE_LOSS_SOFT(600);
439 else if(attacks[is_black][pos] && attacks[is_black][pos] >= attacks[is_white][pos])
440 attackings[is_white] += malus;
443 for(int i=mat_tracking[PAWN+mt].count-1;i>=0;i--)
445 uint8_t pos = mat_tracking[PAWN+mt].pos[i];
446 if(N(attacks[is_black][pos]) > N(attacks[is_white][pos])
447 && attacks[is_black][pos] > attacks[is_white][pos]*3/4)
448 UPDATE_LOSS_SOFT(100);
449 else if(attacks[is_black][pos] && attacks[is_black][pos] >= attacks[is_white][pos])
450 attackings[is_white] += malus;
453 #endif
455 #if 0
456 #define N(x) ((x) & 0x1f)
457 int attackings[2] = { 0, 0 };
459 for(int is_white=0; is_white<2; is_white++)
461 int on_move = IS_WHITE(color_to_move) == is_white;
462 int is_black = !is_white;
463 int mt = (is_white ? +5 : -1);
465 /* Evaluate bishops */
466 for(int i=mat_tracking[BISHOP+mt].count-1;i>=0;i--)
468 uint8_t pos = mat_tracking[BISHOP+mt].pos[i];
469 if(attacks[is_black][pos] && !attacks[is_white][pos])
470 attackings[is_white] += on_move ? -20 : -200;
471 else if(attacks[is_black][pos] >= pawn_attack || attacks[is_black][pos] > attacks[is_white][pos] + bishop_attack)
472 attackings[is_white] += on_move ? -20 : -200;
473 else if(N(attacks[is_black][pos]) >= N(attacks[is_white][pos]) && attacks[is_black][pos] >= attacks[is_white][pos])
474 //else if(attacks[is_black][pos] >= attacks[is_white][pos])
475 attackings[is_white] += -10;
478 /* Evaluate rooks */
479 for(int i=mat_tracking[ROOK+mt].count-1;i>=0;i--)
481 uint8_t pos = mat_tracking[ROOK+mt].pos[i];
482 if(attacks[is_black][pos] && !attacks[is_white][pos])
483 attackings[is_white] += on_move ? -25 : -300;
484 else if(attacks[is_black][pos] >= pawn_attack || attacks[is_black][pos] > attacks[is_white][pos] + bishop_attack)
485 attackings[is_white] += on_move ? -25 : -300;
486 else if(N(attacks[is_black][pos]) >= N(attacks[is_white][pos]) && attacks[is_black][pos] >= attacks[is_white][pos])
487 //else if(attacks[is_black][pos] >= attacks[is_white][pos])
488 attackings[is_white] += -10;
491 /* Evaluate queens */
492 for(int i=mat_tracking[QUEEN+mt].count-1;i>=0;i--)
494 uint8_t pos = mat_tracking[QUEEN+mt].pos[i];
495 if(attacks[is_black][pos] && !attacks[is_white][pos])
496 attackings[is_white] += on_move ? -40 : -600;
497 else if(attacks[is_black][pos] >= bishop_attack)
498 attackings[is_white] += on_move ? -40 : (attacks[is_black][pos] >= pawn_attack ? -600 : -400);
501 /* Evaluate knights */
502 for(int i=mat_tracking[KNIGHT+mt].count-1;i>=0;i--)
504 uint8_t pos = mat_tracking[KNIGHT+mt].pos[i];
505 if(attacks[is_black][pos] && !attacks[is_white][pos])
506 attackings[is_white] += on_move ? -20 : -200;
507 else if(attacks[is_black][pos] >= pawn_attack || attacks[is_black][pos] > attacks[is_white][pos] + bishop_attack)
508 attackings[is_white] += on_move ? -20 : -200;
509 else if(N(attacks[is_black][pos]) >= N(attacks[is_white][pos]) && attacks[is_black][pos] >= attacks[is_white][pos])
510 //else if(attacks[is_black][pos] >= attacks[is_white][pos])
511 attackings[is_white] += -10;
514 for(int i=mat_tracking[PAWN+mt].count-1;i>=0;i--)
516 uint8_t pos = mat_tracking[PAWN+mt].pos[i];
517 if(attacks[is_black][pos] >= attacks[is_white][pos])
519 if(N(attacks[is_black][pos]) > N(attacks[is_white][pos]))
520 attackings[is_white] += on_move ? -25 : -60;
521 else if(N(attacks[is_black][pos]) == N(attacks[is_white][pos]))
522 attackings[is_white] += -5;
526 #endif
528 for(int c = 0;c<2;c++)
530 int on_move = c == IS_WHITE(color_to_move);
531 attackings[c] -= !on_move ? MAX(loss[c][0]*4/8, loss_soft[c][0]*4/8) :
532 MAX(loss[c][1]*3/8, MAX(loss_soft[c][1]*2/8, MIN(loss[c][0]*3/8, loss_soft[c][0]*2/8) ) );
535 int tot_mat = material[0] + material[1];
536 int max_mat = 100*16 + 325*8 + 500*4 + 975*2;
537 int eval[2] = {
538 material[0] + (activity_middle[0]*tot_mat + activity_end[0]*(max_mat-tot_mat))/(16 * max_mat),
539 material[1] + (activity_middle[1]*tot_mat + activity_end[1]*(max_mat-tot_mat))/(16 * max_mat)
542 return 7 + eval[IS_WHITE(color_to_move)] - eval[IS_WHITE(other_color)]
543 + attackings[IS_WHITE(color_to_move)] - attackings[IS_WHITE(other_color)];
546 #if 0
547 /* Evaluate pawns */
548 bool p = false;
549 for(int x=0;x<8;x++)
551 bool nextp = !!line_pawns[is_white][x].count;
552 if(nextp && !p)
553 evaluation[is_white] += pawn_insula;
554 p = nextp;
557 for(int i=mat_tracking[PAWN+mt].count-1;i>=0;i--)
559 int16_t v = 0;
560 uint8_t pos = mat_tracking[PAWN+mt].pos[i];
561 uint8_t x = X(pos);
562 uint8_t y = is_white ? Y(pos) : 7-Y(pos);
564 v += (100 + pawn_value[POS_XY(x,y)]);
566 /* isulated pawn malus */
567 #if 0
568 if( (x == 0 || line_pawns[is_white][x-1].count == 0) &&
569 (x == 7 || line_pawns[is_white][x+1].count == 0) )
571 v += pawn_isulated;
572 if(COLOR_OF(data[uint8_t(up+pos)]) == othcol)
573 v += pawn_isulated_blocked;
575 #endif
577 /* backward pawn malus */
578 if( (x == 0 || line_pawns[is_white][x-1].count == 0
579 || line_pawns[is_white][x-1].pos[0] > y) &&
580 (x == 7 || line_pawns[is_white][x+1].count == 0
581 || line_pawns[is_white][x+1].pos[0] > y) )
583 v += pawn_backward[x];
584 if(!line_pawns[!is_white][x].count)
585 v += pawn_backward_open_file;
586 if(data[I(up+pos)])
587 v += pawn_backward_blocked;
590 if(x!=0 && data[LEFT_OF(pos)]==data[pos])
591 v += pawn_duo[x]*(y+2)/2;
592 if(x!=0 && (data[LEFTUP_OF(pos)]==data[pos] ||
593 data[LEFTDOWN_OF(pos)]==data[pos]))
594 v += pawn_chain;
596 /* passed pawn */
597 if( (x==0||!line_pawns[1-is_white][x-1].count ||
598 line_pawns[1-is_white][x-1].pos[0]>=7-y) &&
599 (x==7||!line_pawns[1-is_white][x+1].count ||
600 line_pawns[1-is_white][x+1].pos[0]>=7-y) &&
601 (!line_pawns[1-is_white][x].count||line_pawns[1-is_white][x].pos[0]>7-y) )
603 if(COLOR_OF(up_dir[is_white]+pos) == othcol)
604 v += MAX(y-2,1)*BLOCKED_PASSER;
605 else
606 v += MAX(y-2,1)*PASSED_PAWN;
609 /* doubled pawns */
610 if(line_pawns[is_white][x].count > 1)
611 v += pawn_doubled[x];
613 evaluation[is_white] += v;
616 /* Evaluate king */
617 for(int i=mat_tracking[KING+mt].count-1;i>=0;i--)
619 int16_t v = 0;
620 uint8_t pos = mat_tracking[KING+mt].pos[i];
621 uint8_t x = X(pos);
622 uint8_t y = is_white ? Y(pos) : 7-Y(pos);
624 if( is_white ? !(castle_passing_mask & 0x30) :
625 !(castle_passing_mask & 0xc0) )
627 if(material[!is_white]>=1500)
629 v += king_safety[pos];
630 if((x>=5 || x<=2) && y<=1)
632 uint8_t f = x<=2 ? 2 : 5;
633 uint8_t g = x<=2 ? 1 : 6;
634 uint8_t h = x<=2 ? 0 : 7;
635 uint8_t fpawn = line_pawns[is_white][f].count ? line_pawns[is_white][f].pos[0] : 255;
636 uint8_t gpawn = line_pawns[is_white][g].count ? line_pawns[is_white][g].pos[0] : 255;
637 uint8_t hpawn = line_pawns[is_white][h].count ? line_pawns[is_white][h].pos[0] : 255;
639 if(fpawn >= 3)
640 v += -12;
641 else
642 v += -4;
643 if(gpawn >= 3)
644 v += -15;
645 else
646 v += -8;
647 if(hpawn >= 3)
648 v += -13;
649 else
650 v += -6;
651 if(fpawn==1 && gpawn>=2 && hpawn==1)
653 uint8_t start = POS_XY(x<=2 ? 1 : 6, is_white?1:6);
654 uint8_t defbish = color | BISHOP;
655 if(data[start] == defbish || data[RIGHTUP_OF(start)] == defbish ||
656 data[LEFTUP_OF(start)] == defbish || data[RIGHTDOWN_OF(start)] == defbish ||
657 data[LEFTDOWN_OF(start)] == defbish)
658 v += 5;
659 else
660 v += -13;
662 if(!line_pawns[is_white][f].count)
663 v += -10;
664 if(!line_pawns[is_white][g].count)
665 v += -16;
666 if(!line_pawns[is_white][h].count)
667 v += -16;
668 if(data[POS_XY(h, is_white?0:7)] == (color | ROOK) ||
669 data[POS_XY(h, is_white?1:6)] == (color | ROOK) )
670 v += -80;
672 else if((x<5 && x>2) && y<=1)
674 if(!line_pawns[is_white][x].count)
675 v += -26;
676 if(!line_pawns[is_white][7-x].count)
677 v += -16;
680 v = v * (MIN(material[!is_white], 2400)-1500)/900;
681 king_danger[is_white] = v;
683 if(material[!is_white]<2400)
684 v += endgame_king_val[pos] * (2400 - MAX(material[!is_white], 1500) )/900;
686 else
687 v += king_still_to_castle;
689 evaluation[is_white] += v;
694 evaluation[0] += (1500*(evaluation[0]-evaluation[1]))/
695 (2000+material[0]+material[1]);
696 evaluation[0] += tropism[0] * 200 / MAX(200 + king_danger[1], 50);
697 evaluation[1] += tropism[1] * 200 / MAX(200 + king_danger[0], 50);
699 int16_t retv = 7 + evaluation[IS_WHITE(color_to_move)] -
700 evaluation[IS_WHITE(other_color)];
702 // if(mat_tracking[PAWN-1].count + mat_tracking[PAWN+5].count >= 15)
703 // retv += color_to_move == eng_color ? -15 : 15;
704 // else if(mat_tracking[PAWN-1].count + mat_tracking[PAWN+5].count >= 15)
705 // retv += color_to_move == eng_color ? -8 : 8;
707 return retv;
709 #endif