1 /***************************************************************************
2 evaluate.cpp - description
4 begin : Wed Mar 13 2002
5 copyright : (C) 2002-2005 by Maurizio Monge
6 email : monge@linuz.sns.it
7 ***************************************************************************/
9 /***************************************************************************
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. *
16 ***************************************************************************/
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] = {
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
,
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 };
106 for(int col
=0;col
<2;col
++)
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 };
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
];
209 if(!OUT_OF_BOARD(currpos
))
210 attacks
[is_white
][currpos
] += bishop_attack
;
212 if(OUT_OF_BOARD(currpos
) || COLOR_OF(data
[currpos
]) == color
)
215 v
+= controlled_bonus
[currpos
];
221 if(OUT_OF_BOARD(currpos
))
225 activity_middle
[is_white
] += v
* bishop_middle
;
226 activity_end
[is_white
] += v
* bishop_end
;
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
];
245 if(!OUT_OF_BOARD(currpos
))
246 attacks
[is_white
][currpos
] += rook_attack
;
248 if(OUT_OF_BOARD(currpos
) || COLOR_OF(data
[currpos
]) == color
)
251 v
+= controlled_bonus
[currpos
];
257 if(OUT_OF_BOARD(currpos
))
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
];
281 if(!OUT_OF_BOARD(currpos
))
282 attacks
[is_white
][currpos
] += queen_attack
;
284 if(OUT_OF_BOARD(currpos
) || COLOR_OF(data
[currpos
]) == color
)
287 v
+= controlled_bonus
[currpos
];
293 if(OUT_OF_BOARD(currpos
))
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
))
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
];
331 attacks
[is_white
][I(pos
+up_right
)] += pawn_attack
;
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
;
350 for(int y
=7;y
>=0;y
--)
352 for(int is_white
= 0;is_white
<2;is_white
++)
355 printf(" % 4x", attacks
[is_white
][POS_XY(x
,y
)]);
356 printf("%s", is_white
? "\n" : " ");
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 };
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;
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
;
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
;
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
;
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;
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;
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;
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
)];
551 bool nextp
= !!line_pawns
[is_white
][x
].count
;
553 evaluation
[is_white
] += pawn_insula
;
557 for(int i
=mat_tracking
[PAWN
+mt
].count
-1;i
>=0;i
--)
560 uint8_t pos
= mat_tracking
[PAWN
+mt
].pos
[i
];
562 uint8_t y
= is_white
? Y(pos
) : 7-Y(pos
);
564 v
+= (100 + pawn_value
[POS_XY(x
,y
)]);
566 /* isulated pawn malus */
568 if( (x
== 0 || line_pawns
[is_white
][x
-1].count
== 0) &&
569 (x
== 7 || line_pawns
[is_white
][x
+1].count
== 0) )
572 if(COLOR_OF(data
[uint8_t(up
+pos
)]) == othcol
)
573 v
+= pawn_isulated_blocked
;
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
;
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
]))
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
;
606 v
+= MAX(y
-2,1)*PASSED_PAWN
;
610 if(line_pawns
[is_white
][x
].count
> 1)
611 v
+= pawn_doubled
[x
];
613 evaluation
[is_white
] += v
;
617 for(int i
=mat_tracking
[KING
+mt
].count
-1;i
>=0;i
--)
620 uint8_t pos
= mat_tracking
[KING
+mt
].pos
[i
];
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;
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
)
662 if(!line_pawns
[is_white
][f
].count
)
664 if(!line_pawns
[is_white
][g
].count
)
666 if(!line_pawns
[is_white
][h
].count
)
668 if(data
[POS_XY(h
, is_white
?0:7)] == (color
| ROOK
) ||
669 data
[POS_XY(h
, is_white
?1:6)] == (color
| ROOK
) )
672 else if((x
<5 && x
>2) && y
<=1)
674 if(!line_pawns
[is_white
][x
].count
)
676 if(!line_pawns
[is_white
][7-x
].count
)
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;
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;