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