1 /*
2 Sjeng - a chess variants playing program
3 Copyright (C) 2000 Gian-Carlo Pascutto
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 File: neval.c
20 Purpose: functions for evaluating positions (standard chess)
21
22 */
23
24 #include "sjeng.h"
25 #include "extvars.h"
26 #include "protos.h"
27 #include "squares.h"
28
29 /* these tables will be used for positional bonuses: */
30
31 static int sbishop[144] = {
32 0,0,0,0,0,0,0,0,0,0,0,0,
33 0,0,0,0,0,0,0,0,0,0,0,0,
34 0,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0,
35 0,0,-2,8,5,5,5,5,8,-2,0,0,
36 0,0,-2,3,3,5,5,3,3,-2,0,0,
37 0,0,-2,2,5,4,4,5,2,-2,0,0,
38 0,0,-2,2,5,4,4,5,2,-2,0,0,
39 0,0,-2,3,3,5,5,3,3,-2,0,0,
40 0,0,-2,8,5,5,5,5,8,-2,0,0,
41 0,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0,
42 0,0,0,0,0,0,0,0,0,0,0,0,
43 0,0,0,0,0,0,0,0,0,0,0,0};
44
45 static int sknight[144] = {
46 0,0,0,0,0,0,0,0,0,0,0,0,
47 0,0,0,0,0,0,0,0,0,0,0,0,
48 0,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0,
49 0,0,-10,0,0,3,3,0,0,-10,0,0,
50 0,0,-10,0,5,5,5,5,0,-10,0,0,
51 0,0,-10,0,5,10,10,5,0,-10,0,0,
52 0,0,-10,0,5,10,10,5,0,-10,0,0,
53 0,0,-10,0,5,5,5,5,0,-10,0,0,
54 0,0,-10,0,0,3,3,0,0,-10,0,0,
55 0,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0,
56 0,0,0,0,0,0,0,0,0,0,0,0,
57 0,0,0,0,0,0,0,0,0,0,0,0};
58
59 static long int swhite_pawn[144] = {
60 0,0,0,0,0,0,0,0,0,0,0,0,
61 0,0,0,0,0,0,0,0,0,0,0,0,
62 0,0,0,0,0,0,0,0,0,0,0,0,
63 0,0,0,0,0,0,0,0,0,0,0,0,
64 0,0,1,2,3,10,10,3,2,1,0,0,
65 0,0,2,4,6,12,12,6,4,2,0,0,
66 0,0,3,6,9,14,14,9,6,3,0,0,
67 0,0,4,8,12,16,16,12,8,4,0,0,
68 0,0,5,10,15,20,20,15,10,5,0,0,
69 0,0,0,0,0,0,0,0,0,0,0,0,
70 0,0,0,0,0,0,0,0,0,0,0,0,
71 0,0,0,0,0,0,0,0,0,0,0,0};
72
73 static int sblack_pawn[144] = {
74 0,0,0,0,0,0,0,0,0,0,0,0,
75 0,0,0,0,0,0,0,0,0,0,0,0,
76 0,0,0,0,0,0,0,0,0,0,0,0,
77 0,0,5,10,15,20,20,15,10,5,0,0,
78 0,0,4,8,12,16,16,12,8,4,0,0,
79 0,0,3,6,9,14,14,9,6,3,0,0,
80 0,0,2,4,6,12,12,6,4,2,0,0,
81 0,0,1,2,3,10,10,3,2,1,0,0,
82 0,0,0,0,0,0,0,0,0,0,0,0,
83 0,0,0,0,0,0,0,0,0,0,0,0,
84 0,0,0,0,0,0,0,0,0,0,0,0,
85 0,0,0,0,0,0,0,0,0,0,0,0};
86
87 /* to be used during opening and middlegame for white king positioning: */
88 static int swhite_king[144] = {
89 0,0,0,0,0,0,0,0,0,0,0,0,
90 0,0,0,0,0,0,0,0,0,0,0,0,
91 0,0,2,14,0,0,0,9,14,2,0,0,
92 0,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0,
93 0,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0,
94 0,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0,
95 0,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0,
96 0,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0,
97 0,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0,
98 0,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0,
99 0,0,0,0,0,0,0,0,0,0,0,0,
100 0,0,0,0,0,0,0,0,0,0,0,0};
101
102 /* to be used during opening and middlegame for black king positioning: */
103 static int sblack_king[144] = {
104 0,0,0,0,0,0,0,0,0,0,0,0,
105 0,0,0,0,0,0,0,0,0,0,0,0,
106 0,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0,
107 0,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0,
108 0,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0,
109 0,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0,
110 0,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0,
111 0,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0,
112 0,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0,
113 0,0,2,14,0,0,0,9,14,2,0,0,
114 0,0,0,0,0,0,0,0,0,0,0,0,
115 0,0,0,0,0,0,0,0,0,0,0,0};
116
117 /* to be used for positioning of both kings during the endgame: */
118 static int send_king[144] = {
119 0,0,0,0,0,0,0,0,0,0,0,0,
120 0,0,0,0,0,0,0,0,0,0,0,0,
121 0,0,-5,-3,-1,0,0,-1,-3,-5,0,0,
122 0,0,-3,10,10,10,10,10,10,-3,0,0,
123 0,0,-1,10,25,25,25,25,10,-1,0,0,
124 0,0,0,10,25,30,30,25,10,0,0,0,
125 0,0,0,10,25,30,30,25,10,0,0,0,
126 0,0,-1,10,25,25,25,25,10,-1,0,0,
127 0,0,-3,10,10,10,10,10,10,-3,0,0,
128 0,0,-5,-3,-1,0,0,-1,-3,-5,0,0,
129 0,0,0,0,0,0,0,0,0,0,0,0,
130 0,0,0,0,0,0,0,0,0,0,0,0};
131
132 /* utility array to reverse rank: */
133 static int srev_rank[9] = {
134 0,8,7,6,5,4,3,2,1};
135
136 const int std_p_tropism[9] =
137 { 9999, 15, 10, 7, 2, 0, 0, 0, 9999};
138
139 const int std_r_tropism[9] =
140 { 9999, 10, 6, 4, 2, 0, 0, 0, 9999};
141
142 const int std_n_tropism[9] =
143 { 9999, 14, 9, 6, 1, 0, 0, 0, 9999};
144
145 const int std_q_tropism[9] =
146 { 9999, 16, 12, 7, 2, 0, 0, 0, 9999};
147
148 const int std_b_tropism[9] =
149 { 9999, 12, 7, 5, 0, 0, 0, 0, 9999};
150
151
bishop_mobility(int square)152 static int bishop_mobility(int square)
153 {
154 register int l;
155 register int m = 0;
156
157 for (l = square-13; board[l] == npiece; l-=13)
158 m++;
159 for (l = square-11; board[l] == npiece; l-=11)
160 m++;
161 for (l = square+11; board[l] == npiece; l+=11)
162 m++;
163 for (l = square+13; board[l] == npiece; l+=13)
164 m++;
165
166 return m;
167 }
168
end_eval(void)169 long int end_eval (void) {
170
171 /* return a score for the current endgame position: */
172
173 int i, a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11],
174 srank, j;
175 long int score = 0;
176 bool isolated, backwards;
177 int in_cache;
178 int wp = 0, bp = 0, wn = 0, bn = 0, wb = 0, bb = 0,
179 wq = 0, bq = 0, wr = 0, br = 0;
180 int fwrook, fbrook, rwrook, rbrook;
181 int wpotential = 0, bpotential = 0, tmp;
182
183 in_cache = 0;
184
185 checkECache(&score, &in_cache);
186
187 if(in_cache)
188 {
189 if (white_to_move == 1) return score;
190 return -score;
191 }
192
193
194 /* initialize the pawns array, (files offset by one to use dummy files in
195 order to easier determine isolated status) and also initialize the
196 arrays keeping track of the rank of the most backward pawn: */
197 memset (pawns, 0, sizeof (pawns));
198 for (i = 0; i < 11; i++) {
199 white_back_pawn[i] = 7;
200 black_back_pawn[i] = 2;
201 }
202 for (j = 1, a = 1; (a <= piece_count); j++) {
203 i = pieces[j];
204
205 if (!i)
206 continue;
207 else
208 a++;
209
210 assert((i > 0) && (i < 145));
211
212 pawn_file = file (i)+1;
213 srank = rank (i);
214 if (board[i] == wpawn) {
215 pawns[1][pawn_file]++;
216 if (srank < white_back_pawn[pawn_file]) {
217 white_back_pawn[pawn_file] = srank;
218 }
219 }
220 else if (board[i] == bpawn) {
221 pawns[0][pawn_file]++;
222 if (srank > black_back_pawn[pawn_file]) {
223 black_back_pawn[pawn_file] = srank;
224 }
225 }
226 }
227
228 /* loop through the board, adding material value, as well as positional
229 bonuses for all pieces encountered: */
230 for (j = 1, a = 1; (a <= piece_count); j++) {
231 i = pieces[j];
232
233 if (!i)
234 continue;
235 else
236 a++;
237
238 pawn_file = file (i)+1;
239 srank = rank (i);
240 switch (board[i]) {
241 case (wpawn):
242 isolated = FALSE;
243 backwards = FALSE;
244 score += 100;
245 score += swhite_pawn[i];
246 wp++;
247
248 /* in general, bonuses/penalties in the endgame evaluation will be
249 higher, since pawn structure becomes more important for the
250 creation of passed pawns */
251
252 /* check for backwards pawns: */
253 if (white_back_pawn[pawn_file+1] > srank
254 && white_back_pawn[pawn_file-1] > srank) {
255 score -= 8;
256 backwards = TRUE;
257 /* check to see if it is furthermore isolated: */
258 if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) {
259 score -= 5;
260 isolated = TRUE;
261 }
262 }
263
264 /* give weak, exposed pawns a penalty (not as much as in the midgame,
265 since there may be no pieces to take advantage of it): */
266 if (!pawns[0][pawn_file]) {
267 if (backwards) score -= 3;
268 if (isolated) score -= 5;
269 }
270
271 /* give doubled, trippled, etc.. pawns a penalty (bigger in the
272 endgame, since they will become big targets): */
273 if (pawns[1][pawn_file] > 1)
274 score -= 3*(pawns[1][pawn_file]-1);
275
276 /* give bonuses for passed pawns (bigger in the endgame since passed
277 pawns are what wins the endgame): */
278 if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] &&
279 srank >= black_back_pawn[pawn_file+1]) {
280 score += 30 + 3*swhite_pawn[i];
281
282 if (white_to_move)
283 {
284 /* check queening race */
285 /* tmp = queening square */
286 tmp = A8 + file(i) - 1;
287 /* king is away how much ?*/
288 if (max(abs(file(bking_loc)-file(tmp)), abs(rank(bking_loc)-rank(tmp)))
289 > (abs(rank(tmp) - rank(i))))
290 {
291 wpotential += 800;
292 }
293 }
294 else
295 {
296 /* check queening race */
297 /* tmp = queening square */
298 tmp = A8 + file(i) - 1;
299 /* king is away how much ?*/
300 if ((max(abs(file(bking_loc)-file(tmp)), abs(rank(bking_loc)-rank(tmp)))-1)
301 > (abs(rank(tmp) - rank(i))))
302 {
303 wpotential += 800;
304 }
305 }
306
307 /* outside passer ? */
308 if (file(i) == 1 || file(i) == 8)
309 score += 12 + 2*swhite_pawn[i];
310
311 /* give an extra bonus if a connected, passed pawn: */
312 if (!isolated)
313 {
314 score += 12;
315
316 /* check whether supporter is passed */
317 if (pawns[1][pawn_file+1])
318 {
319 if (!pawns[0][pawn_file+1]
320 && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file+2])
321 {
322 score += 7*rank(i);
323
324 /* connected on seventh ? */
325 if (rank(i) == 7 && white_back_pawn[pawn_file+1] >= 6)
326 {
327 score += 50;
328 }
329 }
330 }
331 if (pawns[1][pawn_file-1])
332 {
333 if (!pawns[0][pawn_file-1]
334 && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file-2])
335 {
336 score += 7*rank(i);
337
338 /* connected on seventh ? */
339 if (rank(i) == 7 && white_back_pawn[pawn_file-1] >= 6)
340 {
341 score += 50;
342 }
343 }
344 }
345 }
346 }
347
348 if (!pawns[1][pawn_file-1])
349 score -= 7;
350
351 break;
352
353 case (bpawn):
354 isolated = FALSE;
355 backwards = FALSE;
356 score -= 100;
357 score -= sblack_pawn[i];
358 bp++;
359
360 /* in general, bonuses/penalties in the endgame evaluation will be
361 higher, since pawn structure becomes more important for the
362 creation of passed pawns */
363
364 /* check for backwards pawns: */
365 if (black_back_pawn[pawn_file+1] < srank
366 && black_back_pawn[pawn_file-1] < srank) {
367 score += 8;
368 backwards = TRUE;
369 /* check to see if it is furthermore isolated: */
370 if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) {
371 score += 5;
372 isolated = TRUE;
373 }
374 }
375
376 /* give weak, exposed pawns a penalty (not as much as in the midgame,
377 since there may be no pieces to take advantage of it): */
378 if (!pawns[1][pawn_file]) {
379 if (backwards) score += 3;
380 if (isolated) score += 5;
381 }
382
383 /* give doubled, trippled, etc.. pawns a penalty (bigger in the
384 endgame, since they will become big targets): */
385 if (pawns[0][pawn_file] > 1)
386 score += 3*(pawns[0][pawn_file]-1);
387
388 /* give bonuses for passed pawns (bigger in the endgame since passed
389 pawns are what wins the endgame): */
390 if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] &&
391 srank <= white_back_pawn[pawn_file+1]) {
392 score -= 30 + 3*sblack_pawn[i];
393
394 if (!white_to_move)
395 {
396 /* check queening race */
397 /* tmp = queening square */
398 tmp = A1 + file(i) - 1;
399 /* king is away how much ?*/
400 if (max(abs(file(wking_loc)-file(tmp)), abs(rank(wking_loc)-rank(tmp)))
401 > (abs(rank(tmp) - (rank(i)))))
402 {
403 bpotential -= 800;
404 }
405 }
406 else
407 {
408 /* check queening race */
409 /* tmp = queening square */
410 tmp = A1 + file(i) - 1;
411 /* king is away how much ?*/
412 if ((max(abs(file(wking_loc)-file(tmp)), abs(rank(wking_loc)-rank(tmp)))-1)
413 > abs((rank(tmp) - rank(i))))
414 {
415 bpotential -= 800;
416 }
417 }
418
419 /* outside passer ? */
420 if (file(i) == 1 || file(i) == 8)
421 score -= 12 + 2*sblack_pawn[i];
422
423 /* give an extra bonus if a connected, passed pawn: */
424 if (!isolated)
425 {
426 score -= 12;
427
428 /* check whether supporter is passed */
429 if (pawns[0][pawn_file+1])
430 {
431 if (!pawns[1][pawn_file+1]
432 && black_back_pawn[pawn_file+1] <= white_back_pawn[pawn_file+2])
433 {
434 score -= 7*(9-rank(i));
435
436 /* on seventh and supported ? */
437 if (rank(i) == 2 && black_back_pawn[pawn_file+1] <= 3)
438 {
439 score -= 50;
440 }
441 }
442 }
443 if (pawns[0][pawn_file-1])
444 {
445 if (!pawns[1][pawn_file-1]
446 && black_back_pawn[pawn_file-1] <= white_back_pawn[pawn_file-2])
447 {
448 score -= 7*(9-rank(i));
449
450 /* connected on seventh ? */
451 if (rank(i) == 2 && black_back_pawn[pawn_file-1] <= 3)
452 {
453 score -= 50;
454 }
455
456 }
457 }
458 }
459 }
460
461 if (!pawns[0][pawn_file-1])
462 score += 7;
463
464 break;
465
466 case (wrook):
467 score += 500;
468 wr++;
469
470 if (wr == 1)
471 {
472 fwrook = file(i);
473 rwrook = rank(i);
474 }
475
476 /* bonus for being on the 7th (a bit bigger bonus in the endgame, b/c
477 a rook on the 7th can be a killer in the endgame): */
478 if (srank == 7)
479 {
480 score += 12;
481
482 if (wr == 2 && 7 == rwrook)
483 {
484 score += 10;
485 }
486 }
487
488 /* give bonuses depending on how open the rook's file is: */
489 if (!pawns[1][pawn_file]) {
490 /* half open file */
491 score += 5;
492
493 if (wr == 2 && file(i) == fwrook)
494 {
495 /* connected on file */
496 score += 10;
497 }
498
499 if (!pawns[0][pawn_file]) {
500 /* open file */
501 score += 3;
502 }
503 }
504
505 break;
506
507 case (brook):
508 score -= 500;
509 br++;
510
511 if (br == 1)
512 {
513 fbrook = file(i);
514 rbrook = rank(i);
515 }
516
517
518 /* bonus for being on the 7th (a bit bigger bonus in the endgame, b/c
519 a rook on the 7th can be a killer in the endgame): */
520 if (srank == 2)
521 {
522 score -= 12;
523
524 if (br == 2 && 2 == rbrook)
525 {
526 score -= 10;
527 }
528 }
529
530 /* give bonuses depending on how open the rook's file is: */
531 if (!pawns[0][pawn_file])
532 {
533 /* half open file */
534 score -= 5;
535
536 if (br == 2 && file(i) == fbrook)
537 {
538 /* connected on file */
539 score -= 10;
540 }
541
542 if (!pawns[1][pawn_file])
543 {
544 /* open file */
545 score -= 3;
546 }
547 }
548 break;
549
550 case (wbishop):
551 score += 325;
552 score += sbishop[i];
553 score += (bishop_mobility(i) << 1) - 15;
554 wb++;
555 break;
556
557 case (bbishop):
558 score -= 325;
559 score -= sbishop[i];
560 score -= (bishop_mobility(i) << 1) - 15;
561 bb++;
562 break;
563
564 case (wknight):
565 score += 310;
566 score += sknight[i];
567 wn++;
568 break;
569
570 case (bknight):
571 score -= 310;
572 score -= sknight[i];
573 bn++;
574 break;
575
576 case (wqueen):
577 score += 900;
578 wq++;
579 break;
580
581 case (bqueen):
582 score -= 900;
583 bq++;
584 break;
585 }
586 }
587
588 /* some static knowledge about drawn endgames */
589
590 /* pawn ending detection */
591 if (!wr && !wq && !wb && !wn)
592 {
593 score += bpotential;
594 }
595
596 if (!br && !bq && !bb && !bn)
597 {
598 score += wpotential;
599 }
600
601 /* no more pawns */
602 if (!wp && !bp)
603 {
604 /* nor heavies */
605 if (!wr && !br && !wq && !bq)
606 {
607 if (!bb && !wb)
608 {
609 /* only knights */
610 /* it pretty safe to say this is a draw */
611 if (wn < 3 && bn < 3)
612 {
613 score = 0;
614 }
615 }
616 else if (!wn && !bn)
617 {
618 /* only bishops */
619 /* not a draw if one side two other side zero
620 else its always a draw */
621 if (abs(wb - bb) < 2)
622 {
623 score = 0;
624 }
625 }
626 else if ((wn < 3 && !wb) || (wb == 1 && !wn))
627 {
628 /* we cant win, but can black? */
629 if ((bn < 3 && !bb) || (bb == 1 && !bn))
630 {
631 /* guess not */
632 score = 0;
633 }
634 }
635 }
636 else if (!wq && !bq)
637 {
638 if (wr == 1 && br == 1)
639 {
640 /* rooks equal */
641 if ((wn + wb) < 2 && (bn + bb) < 2)
642 {
643 /* one minor difference max */
644 /* a draw too usually */
645 score = 0;
646 }
647 }
648 else if (wr == 1 && !br)
649 {
650 /* one rook */
651 /* draw if no minors to support AND
652 minors to defend */
653 if ((wn + wb == 0) && (((bn + bb) == 1) || ((bn + bb) == 2)))
654 {
655 score = 0;
656 }
657 }
658 else if (br == 1 && !wr)
659 {
660 /* one rook */
661 /* draw if no minors to support AND
662 minors to defend */
663 if ((bn + bb == 0) && (((wn + wb) == 1) || ((wn + wb) == 2)))
664 {
665 score = 0;
666 }
667 }
668 }
669 }
670 else
671 {
672 /* bad trade code, largely based on Crafty's */
673 /* minors are not equal */
674 if ((wn + wb) != (bn + bb))
675 {
676 /* majors are equal */
677 if ((wq + wr) == (bq + br))
678 {
679 if ((wn + wb) > (bn + bb))
680 {
681 /* white is a piece up */
682 score += 120;
683 }
684 else
685 {
686 /* black is a piece up */
687 score -= 120;
688 }
689 }
690 else if (abs((wr + wq) - (br + bq)) == 1)
691 {
692 /* one major difference */
693
694 if ((wb + wn) > (bb + bn + 1))
695 {
696 /* two minors for one major */
697 score += 120;
698 }
699 else if ((bb + bn) > (wb + wn + 1))
700 {
701 score -= 120;
702 }
703 }
704 else if (abs((wr + wq) - (br + bq)) == 2)
705 {
706 /* two majors difference */
707
708 if ((wb + wn) > (bb + bn + 2))
709 {
710 /* three minors for two majors */
711 score += 120;
712 }
713 else if ((bb + bn) > (wb + wn + 2))
714 {
715 score -= 120;
716 }
717
718 }
719 }
720 else if ((wq + wr) == (bq + br))
721 {
722 if (wq && !bq)
723 {
724 score += 120;
725 }
726 else if (!wq && bq)
727 {
728 score -= 120;
729 }
730 }
731 }
732
733 /* the king is safe to come out in the endgame, so we don't check for
734 king safety anymore, and encourage centralization of the king */
735 score += send_king[wking_loc];
736
737 /* the king is safe to come out in the endgame, so we don't check for
738 king safety anymore, and encourage centralization of the king */
739 score -= send_king[bking_loc];
740
741 /* the e/d pawn blockage is not relevant in the endgame, and we don't need
742 to check for king safety due to pawn storms / heavy piece infiltration */
743
744 storeECache(score);
745
746 /* adjust for color: */
747 if (white_to_move == 1) {
748 return score;
749 }
750 else {
751 return -score;
752 }
753
754 }
755
check_phase(void)756 void check_phase(void)
757 {
758 int num_pieces = 0;
759 int j, a, i;
760
761 for (j = 1, a = 1; (a <= piece_count); j++)
762 {
763 i = pieces[j];
764
765 if (!i)
766 continue;
767 else
768 a++;
769
770 if (board[i] != wpawn && board[i] != bpawn &&
771 board[i] != npiece && board[i] != frame)
772 {
773 num_pieces++;
774 }
775 };
776 if ((num_pieces >= 12)
777 /* not both have castled */
778 && (!white_castled || !black_castled)
779 /* no both lost castling priveledges */
780 && (board[30] == wking || board[114] == bking))
781 {
782 phase = Opening;
783 }
784 else if (num_pieces <= 6)
785 {
786 phase = Endgame;
787 }
788 else
789 phase = Middlegame;
790
791 }
792
std_eval(void)793 long int std_eval (void) {
794
795 /* select the appropriate eval() routine: */
796
797 if (phase == Opening) {
798 return (opn_eval ());
799 }
800 else if (phase == Endgame) {
801 return (end_eval ());
802 }
803 else {
804 return (mid_eval ());
805 }
806
807 }
808
809
mid_eval(void)810 long int mid_eval (void) {
811
812 /* return a score for the current middlegame position: */
813
814 int i,a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11],
815 srank, wking_pawn_file, bking_pawn_file, j;
816 long int score = 0;
817 bool isolated, backwards;
818 int in_cache;
819 int wp = 0, bp = 0, wn = 0, bn = 0, wb = 0, bb = 0,
820 wq = 0, bq = 0, wr = 0, br = 0;
821 int rbrook, fbrook, rwrook,fwrook;
822
823 in_cache = 0;
824
825 checkECache(&score, &in_cache);
826
827 if(in_cache)
828 {
829 if (white_to_move == 1) return score;
830 return -score;
831 }
832
833 /* initialize the pawns array, (files offset by one to use dummy files in
834 order to easier determine isolated status) and also initialize the
835 arrays keeping track of the rank of the most backward pawn: */
836 memset (pawns, 0, sizeof (pawns));
837 for (i = 0; i < 11; i++) {
838 white_back_pawn[i] = 7;
839 black_back_pawn[i] = 2;
840 }
841 for (j = 1, a = 1; (a <= piece_count); j++) {
842 i = pieces[j];
843
844 if (!i)
845 continue;
846 else
847 a++;
848
849 assert((i > 0) && (i < 145));
850
851 if (board[i] == wpawn) {
852 pawn_file = file (i)+1;
853 srank = rank (i);
854
855 pawns[1][pawn_file]++;
856 if (srank < white_back_pawn[pawn_file]) {
857 white_back_pawn[pawn_file] = srank;
858 }
859 }
860 else if (board[i] == bpawn) {
861 pawn_file = file (i)+1;
862 srank = rank (i);
863
864 pawns[0][pawn_file]++;
865 if (srank > black_back_pawn[pawn_file]) {
866 black_back_pawn[pawn_file] = srank;
867 }
868 }
869 }
870
871 /* loop through the board, adding material value, as well as positional
872 bonuses for all pieces encountered: */
873 for (j = 1, a = 1; (a <= piece_count); j++) {
874 i = pieces[j];
875
876 if (!i)
877 continue;
878 else
879 a++;
880
881 pawn_file = file (i)+1;
882 srank = rank (i);
883 switch (board[i]) {
884 case (wpawn):
885 isolated = FALSE;
886 backwards = FALSE;
887 score += 100;
888 score += swhite_pawn[i];
889 wp++;
890
891 /* check for backwards pawns: */
892 if (white_back_pawn[pawn_file+1] > srank
893 && white_back_pawn[pawn_file-1] > srank) {
894 score -= 5;
895 backwards = TRUE;
896 /* check to see if it is furthermore isolated: */
897 if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) {
898 score -= 3;
899 isolated = TRUE;
900 }
901 }
902
903 score += std_p_tropism[max(abs(rank(i) - rank(bking_loc)),
904 abs(file(i) - file(bking_loc)))];
905 /* give weak, exposed pawns a penalty: */
906 if (!pawns[0][pawn_file]) {
907 if (backwards) score -= 4;
908 if (isolated) score -= 8;
909 }
910
911 /* give doubled, trippled, etc.. pawns a penalty: */
912 if (pawns[1][pawn_file] > 1)
913 score -= 2*(pawns[1][pawn_file]-1);
914
915 /* give bonuses for passed pawns: */
916 if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] &&
917 srank >= black_back_pawn[pawn_file+1]) {
918 score += 20 + 2*swhite_pawn[i];
919 /* give an extra bonus if a connected, passed pawn: */
920 if (!isolated)
921 {
922 score += 10;
923
924 /* check whether supporter is passed */
925 if (pawns[1][pawn_file+1])
926 {
927 if (!pawns[0][pawn_file+1]
928 && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file+2])
929 {
930 score += 7*rank(i);
931
932 /* connected on seventh ? */
933 if (rank(i) == 7 && white_back_pawn[pawn_file+1] >= 6)
934 {
935 score += 50;
936 }
937 }
938 }
939 if (pawns[1][pawn_file-1])
940 {
941 if (!pawns[0][pawn_file-1]
942 && white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file-2])
943 {
944 score += 7*rank(i);
945
946 /* connected on seventh ? */
947 if (rank(i) == 7 && white_back_pawn[pawn_file-1] >= 6)
948 {
949 score += 50;
950 }
951 }
952 }
953
954 }
955 }
956
957 if (!pawns[1][pawn_file-1])
958 score -= 5;
959
960 break;
961
962 case (bpawn):
963 isolated = FALSE;
964 backwards = FALSE;
965 score -= 100;
966 score -= sblack_pawn[i];
967 bp++;
968
969 /* check for backwards pawns: */
970 if (black_back_pawn[pawn_file+1] < srank
971 && black_back_pawn[pawn_file-1] < srank) {
972 score += 5;
973 backwards = TRUE;
974 /* check to see if it is furthermore isolated: */
975 if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) {
976 score += 3;
977 isolated = TRUE;
978 }
979 }
980
981 score -= std_p_tropism[max(abs(rank(i) - rank(wking_loc)),
982 abs(file(i) - file(wking_loc)))];
983
984 /* give weak, exposed pawns a penalty: */
985 if (!pawns[1][pawn_file]) {
986 if (backwards) score += 4;
987 if (isolated) score += 8;
988 }
989
990 /* give doubled, trippled, etc.. pawns a penalty: */
991 if (pawns[0][pawn_file] > 1)
992 score += 2*(pawns[0][pawn_file]-1);
993
994 /* give bonuses for passed pawns: */
995 if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] &&
996 srank <= white_back_pawn[pawn_file+1]) {
997 score -= 20 + 2*sblack_pawn[i];
998 /* give an extra bonus if a connected, passed pawn: */
999 if (!isolated)
1000 {
1001 score -= 10;
1002
1003 /* check whether supporter is passed */
1004 if (pawns[0][pawn_file+1])
1005 {
1006 if (!pawns[1][pawn_file+1]
1007 && black_back_pawn[pawn_file+1] <= white_back_pawn[pawn_file+2])
1008 {
1009 score -= 7*(9-rank(i));
1010
1011 /* connected on seventh ? */
1012 if (rank(i) == 2 && black_back_pawn[pawn_file+1] <= 3)
1013 {
1014 score -= 50;
1015 }
1016
1017 }
1018 }
1019 if (pawns[0][pawn_file-1])
1020 {
1021 if (!pawns[1][pawn_file-1]
1022 && black_back_pawn[pawn_file-1] <= white_back_pawn[pawn_file-2])
1023 {
1024 score -= 7*(9-rank(i));
1025
1026 /* connected on seventh ? */
1027 if (rank(i) == 2 && black_back_pawn[pawn_file-1] <= 3)
1028 {
1029 score -= 50;
1030 }
1031 }
1032 }
1033 }
1034 }
1035
1036 if (!pawns[0][pawn_file-1])
1037 score += 5;
1038
1039 break;
1040
1041 case (wrook):
1042 score += 500;
1043 wr++;
1044
1045 if (wr == 1)
1046 {
1047 fwrook = file(i);
1048 rwrook = rank(i);
1049 }
1050
1051 score += std_r_tropism[max(abs(rank(i) - rank(bking_loc)),
1052 abs(file(i) - file(bking_loc)))];
1053
1054 /* bonus for being on the 7th: */
1055 if (srank == 7)
1056 {
1057 score += 8;
1058 if (wr == 2 && rwrook == 7)
1059 {
1060 score += 10;
1061 }
1062
1063 }
1064
1065 /* give bonuses depending on how open the rook's file is: */
1066 if (!pawns[1][pawn_file]) {
1067 /* half open file */
1068 score += 5;
1069
1070 if (wr == 2 && file(i) == fwrook)
1071 {
1072 score += 12;
1073 }
1074
1075 if (!pawns[0][pawn_file]) {
1076 /* open file */
1077 score += 3;
1078 }
1079 }
1080
1081 break;
1082
1083 case (brook):
1084 score -= 500;
1085 br++;
1086 if (br == 1)
1087 {
1088 fbrook = file(i);
1089 rbrook = rank(i);
1090 }
1091
1092 score -= std_r_tropism[max(abs(rank(i) - rank(wking_loc)),
1093 abs(file(i) - file(wking_loc)))];
1094
1095 /* bonus for being on the 7th: */
1096 if (srank == 2)
1097 {
1098 score -= 8;
1099 if (wr == 2 && rbrook == 2)
1100 {
1101 score -= 10;
1102 }
1103 }
1104
1105 /* give bonuses depending on how open the rook's file is: */
1106 if (!pawns[0][pawn_file]) {
1107 /* half open file */
1108 score -= 5;
1109
1110 if (br == 2 && file(i) == fbrook)
1111 {
1112 score -= 12;
1113 }
1114
1115 if (!pawns[1][pawn_file]) {
1116 /* open file */
1117 score -= 3;
1118 }
1119 }
1120
1121 break;
1122
1123 case (wbishop):
1124 score += 325;
1125 score += sbishop[i];
1126 wb++;
1127 score += std_r_tropism[max(abs(rank(i) - rank(bking_loc)),
1128 abs(file(i) - file(bking_loc)))];
1129 score += bishop_mobility(i);
1130 break;
1131
1132 case (bbishop):
1133 score -= 325;
1134 score -= sbishop[i];
1135 bb++;
1136 score -= std_r_tropism[max(abs(rank(i) - rank(wking_loc)),
1137 abs(file(i) - file(wking_loc)))];
1138 score -= bishop_mobility(i);
1139 break;
1140
1141 case (wknight):
1142 score += 310;
1143 score += sknight[i];
1144 wn++;
1145 score += std_n_tropism[max(abs(rank(i) - rank(bking_loc)),
1146 abs(file(i) - file(bking_loc)))];
1147 break;
1148
1149 case (bknight):
1150 score -= 310;
1151 score -= sknight[i];
1152 bn++;
1153 score -= std_n_tropism[max(abs(rank(i) - rank(wking_loc)),
1154 abs(file(i) - file(wking_loc)))];
1155 break;
1156
1157 case (wqueen):
1158 score += 900;
1159 wq++;
1160 score += std_q_tropism[max(abs(rank(i) - rank(bking_loc)),
1161 abs(file(i) - file(bking_loc)))];
1162 break;
1163
1164 case (bqueen):
1165 score -= 900;
1166 bq++;
1167 score -= std_q_tropism[max(abs(rank(i) - rank(wking_loc)),
1168 abs(file(i) - file(wking_loc)))];
1169 break;
1170
1171 case (wking):
1172 score += swhite_king[i];
1173
1174 /* encourage castling, and give a penalty for moving the king without
1175 castling */
1176 if (white_castled == wcq)
1177 score += 15;
1178 else if (white_castled == wck)
1179 score += 25;
1180 else if (moved[30]) {
1181 score -= 10;
1182 /* make the penalty bigger if the king is open, leaving the other
1183 side a chance to gain tempo with files along the file, as well
1184 as building an attack: */
1185 if (!pawns[1][pawn_file])
1186 score -= 15;
1187 }
1188
1189 /* if the king is behind some pawn cover, give penalties for the pawn
1190 cover being far from the king, else give a penalty for the king
1191 not having any pawn cover: */
1192 if (file(wking_loc) != 4 && file(wking_loc) != 5)
1193 {
1194 if (srank < white_back_pawn[pawn_file] && pawns[1][pawn_file])
1195 score -= 9*(white_back_pawn[pawn_file]-srank-1);
1196 else
1197 score -= 22;
1198 if (srank < white_back_pawn[pawn_file+1] && pawns[1][pawn_file+1])
1199 score -= 8*(white_back_pawn[pawn_file+1]-srank-1);
1200 else
1201 score -= 16;
1202 if (srank < white_back_pawn[pawn_file-1] && pawns[1][pawn_file-1])
1203 score -= 8*(white_back_pawn[pawn_file-1]-srank-1);
1204 else
1205 score -= 16;
1206 }
1207 else
1208 {
1209 /* being in center isnt great either, so correct */
1210 score -= 10;
1211 }
1212 break;
1213
1214 case (bking):
1215 score -= sblack_king[i];
1216
1217 /* encourage castling, and give a penalty for moving the king without
1218 castling */
1219 if (black_castled == bcq)
1220 score -= 15;
1221 else if (black_castled == bck)
1222 score -= 25;
1223 else if (moved[114]) {
1224 score += 10;
1225 /* make the penalty bigger if the king is open, leaving the other
1226 side a chance to gain tempo with files along the file, as well
1227 as building an attack: */
1228 if (!pawns[0][pawn_file])
1229 score += 15;
1230 }
1231
1232 /* if the king is behind some pawn cover, give penalties for the pawn
1233 cover being far from the king, else give a penalty for the king
1234 not having any pawn cover: */
1235 if (file(bking_loc) != 4 && file(bking_loc) != 5)
1236 {
1237 if (srank > black_back_pawn[pawn_file] && pawns[0][pawn_file])
1238 score += 9*(srev_rank[srank-black_back_pawn[pawn_file]-1]);
1239 else
1240 score += 22;
1241 if (srank > black_back_pawn[pawn_file+1] && pawns[0][pawn_file+1])
1242 score += 8*(srev_rank[srank-black_back_pawn[pawn_file+1]-1]);
1243 else
1244 score += 16;
1245 if (srank > black_back_pawn[pawn_file-1] && pawns[0][pawn_file-1])
1246 score += 8*(srev_rank[srank-black_back_pawn[pawn_file-1]-1]);
1247 else
1248 score += 16;
1249 }
1250 else
1251 {
1252 score += 10;
1253 }
1254 break;
1255 }
1256 }
1257
1258 /* give penalties for blocking the e/d pawns: */
1259 if (!moved[41] && board[53] != npiece)
1260 score -= 5;
1261 if (!moved[42] && board[54] != npiece)
1262 score -= 5;
1263 if (!moved[101] && board[89] != npiece)
1264 score += 5;
1265 if (!moved[102] && board[90] != npiece)
1266 score += 5;
1267
1268 /* to be used for pawn storm code: */
1269 wking_pawn_file = file (wking_loc)+1;
1270 bking_pawn_file = file (bking_loc)+1;
1271
1272 /* if the kings are on opposite wings, or far apart, check for pawn
1273 storms, and open lines for heavy pieces: */
1274 if (abs(wking_pawn_file-bking_pawn_file) > 2) {
1275 /* black pawn storms: */
1276 score -= 3*(srev_rank[black_back_pawn[wking_pawn_file]]-2);
1277 score -= 3*(srev_rank[black_back_pawn[wking_pawn_file+1]]-2);
1278 score -= 3*(srev_rank[black_back_pawn[wking_pawn_file-1]]-2);
1279
1280 /* white pawn storms: */
1281 /* this has side effects on no pawns, but I guess
1282 it wont hurt - GCP */
1283 score += 3*(white_back_pawn[bking_pawn_file]-2);
1284 score += 3*(white_back_pawn[bking_pawn_file+1]-2);
1285 score += 3*(white_back_pawn[bking_pawn_file-1]-2);
1286
1287 /* black opening up lines: */
1288 if (!pawns[0][wking_pawn_file])
1289 score -= 8;
1290 if (!pawns[0][wking_pawn_file+1])
1291 score -= 6;
1292 if (!pawns[0][wking_pawn_file-1])
1293 score -= 6;
1294
1295 /* white opening up lines: */
1296 if (!pawns[1][bking_pawn_file])
1297 score += 8;
1298 if (!pawns[1][bking_pawn_file+1])
1299 score += 6;
1300 if (!pawns[1][bking_pawn_file-1])
1301 score += 6;
1302
1303 }
1304
1305 /* bad trade code, largely based on Crafty's */
1306
1307 /* minors are not equal */
1308 if ((wn + wb) != (bn + bb))
1309 {
1310 /* majors are equal */
1311 if ((wq + wr) == (bq + br))
1312 {
1313 if ((wn + wb) > (bn + bb))
1314 {
1315 /* white is a piece up */
1316 score += 120;
1317 }
1318 else
1319 {
1320 /* black is a piece up */
1321 score -= 120;
1322 }
1323 }
1324 else if (abs((wr + wq) - (br + bq)) == 1)
1325 {
1326 /* one major difference */
1327
1328 if ((wb + wn) > (bb + bn + 1))
1329 {
1330 /* two minors for one major */
1331 score += 120;
1332 }
1333 else if ((bb + bn) > (wb + wn + 1))
1334 {
1335 score -= 120;
1336 }
1337 }
1338 else if (abs((wr + wq) - (br + bq)) == 2)
1339 {
1340 /* two majors difference */
1341
1342 if ((wb + wn) > (bb + bn + 2))
1343 {
1344 /* three minors for two majors */
1345 score += 120;
1346 }
1347 else if ((bb + bn) > (wb + wn + 2))
1348 {
1349 score -= 120;
1350 }
1351
1352 }
1353 }
1354 else if ((wq + wr) == (bq + br))
1355 {
1356 if (wq && !bq)
1357 {
1358 score += 120;
1359 }
1360 else if (!wq && bq)
1361 {
1362 score -= 120;
1363 }
1364 }
1365
1366 storeECache(score);
1367
1368 /* adjust for color: */
1369 if (white_to_move == 1) {
1370 return score;
1371 }
1372 else {
1373 return -score;
1374 }
1375
1376 }
1377
opn_eval(void)1378 long int opn_eval (void) {
1379
1380 /* return a score for the current opening position: */
1381
1382 int i,a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11],
1383 srank, wking_pawn_file, bking_pawn_file, j;
1384 long int score = 0;
1385 bool isolated, backwards;
1386 int in_cache;
1387 int fwrook = 0, fbrook = 0;
1388
1389 in_cache = 0;
1390
1391 checkECache(&score, &in_cache);
1392
1393 if(in_cache)
1394 {
1395 if (white_to_move == 1) return score;
1396 return -score;
1397 }
1398
1399 /* initialize the pawns array, (files offset by one to use dummy files in
1400 order to easier determine isolated status) and also initialize the
1401 arrays keeping track of the rank of the most backward pawn: */
1402 memset (pawns, 0, sizeof (pawns));
1403 for (i = 0; i < 11; i++) {
1404 white_back_pawn[i] = 7;
1405 black_back_pawn[i] = 2;
1406 }
1407 for (j = 1, a = 1; (a <= piece_count); j++) {
1408 i = pieces[j];
1409
1410 if (!i)
1411 continue;
1412 else
1413 a++;
1414
1415 if (board[i] == wpawn) {
1416 pawn_file = file (i)+1;
1417 srank = rank (i);
1418
1419 pawns[1][pawn_file]++;
1420 if (srank < white_back_pawn[pawn_file]) {
1421 white_back_pawn[pawn_file] = srank;
1422 }
1423 }
1424 else if (board[i] == bpawn) {
1425 pawn_file = file (i)+1;
1426 srank = rank (i);
1427
1428 pawns[0][pawn_file]++;
1429 if (srank > black_back_pawn[pawn_file]) {
1430 black_back_pawn[pawn_file] = srank;
1431 }
1432 }
1433 }
1434
1435 /* loop through the board, adding material value, as well as positional
1436 bonuses for all pieces encountered: */
1437 for (j = 1, a = 1; (a <= piece_count); j++) {
1438 i = pieces[j];
1439
1440 if (!i)
1441 continue;
1442 else
1443 a++;
1444
1445 assert((i > 0) && (i < 145));
1446
1447 pawn_file = file (i)+1;
1448 srank = rank (i);
1449 switch (board[i]) {
1450 case (wpawn):
1451 isolated = FALSE;
1452 backwards = FALSE;
1453 score += 100;
1454 score += swhite_pawn[i];
1455
1456 /* penalties / bonuses will be in general smaller in the opening,
1457 in order to put an emphasis on piece development */
1458
1459 /* check for backwards pawns: */
1460 if (white_back_pawn[pawn_file+1] > srank
1461 && white_back_pawn[pawn_file-1] > srank) {
1462 /* no penalty in the opening for having a backwards pawn that hasn't
1463 moved yet! */
1464 if (srank != 2)
1465 score -= 3;
1466 backwards = TRUE;
1467 /* check to see if it is furthermore isolated: */
1468 if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) {
1469 score -= 2;
1470 isolated = TRUE;
1471 }
1472 }
1473
1474 /* give weak, exposed pawns a penalty: */
1475 if (!pawns[0][pawn_file]) {
1476 if (backwards) score -= 3;
1477 if (isolated) score -= 5;
1478 }
1479
1480 /* give doubled, trippled, etc.. pawns a penalty: */
1481 if (pawns[1][pawn_file] > 1)
1482 score -= 2*(pawns[1][pawn_file]-1);
1483
1484 /* give bonuses for passed pawns: */
1485 if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] &&
1486 srank >= black_back_pawn[pawn_file+1]) {
1487 score += 5 + 2*swhite_pawn[i];
1488 /* give an extra bonus if a connected, passed pawn: */
1489 if (!isolated)
1490 score += 10;
1491 }
1492
1493 break;
1494
1495 case (bpawn):
1496 isolated = FALSE;
1497 backwards = FALSE;
1498 score -= 100;
1499 score -= sblack_pawn[i];
1500
1501 /* penalties / bonuses will be in general smaller in the opening,
1502 in order to put an emphasis on piece development */
1503
1504 /* check for backwards pawns: */
1505 if (black_back_pawn[pawn_file+1] < srank
1506 && black_back_pawn[pawn_file-1] < srank) {
1507 /* no penalty in the opening for having a backwards pawn that hasn't
1508 moved yet! */
1509 if (srank != 2)
1510 score += 3;
1511 backwards = TRUE;
1512 /* check to see if it is furthermore isolated: */
1513 if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) {
1514 score += 2;
1515 isolated = TRUE;
1516 }
1517 }
1518
1519 /* give weak, exposed pawns a penalty: */
1520 if (!pawns[1][pawn_file]) {
1521 if (backwards) score += 3;
1522 if (isolated) score += 5;
1523 }
1524
1525 /* give doubled, trippled, etc.. pawns a penalty: */
1526 if (pawns[0][pawn_file] > 1)
1527 score += 2*(pawns[0][pawn_file]-1);
1528
1529 /* give bonuses for passed pawns: */
1530 if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] &&
1531 srank <= white_back_pawn[pawn_file+1]) {
1532 score -= 5 + 2*sblack_pawn[i];
1533 /* give an extra bonus if a connected, passed pawn: */
1534 if (!isolated)
1535 score -= 10;
1536 }
1537
1538 break;
1539
1540 case (wrook):
1541 score += 500;
1542
1543 if (!fwrook) fwrook = file(i);
1544 else if (file(i) == fwrook)
1545 {
1546 /* two rooks, file at least halfopen */
1547 if (!pawns[1][pawn_file])
1548 score += 10;
1549 }
1550
1551 /* bonus for being on the 7th: */
1552 if (srank == 7)
1553 score += 8;
1554
1555 /* give bonuses depending on how open the rook's file is: */
1556 if (!pawns[1][pawn_file]) {
1557 /* half open file */
1558 score += 5;
1559 if (!pawns[0][pawn_file]) {
1560 /* open file */
1561 score += 3;
1562 }
1563 }
1564
1565 break;
1566
1567 case (brook):
1568 score -= 500;
1569
1570 if (!fbrook) fbrook = file(i);
1571 else if (file(i) == fbrook)
1572 {
1573 /* two rooks, file at least halfopen */
1574 if (!pawns[0][pawn_file])
1575 score -= 10;
1576 }
1577
1578 /* bonus for being on the 7th: */
1579 if (srank == 2)
1580 score -= 8;
1581
1582 /* give bonuses depending on how open the rook's file is: */
1583 if (!pawns[0][pawn_file]) {
1584 /* half open file */
1585 score -= 5;
1586 if (!pawns[1][pawn_file]) {
1587 /* open file */
1588 score -= 3;
1589 }
1590 }
1591
1592 break;
1593
1594 case (wbishop):
1595 score += 325;
1596 score += sbishop[i];
1597 score += std_b_tropism[max(abs(rank(i) - rank(bking_loc)),
1598 abs(file(i) - file(bking_loc)))];
1599 score += bishop_mobility(i);
1600 break;
1601
1602 case (bbishop):
1603 score -= 325;
1604 score -= sbishop[i];
1605 score -= std_b_tropism[max(abs(rank(i) - rank(wking_loc)),
1606 abs(file(i) - file(wking_loc)))];
1607 score -= bishop_mobility(i);
1608 break;
1609
1610 case (wknight):
1611 score += 310;
1612 score += sknight[i];
1613 score += std_n_tropism[max(abs(rank(i) - rank(bking_loc)),
1614 abs(file(i) - file(bking_loc)))];
1615 break;
1616
1617 case (bknight):
1618 score -= 310;
1619 score -= sknight[i];
1620 score -= std_n_tropism[max(abs(rank(i) - rank(wking_loc)),
1621 abs(file(i) - file(wking_loc)))];
1622 break;
1623
1624 case (wqueen):
1625 score += 900;
1626
1627 score += std_q_tropism[max(abs(rank(i) - rank(bking_loc)),
1628 abs(file(i) - file(bking_loc)))];
1629
1630 /* a small penalty to discourage moving the queen in the opening
1631 before the other minors: */
1632 if (i != 29)
1633 if (!moved[28] || !moved[27] || !moved[31] || !moved[32])
1634 score -= 10;
1635
1636 break;
1637
1638 case (bqueen):
1639 score -= 900;
1640
1641 score -= std_q_tropism[max(abs(rank(i) - rank(wking_loc)),
1642 abs(file(i) - file(wking_loc)))];
1643
1644 /* a small penalty to discourage moving the queen in the opening
1645 before the other minors: */
1646 if (i != 113)
1647 if (!moved[112] || !moved[111] || !moved[115] || !moved[116])
1648 score += 10;
1649
1650 break;
1651
1652 case (wking):
1653 score += swhite_king[i];
1654
1655 /* encourage castling, and give a penalty for moving the king without
1656 castling */
1657 if (white_castled == wcq)
1658 score += 12;
1659 else if (white_castled == wck)
1660 score += 20;
1661 else if (moved[30]) {
1662 score -= 15;
1663 /* make the penalty bigger if the king is open, leaving the other
1664 side a chance to gain tempo with files along the file, as well
1665 as building an attack: */
1666 if (!pawns[1][pawn_file])
1667 score -= 10;
1668 }
1669
1670 /* in general, in the opening, don't worry quite so much about pawn
1671 cover, because sometimes it isn't good for the king to castle */
1672
1673 /* if the king is behind some pawn cover, give penalties for the pawn
1674 cover being far from the king, else give a penalty for the king
1675 not having any pawn cover: */
1676 /* only worry about cover when castled */
1677 if (file(wking_loc) != 4 && file(wking_loc) != 5)
1678 {
1679 if (srank < white_back_pawn[pawn_file] && pawns[1][pawn_file])
1680 score -= 7*(white_back_pawn[pawn_file]-srank-1);
1681 else
1682 score -= 14;
1683 if (srank < white_back_pawn[pawn_file+1] && pawns[1][pawn_file+1])
1684 score -= 4*(white_back_pawn[pawn_file+1]-srank-1);
1685 else
1686 score -= 8;
1687 if (srank < white_back_pawn[pawn_file-1] && pawns[1][pawn_file-1])
1688 score -= 4*(white_back_pawn[pawn_file-1]-srank-1);
1689 else
1690 score -= 8;
1691 }
1692 else
1693 {
1694 score -= 7;
1695 }
1696
1697 break;
1698
1699 case (bking):
1700 score -= sblack_king[i];
1701
1702 /* encourage castling, and give a penalty for moving the king without
1703 castling */
1704 if (black_castled == bcq)
1705 score -= 12;
1706 else if (black_castled == bck)
1707 score -= 20;
1708 else if (moved[114]) {
1709 score += 15;
1710 /* make the penalty bigger if the king is open, leaving the other
1711 side a chance to gain tempo with files along the file, as well
1712 as building an attack: */
1713 if (!pawns[0][pawn_file])
1714 score += 10;
1715 }
1716
1717 /* in general, in the opening, don't worry quite so much about pawn
1718 cover, because sometimes it isn't good for the king to castle */
1719
1720 /* if the king is behind some pawn cover, give penalties for the pawn
1721 cover being far from the king, else give a penalty for the king
1722 not having any pawn cover: */
1723 if (file(bking_loc) != 4 && file(bking_loc) != 5)
1724 {
1725 if (srank > black_back_pawn[pawn_file] && pawns[0][pawn_file])
1726 score += 7*(srev_rank[srank-black_back_pawn[pawn_file]-1]);
1727 else
1728 score += 14;
1729 if (srank > black_back_pawn[pawn_file+1] && pawns[0][pawn_file+1])
1730 score += 4*(srev_rank[srank-black_back_pawn[pawn_file+1]-1]);
1731 else
1732 score += 8;
1733 if (srank > black_back_pawn[pawn_file-1] && pawns[0][pawn_file-1])
1734 score += 4*(srev_rank[srank-black_back_pawn[pawn_file-1]-1]);
1735 else
1736 score += 8;
1737 }
1738 else
1739 {
1740 score += 7;
1741 }
1742
1743 break;
1744 }
1745 }
1746
1747 /* give bigger penalties for blocking the e/d pawns in the opening, as
1748 we want to develop quickly: */
1749 if (!moved[41] && board[53] != npiece)
1750 score -= 7;
1751 if (!moved[42] && board[54] != npiece)
1752 score -= 7;
1753 if (!moved[101] && board[89] != npiece)
1754 score += 7;
1755 if (!moved[102] && board[90] != npiece)
1756 score += 7;
1757
1758 /* to be used for pawn storm code: */
1759 wking_pawn_file = file[wking_loc]+1;
1760 bking_pawn_file = file[bking_loc]+1;
1761
1762 /* if the kings are on opposite wings, or far apart, check for pawn
1763 storms, and open lines for heavy pieces (bonuses/penalties brought
1764 down a bit in the opening, as it isn't a good idea to start pawn
1765 storming when the position is still fluid): */
1766 if (abs(bking_pawn_file-wking_pawn_file) > 2) {
1767 /* black pawn storms: */
1768 score -= srev_rank[black_back_pawn[wking_pawn_file]] - 2;
1769 score -= srev_rank[black_back_pawn[wking_pawn_file+1]] - 2;
1770 score -= srev_rank[black_back_pawn[wking_pawn_file-1]] - 2;
1771
1772 /* white pawn storms: */
1773 score += white_back_pawn[bking_pawn_file] - 2;
1774 score += white_back_pawn[bking_pawn_file+1] - 2;
1775 score += white_back_pawn[bking_pawn_file-1] - 2;
1776
1777 /* black opening up lines: */
1778 if (!pawns[0][wking_pawn_file])
1779 score -= 6;
1780 if (!pawns[0][wking_pawn_file+1])
1781 score -= 4;
1782 if (!pawns[0][wking_pawn_file-1])
1783 score -= 4;
1784
1785 /* white opening up lines: */
1786 if (!pawns[1][bking_pawn_file])
1787 score += 6;
1788 if (!pawns[1][bking_pawn_file+1])
1789 score += 4;
1790 if (!pawns[1][bking_pawn_file-1])
1791 score += 4;
1792
1793 }
1794
1795 storeECache(score);
1796
1797 /* adjust for color: */
1798 if (white_to_move == 1) {
1799 return score;
1800 }
1801 else {
1802 return -score;
1803 }
1804
1805 }
1806