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
31static int sbishop[144] = {
320,0,0,0,0,0,0,0,0,0,0,0,
330,0,0,0,0,0,0,0,0,0,0,0,
340,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0,
350,0,-2,8,5,5,5,5,8,-2,0,0,
360,0,-2,3,3,5,5,3,3,-2,0,0,
370,0,-2,2,5,4,4,5,2,-2,0,0,
380,0,-2,2,5,4,4,5,2,-2,0,0,
390,0,-2,3,3,5,5,3,3,-2,0,0,
400,0,-2,8,5,5,5,5,8,-2,0,0,
410,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0,
420,0,0,0,0,0,0,0,0,0,0,0,
430,0,0,0,0,0,0,0,0,0,0,0};
44
45static int sknight[144] = {
460,0,0,0,0,0,0,0,0,0,0,0,
470,0,0,0,0,0,0,0,0,0,0,0,
480,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0,
490,0,-10,0,0,3,3,0,0,-10,0,0,
500,0,-10,0,5,5,5,5,0,-10,0,0,
510,0,-10,0,5,10,10,5,0,-10,0,0,
520,0,-10,0,5,10,10,5,0,-10,0,0,
530,0,-10,0,5,5,5,5,0,-10,0,0,
540,0,-10,0,0,3,3,0,0,-10,0,0,
550,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0,
560,0,0,0,0,0,0,0,0,0,0,0,
570,0,0,0,0,0,0,0,0,0,0,0};
58
59static int32_t swhite_pawn[144] = {
600,0,0,0,0,0,0,0,0,0,0,0,
610,0,0,0,0,0,0,0,0,0,0,0,
620,0,0,0,0,0,0,0,0,0,0,0,
630,0,0,0,0,0,0,0,0,0,0,0,
640,0,1,2,3,10,10,3,2,1,0,0,
650,0,2,4,6,12,12,6,4,2,0,0,
660,0,3,6,9,14,14,9,6,3,0,0,
670,0,4,8,12,16,16,12,8,4,0,0,
680,0,5,10,15,20,20,15,10,5,0,0,
690,0,0,0,0,0,0,0,0,0,0,0,
700,0,0,0,0,0,0,0,0,0,0,0,
710,0,0,0,0,0,0,0,0,0,0,0};
72
73static int sblack_pawn[144] = {
740,0,0,0,0,0,0,0,0,0,0,0,
750,0,0,0,0,0,0,0,0,0,0,0,
760,0,0,0,0,0,0,0,0,0,0,0,
770,0,5,10,15,20,20,15,10,5,0,0,
780,0,4,8,12,16,16,12,8,4,0,0,
790,0,3,6,9,14,14,9,6,3,0,0,
800,0,2,4,6,12,12,6,4,2,0,0,
810,0,1,2,3,10,10,3,2,1,0,0,
820,0,0,0,0,0,0,0,0,0,0,0,
830,0,0,0,0,0,0,0,0,0,0,0,
840,0,0,0,0,0,0,0,0,0,0,0,
850,0,0,0,0,0,0,0,0,0,0,0};
86
87/* to be used during opening and middlegame for white king positioning: */
88static int swhite_king[144] = {
890,0,0,0,0,0,0,0,0,0,0,0,
900,0,0,0,0,0,0,0,0,0,0,0,
910,0,2,14,0,0,0,9,14,2,0,0,
920,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0,
930,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0,
940,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0,
950,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0,
960,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0,
970,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0,
980,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0,
990,0,0,0,0,0,0,0,0,0,0,0,
1000,0,0,0,0,0,0,0,0,0,0,0};
101
102/* to be used during opening and middlegame for black king positioning: */
103static int sblack_king[144] = {
1040,0,0,0,0,0,0,0,0,0,0,0,
1050,0,0,0,0,0,0,0,0,0,0,0,
1060,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0,
1070,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0,
1080,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0,
1090,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0,
1100,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0,
1110,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0,
1120,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0,
1130,0,2,14,0,0,0,9,14,2,0,0,
1140,0,0,0,0,0,0,0,0,0,0,0,
1150,0,0,0,0,0,0,0,0,0,0,0};
116
117/* to be used for positioning of both kings during the endgame: */
118static int send_king[144] = {
1190,0,0,0,0,0,0,0,0,0,0,0,
1200,0,0,0,0,0,0,0,0,0,0,0,
1210,0,-5,-3,-1,0,0,-1,-3,-5,0,0,
1220,0,-3,10,10,10,10,10,10,-3,0,0,
1230,0,-1,10,25,25,25,25,10,-1,0,0,
1240,0,0,10,25,30,30,25,10,0,0,0,
1250,0,0,10,25,30,30,25,10,0,0,0,
1260,0,-1,10,25,25,25,25,10,-1,0,0,
1270,0,-3,10,10,10,10,10,10,-3,0,0,
1280,0,-5,-3,-1,0,0,-1,-3,-5,0,0,
1290,0,0,0,0,0,0,0,0,0,0,0,
1300,0,0,0,0,0,0,0,0,0,0,0};
131
132/* utility array to reverse rank: */
133static int srev_rank[9] = {
1340,8,7,6,5,4,3,2,1};
135
136const int std_p_tropism[9] =
137{ 9999, 15, 10, 7, 2, 0, 0, 0, 9999};
138
139const int std_r_tropism[9] =
140{ 9999, 10, 6, 4, 2, 0, 0, 0, 9999};
141
142const int std_n_tropism[9] =
143{ 9999, 14, 9, 6, 1, 0, 0, 0, 9999};
144
145const int std_q_tropism[9] =
146{ 9999, 16, 12, 7, 2, 0, 0, 0, 9999};
147
148const int std_b_tropism[9] =
149{ 9999, 12, 7, 5, 0, 0, 0, 0, 9999};
150
151
152static 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
169int32_t 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  int32_t 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
756void 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
793int32_t 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
810int32_t 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  int32_t 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
1378int32_t 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  int32_t 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