7d6a176c276bb451b1a6de57280bb1f56bca5e74
[gnushogi.git] / src / eval.c
1 /*
2  * eval.c - C source for GNU SHOGI
3  *
4  * Copyright (c) 1993, 1994, 1995 Matthias Mutz
5  *
6  * GNU SHOGI is based on GNU CHESS
7  *
8  * Copyright (c) 1988,1989,1990 John Stanback
9  * Copyright (c) 1992 Free Software Foundation
10  *
11  * This file is part of GNU SHOGI.
12  *
13  * GNU Shogi is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 1, or (at your option)
16  * any later version.
17  *
18  * GNU Shogi is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with GNU Shogi; see the file COPYING.  If not, write to
25  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27  
28 #include "gnushogi.h"
29
30 #include "pattern.h"
31  
32
33 /* Hash table for preventing multiple scoring of the same position */
34
35 int EADD = 0;       /* number of writes to the cache table */ 
36 int EGET = 0;       /* number of hits to the cache table */
37 int PUTVAR = false; /* shall the current scoring be cached? */
38
39
40 /* Pieces and colors of initial board setup */
41
42 const small_short Stboard[NO_SQUARES] =
43 {lance,knight,silver,gold,king,gold,silver,knight,lance,
44  0, bishop, 0, 0, 0, 0, 0, rook, 0,
45  pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn, 
46  0, 0, 0, 0, 0, 0, 0, 0, 0, 
47  0, 0, 0, 0, 0, 0, 0, 0, 0, 
48  0, 0, 0, 0, 0, 0, 0, 0, 0, 
49  pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn, 
50  0, rook, 0, 0, 0, 0, 0, bishop, 0,
51  lance,knight,silver,gold,king,gold,silver,knight,lance};
52
53
54 const small_short Stcolor[NO_SQUARES] =
55 {black, black, black, black, black, black, black, black, black, 
56  neutral, black, neutral, neutral, neutral, neutral, neutral, black, neutral,
57  black, black, black, black, black, black, black, black, black, 
58  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral, 
59  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral, 
60  neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral, 
61  white, white, white, white, white, white, white, white, white,
62  neutral, white, neutral, neutral, neutral, neutral, neutral, white, neutral,
63  white, white, white, white, white, white, white, white, white};
64                                               
65
66 /* Actual pieces and colors */
67
68 small_short board[NO_SQUARES], color[NO_SQUARES];
69
70
71 /* relative piece values at the beginning of main stages */
72
73 #define MAIN_STAGES 4                                       
74
75 static small_short ispvalue[NO_PIECES][MAIN_STAGES] =
76   {   0,  35,  70,  99, /* main stage borders */
77   /* ------------------- */
78       7,   7,   8,  10, /* Pawn */
79      20,  35,  45,  60, /* Lance */
80      20,  35,  45,  60, /* Knight */
81      35,  40,  60,  80, /* Silver */
82      35,  50,  65,  80, /* Gold */
83      90,  90,  90,  90, /* Bishop */
84      95,  95,  95,  95, /* Rook */
85      15,  25,  40,  65, /* promoted Pawn */
86      25,  45,  55,  65, /* promoted Lance */
87      25,  45,  55,  65, /* promoted Knight */
88      35,  55,  75,  75, /* promoted Silver */
89      99,  99,  99,  99, /* promoted Bishop */
90      97,  97,  99,  99, /* promoted Rook */
91     100, 100, 100, 100, /* King */
92   };
93                                 
94 /* Features and Weights */
95
96 #define ATAKD       0
97 #define HUNGP       1
98 #define HUNGX       2
99 #define CNTRL5TH    3
100 #define HOLES       4
101 #define PCASTLE     5
102 #define PATTACK     6
103 #define CTRLK       7
104 #define PROTECT     8
105 #define HCLSD       9
106 #define PINVAL     10
107 #define XRAY       11
108 #define OPENWRONG  12
109 #define SEED       13
110 #define LOOSE      14
111 #define MOBILITY   15
112 #define TARGET     16
113 #define KSFTY      17
114 #define HOPN       18
115 #define PROMD      19
116 #define KINGOD     20
117 #define PWNDROP    21
118 #define DFFDROP    22
119 #define FCLATTACK  23
120 #define KNGATTACK  24
121 #define KNGPROTECT 25
122 #define DNGLPC     26
123 #define LSATTACK   27
124 #define NIHATTACK  28
125 #define COHESION   29
126 #define OPPDROP    30
127
128 static small_short weight[NO_FEATURES+1][MAIN_STAGES+2] =
129   {  80, 100, 100,  40, 10, 15, /* ATAKD */
130      80, 100, 100,  50, 14, 10, /* HUNGP */
131      80, 100, 100,  50, 18, 12, /* HUNGX */
132     100,  50,   0,   0,  2,  1, /* CNTRL5TH */
133     100, 100,  60,  10,  4,  2, /* HOLES */
134     100,  50,   0,   0, 14,  7, /* PCASTLE */
135     100,  50,   0,   0,  6, 12, /* PATTACK */
136      10,  40,  70, 100, 10, 15, /* CTRLK */
137     100,  80,  50,  40,  2,  1, /* PROTECT */
138      40, 100,  40,   5,  4,  4, /* HCLSD */
139      80, 100,  80,  30, 10, 15, /* PINVAL */
140      80, 100,  60,  15,  6, 10, /* XRAY */
141     100,  50,   0,   0, 15, 15, /* OPENWRONG */
142       0,  40,  70, 100,  8, 12, /* SEED */
143      50, 100,  80,  20,  5,  3, /* LOOSE */
144      50, 100,  80,  50,100,100, /* MOBILITY (%) */
145      50, 100,  80,  50,  4,  8, /* TARGET */
146      50,  40, 100,  80,  8,  4, /* KSFTY */
147      80, 100,  60,  20,  5,  5, /* HOPN */
148      20,  40,  80, 100,  3,  6, /* PROMD */
149      20,  40,  80, 100,  4,  1, /* KINGOD */
150       5,  40, 100,  50,  0,  4, /* PWNDROP */
151       0,  20,  80, 100,  0,  4, /* DFFDROP */
152      20,  50, 100,  80,  0,  4, /* FCLATTACK */
153       0,  20,  80, 100,  0,  8, /* KNGATTACK */
154      40,  80, 100,  80,  6,  0, /* KNGPROTECT */
155      50, 100,  60,  10,  0,  8, /* DNGPC */
156      30, 100,  60,   5,  0,  6, /* LSATTACK */
157       0,  50,  80, 100,  0,  8, /* NIHATTACK */
158      50, 100,  80,  60,  8,  0, /* COHESION */
159     100, 100,  80,  60,  4,  4, /* OPPDROP */
160   };
161 short ADVNCM[NO_PIECES];
162
163 /* distance to enemy king */
164 static const EnemyKingDistanceBonus[10] =
165 {0, 6, 4, -1, -3, -4, -6, -8, -10, -12};
166  
167 /* distance to own king */
168 static const OwnKingDistanceBonus[10] =
169 {0, 5, 2, 1, 0, -1, -2, -3, -4, -5};
170
171 /* distance to promotion zone */
172 static const PromotionZoneDistanceBonus[NO_ROWS] =
173 {0, 0, 0, 0, 2, 6, 6, 8, 8};
174
175 #define MAX_BMBLTY 20
176 #define MAX_RMBLTY 20
177 #define MAX_LMBLTY 8
178
179 /* Bishop mobility bonus indexed by # reachable squares */
180 static const short BMBLTY[MAX_BMBLTY] =
181  {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 16, 16, 16, 16};
182
183 /* Rook mobility bonus indexed by # reachable squares */
184 static const short RMBLTY[MAX_RMBLTY] =
185  {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 16, 16, 16, 16};
186
187 /* Lance mobility bonus indexed by # reachable squares */
188 static const short LMBLTY[MAX_LMBLTY] =
189  {0, 0, 0, 0, 4, 6, 8, 10};
190
191 static const short MBLTY[NO_PIECES] =
192  {0, 2, 1, 10, 5, 5, 1, 1, 5, 5, 5, 5, 1, 1, 4};
193
194 static const short KTHRT[36] =
195 {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
196  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
197  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
198
199 static small_short fvalue[2][NO_FEATURES];
200
201 long int atak[2][NO_SQUARES];       /* threats to squares */
202 small_short sseed[NO_SQUARES];      /* square occupied by a seed piece? */
203
204 struct signature threats_signature[2] =    /* statistics valid for position ... */
205  {-1, -1, -1, -1};                         /* atak and sseed available */
206
207 small_short starget[2][NO_SQUARES]; /* significance as a target for a side of a square */
208 small_short sloose[NO_SQUARES];     /* square occupied by a loose piece? */
209 small_short shole[NO_SQUARES];      /* empty square a hole? */
210 small_short shung[NO_SQUARES];     /* hung piece? */
211
212 struct signature squares_signature =       /* statistics valid for position ... */
213  {0, 0};                                   /* starget, sloose, shole, shung available */
214
215 short target[2], seed[2], loose[2], hole[2];
216
217 short captured[2];  /* number of captured pieces */
218 short dcaptured[2]; /* different types of captured pieces */
219
220 small_short Kdist[2][NO_SQUARES];    /* distance to king */
221
222 short MAXADIST, MAXCDIST; /* maximum half move distance to pattern */
223
224 char GameType[2] = {UNKNOWN,UNKNOWN}; /* choosen game type of each side */
225
226
227 static short attack_opening_sequence[2];    /* current castle patterns */
228 static short castle_opening_sequence[2];    /* current attack formations */
229
230 static small_short Mpawn[2][NO_SQUARES]; 
231 static small_short Msilver[2][NO_SQUARES]; 
232 static small_short Mgold[2][NO_SQUARES]; 
233 static small_short Mking[2][NO_SQUARES];
234 static small_short Mlance[2][NO_SQUARES]; 
235 static small_short Mknight[2][NO_SQUARES]; 
236 static small_short Mbishop[2][NO_SQUARES]; 
237 static small_short Mrook[2][NO_SQUARES]; 
238
239 static Mpiece_array Mpawn, Mlance, Mknight, Msilver, Mgold,
240                     Mbishop, Mrook, Mking;
241
242 Mpiece_array *Mpiece[NO_PIECES] =
243   { NULL, &Mpawn, &Mlance, &Mknight, &Msilver, &Mgold, &Mbishop, &Mrook,
244           &Mgold, &Mgold, &Mgold, &Mgold, &Mbishop, &Mrook, &Mking };
245
246
247 static short c1, c2;
248
249 static small_short *PC1, *PC2;
250
251 static small_short *fv1;
252
253 static long *atk1, *atk2;
254
255 static long a1, a2;           
256                                                            
257
258 #define csquare(side,sq) ((side==black)?sq:(NO_SQUARES_1-sq))
259 #define crow(side,sq) row(csquare(side,sq))
260 #define ccolumn(side,sq) column(csquare(side,sq))
261
262 inline static short on_csquare(short side,short piece,short square)
263 { short sq;
264   return(board[sq=csquare(side,square)]==piece && color[sq]==side);
265 }
266     
267 inline static short on_column(short side,short piece,short c)
268 { short sq;
269   for (sq = c; sq < NO_SQUARES; sq+=9)
270     if (on_csquare(side,piece,sq))
271       return(true);
272   return(false);
273 }
274
275 #define empty_csquare(side,square)\
276   (board[csquare(side,square)]==no_piece)
277
278 inline static short on_left_side(short side,short piece)
279 { short c;
280   for (c=0; c<4; c++)
281     if (on_column(side,piece,c))
282       return(true);
283   return(false);
284 }
285
286 inline static short on_right_side(short side,short piece)
287 { short c;
288   for (c=5; c<NO_COLS; c++)
289     if (on_column(side,piece,c))
290       return(true);
291   return(false);
292 }
293
294
295
296 short pscore[2];  /* piece score for each side */
297
298
299
300 #if defined DEBUG8 || defined DEBUG_EVAL
301
302
303 char *PieceStr[NO_PIECES] = 
304   { "no piece", "Pawn", "Lance", "Knight", "Silver", "Gold", "Bishop", "Rook",
305     "promoted Pawn", "promoted Lance", "promoted Knight", "promoted Silver",
306     "promoted Bishop", "promoted Rook", "King" };
307                                                
308
309 #if !defined SAVE_SVALUE
310
311 void
312 debug_svalue (FILE *D)
313
314   short r, c;
315
316   fprintf(D, "\nSVALUE\n");
317   for (r = (NO_ROWS-1); r >= 0; r--)
318     {
319         for (c = 0; c < NO_COLS; c++)
320             {
321               short sq = (r * NO_COLS) + c;
322               fprintf(D,"%5d",svalue[sq]);
323             }
324         fprintf (D, "\n");
325     }
326   fprintf (D, "\n");
327 }
328
329 #endif            
330
331                           
332 void
333 debug_table (FILE *D, small_short *table, char *s)
334
335   short r, c;
336
337   fprintf (D, "\n%s\n", s);
338   for (r = (NO_ROWS-1); r >= 0; r--)
339     {         
340         for (c = 0; c < NO_COLS; c++)
341             {
342               short sq = (r * NO_COLS) + c;
343               fprintf(D,"%5d",table[sq]);
344             }
345         fprintf (D, "\n");
346     }
347   fprintf (D, "\n");
348 }                                      
349
350
351 #endif           
352
353
354 void 
355 threats (short int side)
356 /*
357  * Fill array atak[side][] with info about ataks to a square.  Bits 16-31 are set
358  * if the piece (king..pawn) ataks the square.  Bits 0-15 contain a count of
359  * total ataks to the square.
360  * Fill array sseed[] with info about occupation by a seed piece.
361  */  
362 {                                                            
363   register short u, sq;
364   long int c; 
365   long int *a;
366 #ifdef SAVE_NEXTPOS
367   short d;
368 #else
369   register unsigned char far *ppos, *pdir;
370 #endif
371   short i, kd, piece, xside; 
372   small_short *PL;
373
374   if ( MatchSignature(threats_signature[side]) ) {
375     /* data valid for current positional signature */
376     return;
377   }
378
379   a = atak[side];
380   xside = side ^ 1;
381
382   array_zero (a, NO_SQUARES * sizeof(a[0]));
383
384   PL = PieceList[side];
385   for (i = PieceCnt[side]; i >= 0; i--)
386     { short ptyp;
387       sq = PL[i];
388       piece = board[sq];
389       ptyp = ptype[side][piece];
390       c = control[piece];
391 #ifdef SAVE_NEXTPOS
392       u = first_direction(ptyp,&d,sq);
393 #else
394       ppos = (*nextpos[ptyp])[sq];
395       pdir = (*nextdir[ptyp])[sq];
396       u = ppos[sq];
397 #endif
398       do {
399           a[u] = ((a[u]+1) | c);
400           if ( (kd = Kdist[xside][u]) < 2 ) {
401             sseed[sq] += 2 - kd;
402             seed[side]++;
403           }
404 #ifdef SAVE_NEXTPOS
405           u = ((color[u] == neutral) ? next_position(ptyp,&d,sq,u)
406                                      : next_direction(ptyp,&d,sq));
407 #else
408           u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
409 #endif
410       } while (u != sq);
411    }
412    
413    /* data valid for current positional signature */
414    CopySignature(threats_signature[side]);
415 }
416
417
418 /* 
419  * Compute the board square with nunmap offset "id".
420  * If side==white, offset is negated.
421  * inunmap[sq] is the corresponding nunmap index isq.
422  * nunmap[isq+id] computes the board square. If negative,
423  * it is outside the board.
424  */ 
425
426 static void add_target (short sq, short side, short id)
427 {               
428   short isq,tsq,xside; 
429   isq = inunmap[sq];
430   tsq = (side == black) ? nunmap[isq+id] : nunmap[isq-id];
431   if ( tsq >= 0 ) {
432     target[xside = side^1]++;
433     if ( atak[side][tsq] )
434       starget[xside][tsq]++;  /* protected target square */                   
435     else
436       starget[xside][tsq]+=2; /* unprotected target square */                   
437   }
438 }
439    
440
441 /*
442  * Target squares can be vertically ahead, diagonally ahead
443  * or diagonally behind.
444  */
445
446 static void CheckTargetPiece (short sq, short side)
447 {
448   switch ( board[sq] ) {
449     case pawn: /* vertically ahead if unprotected */
450         if ( !atak[side][sq] )  
451           add_target(sq,side,11);
452         break;
453     case king: /* diagonally and vertically ahead */
454         add_target(sq,side,10);
455         add_target(sq,side,11);
456         add_target(sq,side,12);
457         break;
458     case rook: /* diagonally ahead and behind */
459         add_target(sq,side,10);
460         add_target(sq,side,12);
461         add_target(sq,side,-10);
462         add_target(sq,side,-12);
463         break;
464     case bishop: /* vertically ahead */
465         add_target(sq,side,11);
466         break;
467     case knight: /* vertically ahead if advanced */
468         if ( sq != 1 && sq != 7 && sq != 73 && sq != 79 )  
469           add_target(sq,side,11);
470         break;
471   }
472 }
473
474
475
476 static
477 ScoreKingOpeningFeatures (void)
478 {
479   short s = 0, sq = OwnKing, ds;
480   
481   if ( GameType[c1] == STATIC_ROOK ) {
482     /* Malus for king on right side or fifth file */
483     short c;
484     c = 4 - ccolumn(c1,sq);
485     if ( c < 0 || (c == 0 && sq != kingP[c1]) ) {
486       s += (ds = -c - c - fv1[OPENWRONG]);
487 #ifdef DEBUG_EVAL
488       if ( debug_eval )
489         fprintf(debug_eval_file,"%d for king on right side (Static)\n",ds);
490 #endif
491       }
492   } else if ( GameType[c1] == RANGING_ROOK ) {
493     /* Malus for king on left side or fifth file */
494     short c;
495     c = 4 - ccolumn(c1,sq);
496     if ( c > 0 || (c == 0 && sq != kingP[c1]) ) {
497       s += (ds = -c - c - fv1[OPENWRONG]);
498 #ifdef DEBUG_EVAL
499             if ( debug_eval )
500                 fprintf(debug_eval_file,"%d for king on left side (Ranging)\n",ds);
501 #endif
502     }
503     /* Malus for king moved before rook switch */
504     if ( sq != kingP[c1] ) {
505       if ( on_csquare(c1,rook,16) ) {
506         s += (ds = -4 * fv1[OPENWRONG]);         
507 #ifdef DEBUG_EVAL
508         if ( debug_eval )
509           fprintf(debug_eval_file,"%d for king moved before rook switch (Ranging)\n",ds);
510 #endif
511         }
512       } else {
513         /* Malus for sitting king after rook switch */
514         if ( !on_csquare(c1,rook,16) ) {
515           s += (ds = -2 * fv1[OPENWRONG]);
516 #ifdef DEBUG_EVAL
517           if ( debug_eval )
518             fprintf(debug_eval_file,"%d for sitting king after rook switch (Ranging)\n",ds);
519 #endif  
520         }
521       }
522       /* Malus for defending general moved before king switch to right side */
523       if ( ccolumn(c1,sq) < 6 ) {
524         if ( Mvboard[csquare(c1,5)] || Mvboard[csquare(c1,6)] ) {
525           s += (ds = -2 * fv1[OPENWRONG]);         
526 #ifdef DEBUG_EVAL
527           if ( debug_eval )
528             fprintf(debug_eval_file,"%d for defending general moved before king switch (Ranging)\n",ds);
529 #endif
530       }
531     }
532   }
533   return s;
534 }
535
536
537 inline
538 static
539 ExamineSquares (void)
540
541 {
542   register short sq, side, piece, n;
543
544   if ( MatchSignature(squares_signature) ) {
545     /* data valid for current positional signature */
546     return;
547   }
548
549   array_zero(shole,sizeof(shole));
550   array_zero(sloose,sizeof(sloose));
551   array_zero(starget,sizeof(starget));
552   
553   hole[0] = hole[1] = loose[0] = loose[1] = target[0] = target[1] = 0;
554
555   for ( sq = 0; sq < NO_SQUARES; sq++ )
556     {
557         if ( (side = color[sq]) == neutral )
558           {
559             if ( InWhiteCamp(sq) ) {
560                if ( !atak[white][sq] ) {
561                   shole[sq] = 1;
562                   hole[white]++;
563                }
564             } else if ( InBlackCamp(sq) ) {
565                if ( !atak[black][sq] ) {
566                   shole[sq] = 1;
567                   hole[black]++;
568                }
569             }        
570           }
571         else 
572           { /* occupied by "side" piece */
573             if ( !atak[side][sq] ) {
574               sloose[sq] = 1;
575               loose[side]++;
576             }
577             CheckTargetPiece(sq,side);
578           }
579     }
580
581 #ifdef DEBUG_EVAL
582     if ( debug_eval ) {
583       char buffer[80];
584       debug_position (debug_eval_file);
585       debug_ataks (debug_eval_file, atak[black]);
586       debug_ataks (debug_eval_file, atak[white]);
587       sprintf(buffer,"%d Black and %d White SEED PIECES",seed[black],seed[white]);
588       debug_table (debug_eval_file,sseed,buffer);
589       sprintf(buffer,"%d Black TARGETS",target[black]);
590       debug_table (debug_eval_file,starget[black],buffer);
591       sprintf(buffer,"%d White TARGETS",target[white]);
592       debug_table (debug_eval_file,starget[white],buffer);
593       sprintf(buffer,"%d Black and %d White LOOSE PIECES",loose[black],loose[white]);
594       debug_table (debug_eval_file,sloose,buffer);
595       sprintf(buffer,"%d Black and %d White HOLES",hole[black], hole[white]);                   
596       debug_table (debug_eval_file,shole,buffer);
597     }
598 #endif
599
600   for ( side=black; side<=white; side++ ) {
601     captured[side] = dcaptured[side] = 0;
602     for ( piece = pawn; piece <= rook; piece++ ) {
603         if ( (n = Captured[side][piece]) != 0 ) {
604           if ( piece != pawn ) 
605             captured[side] += n; 
606           dcaptured[side]++;
607         }
608     }
609 #ifdef DEBUG_EVAL
610     if ( debug_eval ) {
611         fprintf(debug_eval_file,"%s captured=%d dcaptured=%d\n",
612                         ColorStr[side],captured[side], dcaptured[side]);
613     }
614 #endif
615   }
616                                         
617   /* Data valid for current positional signature */
618   CopySignature(squares_signature);
619 }                 
620
621
622
623 /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
624
625 /*
626  * Inputs are:
627  * mtl[side]  - value of all material
628  * hung[side] - count of hung pieces
629  * Tscore[ply] - search tree score for ply ply
630  * Pscore[ply] - positional score for ply ply
631  * INCscore    - bonus score or penalty for certain moves
632  * Sdepth - search goal depth
633  * xwndw - evaluation window about alpha/beta
634  * EWNDW - second evaluation window about alpha/beta
635  * ChkFlag[ply]- checking piece at level ply or 0 if no check
636  * TesujiFlag[ply]- 1 if tesuji move at level ply or 0 if no tesuji
637  * PC1[column] - # of my pawns in this column
638  * PC2[column] - # of opponents pawns in column
639  * PieceCnt[side] - just what it says
640  */
641
642
643
644 int
645 evaluate (register short int side,
646           register short int ply,
647           register short int alpha,
648           register short int beta,
649           short int INCscore,
650           short int *InChk,     /* output Check flag */
651           short int *blockable) /* king threat blockable */
652
653 /*
654  * Compute an estimate of the score by adding the positional score from the
655  * previous ply to the material difference. If this score falls inside a
656  * window which is 180 points wider than the alpha-beta window (or within a
657  * 50 point window during quiescence search) call ScorePosition() to
658  * determine a score, otherwise return the estimated score. 
659  * "side" has to moved.
660  */
661
662 {
663     register short evflag, xside;
664     short s, sq;
665
666     xside = side ^ 1;
667     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] /* - INCscore */;
668
669 #ifdef DEBUG_EVAL
670     if ( debug_eval )
671       fprintf (debug_eval_file, "estimated score at ply %d:%d, -%d+%d-%d-%d\n",
672         ply, s, Pscore[ply-1], mtl[side], mtl[xside], INCscore );
673 #endif
674
675     hung[black] = hung[white] = 0;
676
677     /* should we use the estimete or score the position */
678     if ( (ply == 1) ||
679          (ply == Sdepth) ||
680          (ply > Sdepth && s >= (alpha - 30) && s <= (beta + 30))
681 #ifdef CACHE
682         || (use_etable && CheckEETable (side))
683 #endif   
684                                                          )
685       { short sq;
686         /* score the position */
687 #ifdef DEBUG_EVAL
688         if ( debug_eval )
689           fprintf (debug_eval_file, "do NOT use the estimete\n");
690 #endif
691         array_zero (sseed, sizeof(sseed));
692
693         seed[0] = seed[1] = 0;
694         threats (side);
695         if (Anyatak (side, sq=PieceList[xside][0]) && board[sq] == king) {
696           *InChk = (board[sq=PieceList[side][0]] == king) ? SqAtakd (sq, xside, blockable) : false;
697           return ((SCORE_LIMIT+1001) - ply);
698         }
699         threats (xside);
700         *InChk = (board[sq=PieceList[side][0]] == king) ? Anyatak (xside, sq) : false;
701         *blockable = true;
702 #ifndef BAREBONES 
703         EvalNodes++;
704 #endif    
705         if ( ply > 4 )       
706           PUTVAR=true;
707         ExamineSquares();
708         s = ScorePosition (side);
709         PUTVAR = false;
710       }
711     else
712       {
713         /* use the estimate but look at check */
714         short sq;
715 #ifdef DEBUG_EVAL
716         if ( debug_eval )
717           fprintf (debug_eval_file, "use the estimete\n");
718 #endif
719         *InChk = (board[sq=PieceList[side][0]] == king) ? SqAtakd (sq, xside, blockable) : false; 
720         if ( board[sq=PieceList[xside][0]] == king && SqAtakd (sq, side, blockable) ) {
721           return ((SCORE_LIMIT+1001) - ply);
722         }
723       }
724
725     Pscore[ply] = s - mtl[side] + mtl[xside];
726     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] : 0);
727     return (s);
728 }       
729
730
731 static short value_of_weakest_attacker (long a2)
732 {     
733   register short piece;  
734   short min_value, v;
735   min_value = SCORE_LIMIT;
736   for ( piece = pawn; piece <= king; piece++ )
737     if ( control[piece] & a2 )
738       { 
739         if ( min_value > (v = (*value)[stage][piece]) )
740           min_value = v;                            
741       } 
742   return min_value;
743 }
744
745
746 inline
747 int
748 BRLscan (register short int sq, short int *mob)
749
750 /*
751  * Find (promoted) Bishop, (promoted) Rook, and Lance mobility, XRAY attacks, and pins. 
752  * Let BRL be the bishop, rook, or lance.
753  * Let P be the first piece (no king and no pawn) in a direction and let Q be the second
754  * piece in the same direction. If Q is an unprotected opponent's piece with 
755  * bigger relative value than BRL, there is a pin if P is an opponent's piece and
756  * there is an XRAY attack if P is an own piece.
757  * Increment the hung[] array if a pin is found.
758  */
759 {
760 #ifdef SAVE_NEXTPOS
761     short d, dd;
762 #else
763     register unsigned char far *ppos, *pdir;
764 #endif
765     register short s, mobx;
766     register short u, xu, pin, ptyp, csq = column(sq);
767     short piece, upiece, xupiece, rvalue, ds;
768     small_short *Kd = Kdist[c2];
769     mobx = s = 0;
770     piece = board[sq];
771
772     rvalue = (*value)[stage][piece];
773     ptyp = ptype[c1][upiece = unpromoted[piece]];
774     rvalue = (*value)[stage][upiece];
775 #ifdef SAVE_NEXTPOS
776     u = first_direction(ptyp,&d,sq);
777 #else
778     ppos = (*nextpos[ptyp])[sq];
779     pdir = (*nextdir[ptyp])[sq];
780     u = ppos[sq];                         
781 #endif
782     pin = -1;                   /* start new direction */
783     do
784       {
785           if ( Kd[u] < 2 ) {
786             s += (ds = fv1[CTRLK] * (2-Kd[u]));
787 #ifdef DEBUG_EVAL
788             if ( debug_eval )
789               fprintf(debug_eval_file,"%d for threatening square %d away from enemy king\n",
790                         ds, Kd[u]);
791 #endif
792           }
793           if ( (ds = starget[c1][u]) != 0 ) {
794             /* threatening a target square */
795             if ( pin < 0 || /* direct threat */
796                  color[pin] == c2 ) /* pin threat */ {
797               s += (ds *= fv1[TARGET]);
798 #ifdef DEBUG_EVAL
799               if ( debug_eval )
800                 fprintf(debug_eval_file,"%d for threatening target square\n",ds);
801 #endif       
802             }
803           }
804           if ( (ds = shole[u]) != 0 ) {
805             /* attacking or protecting a hole */
806             s += (ds = fv1[HOLES]);
807 #ifdef DEBUG_EVAL
808             if ( debug_eval )
809               fprintf(debug_eval_file,"%d for threatening a hole\n",ds);
810 #endif
811           } else if ( InPromotionZone(c1,u) ) {
812             /* attacking a square in promotion zone */
813             s += (ds = fv1[HOLES] / 2);
814 #ifdef DEBUG_EVAL
815             if ( debug_eval )
816               fprintf(debug_eval_file,"%d for threatening promotion zone\n",ds);
817 #endif
818           }
819           if (color[u] == neutral)
820             {
821 #ifdef SAVE_NEXTPOS
822                 dd = d;
823                 xu = next_position(ptyp,&d,sq,u);
824                 if ( xu == next_direction(ptyp,&dd,sq) )
825                     pin = -1;   /* oops new direction */
826 #else
827                 if ((xu = ppos[u]) == pdir[u])
828                     pin = -1;   /* oops new direction */
829 #endif
830                 u = xu;
831                 mobx++;
832             }
833           else 
834             {   /* there is a piece in current direction */
835                 if (pin < 0)
836                     {   /* it's the first piece in the current direction */
837 #ifdef DEBUG_EVAL
838                         if ( debug_eval )
839                           fprintf(debug_eval_file, 
840                             "first piece on square %d is an %s piece\n",
841                                 u, (color[u]==c1) ? "own" : "enemy");
842 #endif
843                         if ( color[u] == c1 ) {
844                           /* own intercepting piece in xray attack */
845                           if ( upiece == lance ) {
846                             /* lance xray */
847                             if ( board[u] == pawn ) {
848                                 s += (ds = 2*fv1[PROTECT]);
849 #ifdef DEBUG_EVAL
850                                 if ( debug_eval )
851                                   fprintf(debug_eval_file,"%d for lance protecting pawn\n",ds);
852 #endif
853                             } else if ( in_opening_stage ) {
854                                 s += (ds = -2*fv1[PROTECT]);
855 #ifdef DEBUG_EVAL
856                                 if ( debug_eval )
857                                   fprintf(debug_eval_file,"%d for lance protecting non-pawn\n",ds);
858 #endif
859                             }
860                           } else {
861                             /* bishop or rook xray */
862                             if ( upiece == bishop && board[u] == pawn && GameType[c1] == STATIC_ROOK ) {
863                                   s += (ds = -2*fv1[HCLSD]); 
864 #ifdef DEBUG_EVAL
865                                   if ( debug_eval )
866                                     fprintf(debug_eval_file,"%d for own pawn in bishops direction\n",ds);
867 #endif
868                             } else if ( upiece == rook && board[u] == lance && GameType[c1] == STATIC_ROOK && column(u) == csq) {
869                                   s += (ds = fv1[XRAY]); 
870 #ifdef DEBUG_EVAL
871                                   if ( debug_eval )
872                                     fprintf(debug_eval_file,"%d for lance supported by rook\n",ds);
873 #endif
874                             }
875                           }
876                         } else {
877                           /* enemy's intercepting piece in pin attack */
878                           if ( upiece == lance ) {
879                             /* lance pin attack */
880                             if ( board[u] == pawn ) {
881                                 s += (ds = -2*fv1[PROTECT]);
882 #ifdef DEBUG_EVAL
883                                 if ( debug_eval )
884                                   fprintf(debug_eval_file,"%d for lance attacking pawn\n",ds);
885 #endif
886                             } else if ( in_opening_stage ) {
887                                 s += (ds = 2*fv1[PROTECT]);
888 #ifdef DEBUG_EVAL
889                                 if ( debug_eval )
890                                   fprintf(debug_eval_file,"%d for lance attacking non-pawn\n",ds);
891 #endif
892                             }
893                           } else {
894                             /* bishop or rook pin attack */
895                             if ( board[u] == pawn ) {
896                                   s += (ds = -fv1[HCLSD]); 
897 #ifdef DEBUG_EVAL
898                                   if ( debug_eval )
899                                     fprintf(debug_eval_file,"%d for enemy pawn in bishops direction\n",ds);
900 #endif
901                             }
902                           }
903                         }
904 #ifdef SAVE_NEXTPOS
905                         dd = d;
906                         xu = next_position(ptyp,&d,sq,u);
907                         if ( xu != next_direction(ptyp,&dd,sq) )
908                             pin = u;    /* not on the edge and on to find a pin */
909 #else
910                         if ((xu = ppos[u]) != pdir[u])
911                             pin = u;    /* not on the edge and on to find a pin */
912 #endif
913                         u = xu;
914                     }
915                 else
916                     {
917                         /* it's the second piece in the current direction */
918 #ifdef DEBUG_EVAL
919                         if ( debug_eval )
920                           fprintf(debug_eval_file, 
921                             "second piece on square %d is an %s piece\n",
922                                 u, (color[u]==c1) ? "own" : "enemy");
923 #endif
924                         if ( color[u] == c1 ) {
925                           /* second piece is an own piece */
926                           if ( upiece == bishop && board[u] == pawn && GameType[c1] == STATIC_ROOK ) {
927                             s += (ds = -fv1[HCLSD]); 
928 #ifdef DEBUG_EVAL
929                             if (debug_eval )
930                               fprintf(debug_eval_file,"%d for own pawn in bishops (2) direction\n",ds);
931 #endif
932                           }
933                         } else {
934                           /* second piece is an enemy piece */
935                           if ( upiece == bishop && board[u] == pawn ) {
936                             s += (ds = -fv1[HCLSD]/2); 
937 #ifdef DEBUG_EVAL
938                             if (debug_eval )
939                               fprintf(debug_eval_file,"%d for enemy pawn in bishops (2) direction\n",ds);
940 #endif
941                           }
942                           if ((*value)[stage][xupiece = unpromoted[board[u]]] > rvalue || atk2[u] == 0) {
943 #ifdef DEBUG_EVAL
944                               if ( debug_eval )
945                                 fprintf(debug_eval_file,"enemy %s better than attacking %s\n",
946                                         PieceStr[upiece], PieceStr[xupiece]);
947 #endif
948                             if (color[pin] == c2) {
949                               if ( xupiece == king && in_endgame_stage ) {
950                                 s += (ds = 2*fv1[PINVAL]);
951 #ifdef DEBUG_EVAL
952                                 if ( debug_eval && ds )
953                                   fprintf(debug_eval_file,"%d for pin attack to king\n",ds);
954 #endif
955                               } else { 
956                                 s += (ds = fv1[PINVAL]);
957 #ifdef DEBUG_EVAL
958                                 if ( debug_eval && ds )
959                                   fprintf(debug_eval_file,"%d for pin attack\n",ds);
960 #endif
961                               }
962                               if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1) {
963                                 hung[c2]++;
964                                 shung[u]++;
965                               }
966                             } else {
967                               if ( upiece == lance ) {
968                                 s += (ds = fv1[XRAY]/2);
969 #ifdef DEBUG_EVAL   
970                                 if ( debug_eval && ds )
971                                   fprintf(debug_eval_file,"lance xray attack: %d\n",ds);
972 #endif
973                               } else {
974                                 s += (ds = fv1[XRAY]); 
975 #ifdef DEBUG_EVAL                     
976                                 if ( debug_eval )
977                                   fprintf(debug_eval_file,"bishop/rook xray attack: %d\n",ds);
978 #endif          
979                               }
980                             }
981                           }
982                         }
983                         pin = -1;       /* new direction */
984 #ifdef SAVE_NEXTPOS
985                         u = next_direction(ptyp,&d,sq);
986 #else
987                         u = pdir[u];
988 #endif
989                     }
990             }
991       }
992     while (u != sq);
993     *mob = mobx;
994     return s;
995 }                             
996
997
998
999 #define ctlSG (ctlS | ctlG | ctlPp | ctlLp | ctlNp | ctlSp)
1000
1001
1002 inline
1003 short int
1004 KingScan (register short int sq)
1005
1006 /*
1007  * Assign penalties if king can be threatened by checks, if squares near the
1008  * king are controlled by the enemy (especially by promoted pieces), 
1009  * or if there are no own generals near the king. 
1010  * The following must be true: 
1011  *    board[sq] == king, c1 == color[sq], c2 == otherside[c1]
1012  */
1013
1014                  
1015 #ifdef DEBUG_EVAL
1016
1017 #define ScoreThreat \
1018         { if (color[u] != c2)\
1019           if (atk1[u] == 0 || (atk2[u] & CNT_MASK) > 1) {\
1020             ++cnt;\
1021           } else {\
1022             s += (ds = -fv1[CTRLK]);\
1023             if ( debug_eval ) \
1024               fprintf(debug_eval_file,"%d for squares near king controlled by enemy %s\n",\
1025                         ds, PieceStr[p]);\
1026           }\
1027         }
1028
1029 #else
1030
1031 #define ScoreThreat \
1032         { if (color[u] != c2)\
1033           if (atk1[u] == 0 || (atk2[u] & CNT_MASK) > 1) {\
1034             ++cnt;\
1035           } else {\
1036             s += (ds = -fv1[CTRLK]);\
1037           }\
1038         }
1039
1040 #endif
1041
1042
1043 {
1044     register short cnt;
1045 #ifdef SAVE_NEXTPOS
1046     short d;
1047 #else
1048     register unsigned char far *ppos, *pdir;
1049 #endif
1050     register short int s;
1051     register short u, ptyp;
1052     short int ok, ds;
1053 #ifdef DEBUG_EVAL
1054     short s0;
1055 #endif
1056
1057     /* Penalties, if a king can be threatened by checks. */      
1058
1059     s = 0;
1060     cnt = 0;
1061     { short p;
1062       for ( p = pawn; p < king; p++ )
1063         if ( HasPiece[c2][p] || Captured[c2][p] )
1064           { short ptyp;
1065             /* if a c1 piece can reach u from sq, 
1066              * then a c2 piece can reach sq from u.
1067              * That means, each u is a square, from which a 
1068              * piece of type p and color c2 threats square sq.
1069              */
1070             ptyp = ptype[c1][p];
1071 #ifdef SAVE_NEXTPOS
1072             u = first_direction(ptyp,&d,sq);
1073 #else
1074             ppos = (*nextpos[ptyp])[sq];
1075             pdir = (*nextdir[ptyp])[sq];
1076             u = ppos[sq];
1077 #endif
1078             do
1079               {  
1080                 /* If a p piece can reach (controls or can drop to)  
1081                  * square u, then score threat. 
1082                  */
1083                 if (atk2[u] & control[p])
1084                     ScoreThreat
1085                 else if (Captured[c2][p] && color[u] == neutral)
1086                     ScoreThreat
1087 #ifdef SAVE_NEXTPOS
1088                 u = ((color[u] == neutral) ? next_position(ptyp,&d,sq,u)
1089                                            : next_direction(ptyp,&d,sq));
1090 #else
1091                 u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
1092 #endif
1093               }
1094             while (u != sq);
1095           }
1096     }
1097     s += (ds = fv1[KSFTY] * KTHRT[cnt] / 16);
1098
1099 #ifdef DEBUG_EVAL
1100     if ( debug_eval && ds )
1101        fprintf(debug_eval_file,"%d for possible king threats\n",ds);
1102 #endif                        
1103
1104     /* Penalties, if squares near king are controlled by enemy. */
1105
1106     cnt = 0;
1107     ok = false;
1108     ptyp = ptype[c1][king];
1109 #ifdef SAVE_NEXTPOS
1110     u = first_direction(ptyp,&d,sq);
1111 #else
1112     pdir = (*nextpos[ptyp])[sq];
1113     u = pdir[sq];
1114 #endif
1115     do
1116       {   
1117           if ( !ok && color[u] == c1 ) 
1118             {
1119               short ptype_piece = ptype[black][board[u]];
1120               if ( ptype_piece == ptype_silver || ptype_piece == ptype_gold )
1121                 ok = true;
1122             }
1123           if (atk2[u] > atk1[u])
1124             {
1125                 ++cnt;
1126                 if (atk2[u] & ctlSG) {
1127                   s += (ds = -fv1[KSFTY]/2);             
1128 #ifdef DEBUG_EVAL
1129                   if (debug_eval )
1130                     fprintf(debug_eval_file,"%d square controlled by near enemy silver or gold\n",ds);
1131 #endif                        
1132                 }
1133             }
1134 #ifdef SAVE_NEXTPOS
1135           u = next_direction(ptyp,&d,sq);
1136 #else
1137           u = pdir[u];
1138 #endif
1139       }
1140     while (u != sq); 
1141     if ( !ok || cnt > 1) { 
1142         if ( cnt > 1 ) 
1143           s += (ds = -fv1[KSFTY]/2);
1144         else
1145           s += (ds = -fv1[KSFTY]);
1146 #ifdef DEBUG_EVAL
1147         if (debug_eval )
1148           if ( !ok )
1149             fprintf(debug_eval_file,"%d for no general protect king\n",ds);
1150           else
1151             fprintf(debug_eval_file,"%d for %d enemy generals dear king\n",cnt,ds);
1152 #endif                        
1153     }
1154
1155     return (s);
1156 }
1157
1158
1159 static short checked_trapped;
1160
1161
1162 inline
1163 int
1164 trapped (register short int sq)
1165
1166 /*
1167  * See if the attacked piece has unattacked squares to move to. The following
1168  * must be true: c1 == color[sq] c2 == otherside[c1]
1169  */
1170
1171 {
1172     register short u, ptyp;
1173 #ifdef SAVE_NEXTPOS
1174     short d;
1175 #else
1176     register unsigned char far *ppos, *pdir;
1177 #endif
1178     register short int piece;
1179     short rvalue;
1180
1181     piece = board[sq];
1182     rvalue = (*value)[stage][piece];
1183     ptyp = ptype[c1][piece];
1184 #ifdef SAVE_NEXTPOS
1185     u = first_direction(ptyp,&d,sq);
1186 #else
1187     ppos = (*nextpos[ptyp])[sq];
1188     pdir = (*nextdir[ptyp])[sq];
1189     u = ppos[sq];
1190 #endif
1191     do {
1192         if (color[u] != c1)
1193             if (atk2[u] == 0 || (*value)[stage][board[u]] >= rvalue)
1194               return (false);
1195 #ifdef SAVE_NEXTPOS
1196         u = ((color[u] == neutral) ? next_position(ptyp,&d,sq,u)
1197                                    : next_direction(ptyp,&d,sq));
1198 #else
1199         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
1200 #endif
1201     } while (u != sq);
1202 #ifdef DEBUG_EVAL
1203     if ( debug_eval )
1204       fprintf(debug_eval_file,"piece is trapped\n");
1205 #endif                             
1206     checked_trapped = true;
1207
1208     return (true);
1209 }                         
1210
1211
1212
1213 static int AttackedPieceValue (register short int sq, short int side)
1214 {              
1215    short s, ds;
1216
1217    s = 0;     
1218
1219    ds += (ds = -fv1[HUNGP]);
1220    hung[c1]++;
1221    shung[sq]++;
1222 #ifdef DEBUG_EVAL
1223    if ( debug_eval )
1224       fprintf(debug_eval_file,"attacked: %d, hung[%s]++\n", 
1225         ds, ColorStr[c1]);
1226 #endif
1227
1228    if (trapped (sq))
1229      {
1230        hung[c1] += 2;
1231        shung[sq] += 2;
1232 #ifdef DEBUG_EVAL
1233        if ( debug_eval )
1234           fprintf(debug_eval_file,"trapped: hung[%s] += 2\n",
1235                 ColorStr[c1]);
1236 #endif
1237    }
1238
1239    return s; 
1240 }
1241
1242
1243
1244 static inline int
1245 OpenFileValue (register short sq, short hopn, short hopnx)
1246 {
1247     short s=0, fyle;
1248
1249     if (PC1[fyle = column(sq)] == 0)
1250       {
1251         s += hopn;
1252 #ifdef DEBUG_EVAL
1253         if (debug_eval && hopn)
1254           fprintf(debug_eval_file,"adding %d for now own pawn on file\n",hopn);
1255 #endif
1256       } 
1257
1258     if (PC2[fyle] == 0)
1259       {
1260         s += hopnx;
1261 #ifdef DEBUG_EVAL
1262         if (debug_eval && hopnx)
1263           fprintf(debug_eval_file,"%d for no opponents pawn on file\n",hopnx);
1264 #endif
1265       }
1266
1267     return s;
1268 }
1269   
1270
1271 /* Distance bonus */
1272
1273 #ifdef DEBUG_EVAL
1274
1275 #define PromotionZoneDistanceValue(sq,dd)\
1276     if ( ds = fv1[PROMD] ) { \
1277       s += (ds = ds * PromotionZoneDistanceBonus[crow(c1,sq)] * dd);\
1278       if (debug_eval && ds) \
1279         fprintf(debug_eval_file,"%d for distance to promotion zone\n",ds); \
1280     }                            
1281
1282 #else
1283
1284 #define PromotionZoneDistanceValue(sq,dd)\
1285     if ( ds = fv1[PROMD] ) { \
1286       s += (ds = ds * PromotionZoneDistanceBonus[crow(c1,sq)] * dd);\
1287     }                            
1288
1289 #endif
1290      
1291
1292 #ifdef DEBUG_EVAL
1293
1294 #define OwnKingDistanceValue(sq,dd,maxd)\
1295     if ( (ds = fv1[KINGOD]) && ((ad = Kdist[c1][sq]) <= maxd) ) { \
1296       s += (ds = ds * OwnKingDistanceBonus[ad] * dd);\
1297       if (debug_eval && ds) \
1298         fprintf(debug_eval_file,"%d for distance to own king\n",ds); \
1299     }                            
1300
1301 #else
1302
1303 #define OwnKingDistanceValue(sq,dd,maxd)\
1304     if ( (ds = fv1[KINGOD]) && ((ad = Kdist[c1][sq]) <= maxd) ) { \
1305       s += (ds = ds * OwnKingDistanceBonus[ad] * dd);\
1306     }                            
1307
1308 #endif
1309      
1310
1311 #ifdef DEBUG_EVAL
1312
1313 #define EnemyKingDistanceValue(sq,dd,maxd)\
1314     if ( (ds = fv1[KINGOD]) && ((ad = Kdist[c2][sq]) <= maxd) ) { \
1315       s += (ds = ds * EnemyKingDistanceBonus[ad] * dd);\
1316       if (debug_eval && ds) \
1317         fprintf(debug_eval_file,"%d for distance to enemy king\n",ds); \
1318     }                            
1319
1320 #else
1321
1322 #define EnemyKingDistanceValue(sq,dd,maxd)\
1323     if ( (ds = fv1[KINGOD]) && ((ad = Kdist[c2][sq]) <= maxd) ) { \
1324       s += (ds = ds * EnemyKingDistanceBonus[ad] * dd);\
1325     }                            
1326
1327 #endif                  
1328
1329
1330
1331
1332 static inline int
1333 PawnValue (register short int sq, short int side)
1334 /*
1335  * Calculate the positional value for a pawn on 'sq'.
1336  */
1337
1338 {
1339     register short s=0;
1340     short ds;
1341     short n;
1342     short ccol = ccolumn(c1,sq);  
1343             
1344     PromotionZoneDistanceValue(sq,3);        
1345
1346     /* pawn mobility */
1347     if ( color[(c1==black)?(sq+9):(sq-9)] == neutral ) {
1348       s += (ds = MBLTY[pawn]);
1349 #ifdef DEBUG_EVAL
1350       if ( debug_eval && ds )
1351         fprintf(debug_eval_file,"%d for mobility\n", ds);
1352 #endif       
1353     }
1354     
1355     if ( (a1 & ((ctlR | ctlRp) | ctlL)) ) {
1356       s += (ds = fv1[ATAKD]);
1357 #ifdef DEBUG_EVAL
1358       if ( debug_eval && ds )
1359         fprintf(debug_eval_file,"%d for rook/lance-supported pawn\n",ds);
1360 #endif
1361     }         
1362
1363     if ( in_opening_stage ) {
1364
1365       if ( crow(c1,sq) == 2 ) /* pawn on 3d rank */
1366         if ( board[(c1==black)?(sq+27):(sq-27)] == pawn )
1367           {  /* opposing pawn has been moved (even column == (sq & 1)) */
1368              short m;
1369              switch ( ccol ) {
1370                case 0: case 8: m = ( side == c1 ) ? 3 : 5; break;
1371                case 4: m = ( side == c1 ) ? 2 : 3; break;
1372                default:m = ( side == c1 ) ? 1 : 2; break;
1373              }
1374              s += (ds = -m*MBLTY[pawn]);
1375 #ifdef DEBUG_EVAL
1376              if ( debug_eval && ds )
1377                fprintf(debug_eval_file,"%d for opposing pawn pushed\n",ds);
1378 #endif         
1379           }
1380
1381       if ( GameType[c1] == STATIC_ROOK && sq == csquare(c1,43) )
1382         if ( (atk2[csquare(c1,52)] & CNT_MASK) < 2 ) 
1383           {
1384              s += (ds = fv1[ATAKD]);
1385 #ifdef DEBUG_EVAL
1386              if ( debug_eval )
1387                fprintf(debug_eval_file,"%d for attacking pawn on 2nd col\n",ds);
1388 #endif         
1389           }  
1390
1391       if ( GameType[c2] == STATIC_ROOK && ccol == 1 ) 
1392         {
1393           if ( sq == csquare(c1,28) )
1394             {
1395               s += (ds = -fv1[ATAKD]);
1396 #ifdef DEBUG_EVAL
1397               if ( debug_eval )
1398                 fprintf(debug_eval_file,"%d for pushed pawn on 8th file\n",ds);
1399 #endif         
1400             }
1401           if ( (atk1[csquare(c1,19)] & CNT_MASK) < 2 && (atk1[csquare(c1,28)] & CNT_MASK) < 2 ) 
1402             {   
1403               s += (ds = -2*fv1[ATAKD]);
1404 #ifdef DEBUG_EVAL
1405               if ( debug_eval )
1406                 fprintf(debug_eval_file,"%d for weak pawn on 8th col\n",ds);
1407 #endif         
1408             }
1409         } 
1410
1411     }
1412
1413     return (s);
1414 }
1415
1416
1417 static inline int
1418 LanceValue (register short int sq, short int side)
1419 /*
1420  * Calculate the positional value for a lance on 'sq'.
1421  */
1422
1423 {
1424     register short s=0, ds, ad;
1425
1426     OwnKingDistanceValue(sq,1,2);
1427
1428     OpenFileValue (sq, -fv1[HOPN], fv1[HOPN]);
1429
1430     if ( !checked_trapped && crow(c1,sq) > 2 )
1431       {          
1432         if (in_opening_stage || trapped (sq))
1433           {
1434             s += (ds = -3*fv1[ATAKD]);
1435 #ifdef DEBUG_EVAL     
1436             if ( debug_eval )
1437                 fprintf(debug_eval_file,"%d for lance in danger\n",ds);
1438 #endif                             
1439           }
1440         else 
1441           {
1442             s += (ds = -2*fv1[ATAKD]);
1443 #ifdef DEBUG_EVAL     
1444             if ( debug_eval )
1445                 fprintf(debug_eval_file,"%d for lance in danger\n",ds);
1446 #endif                             
1447           }
1448       }
1449
1450     return (s);
1451 }
1452
1453 static inline int
1454 KnightValue (register short int sq, short int side)
1455 /*
1456  * Calculate the positional value for a knight on 'sq'.
1457  */
1458
1459 {
1460     register short s = 0, ad;
1461     short ds, checked_trapped = false;
1462     short c = column(sq);
1463
1464     PromotionZoneDistanceValue(sq,1);
1465     OwnKingDistanceValue(sq,1,2);
1466
1467     if ( !checked_trapped && crow(c1,sq) > 2 )
1468       {          
1469         if (trapped (sq))
1470           {
1471             s += (ds = -4*fv1[ATAKD]);
1472 #ifdef DEBUG_EVAL     
1473             if ( debug_eval )
1474                 fprintf(debug_eval_file,"%d for knight in danger\n",ds);
1475 #endif                             
1476           }
1477         else
1478           {
1479             s += (ds = -3*fv1[ATAKD]);
1480 #ifdef DEBUG_EVAL     
1481             if ( debug_eval && ds )
1482                 fprintf(debug_eval_file,"%d for knight in danger\n",ds);
1483 #endif                             
1484           }
1485       }
1486       
1487     if ( c == 0 || c == 8 ) {
1488       s += (ds = -fv1[ATAKD]);
1489 #ifdef DEBUG_EVAL
1490       if ( debug_eval )
1491         fprintf(debug_eval_file,"%d for knight on edge file\n",ds);
1492 #endif             
1493     }
1494
1495     return (s);
1496 }
1497
1498 static inline int
1499 SilverValue (register short int sq, short int side)
1500 /*
1501  * Calculate the positional value for a silver on 'sq'.
1502  */
1503
1504 {
1505     register short s= 0, ds, ad;
1506
1507     OwnKingDistanceValue(sq,2,3);
1508
1509     if ( Kdist[c1][sq] < 3 && (atk1[sq] & (control[gold] | control[silver])) ) {
1510         s += (ds = fv1[COHESION]);
1511 #ifdef DEBUG_EVAL
1512         if ( debug_eval )
1513           fprintf(debug_eval_file,"%d for good cohesion\n",ds);
1514 #endif             
1515     } 
1516
1517     if ( in_opening_stage ) {
1518       if ( GameType[c1] == STATIC_ROOK )
1519         if ( csquare(c1,sq) == 12 )
1520           {
1521             short csq;
1522             if ( board[csq = csquare(c1,20)] == bishop && color[csq] == c1 )
1523                 {
1524                   s += (ds = -2*fv1[OPENWRONG]);
1525 #ifdef DEBUG_EVAL
1526                   if ( debug_eval )
1527                     fprintf(debug_eval_file,"%d for wrong opening\n",ds);
1528 #endif             
1529                 }
1530           }   
1531     } else {
1532       EnemyKingDistanceValue(sq,2,3);
1533     }
1534
1535     return (s);
1536 }
1537
1538 static inline int
1539 GoldValue (register short int sq, short int side)
1540 /*
1541  * Calculate the positional value for a gold on 'sq'.
1542  */
1543
1544 {
1545     register short s=0, ds, ad;
1546
1547     OwnKingDistanceValue(sq,2,3);
1548
1549     if ( Kdist[c1][sq] < 3 && (atk1[sq] & (control[gold] | control[silver])) ) {
1550         s += (ds = fv1[COHESION]);
1551 #ifdef DEBUG_EVAL
1552         if ( debug_eval )
1553           fprintf(debug_eval_file,"%d for good cohesion\n",ds);
1554 #endif             
1555     } 
1556
1557     if ( in_opening_stage ) {
1558       if ( GameType[c1] == STATIC_ROOK && GameType[c2] != STATIC_ROOK )
1559         if ( Mvboard[csquare(c1,3)] )
1560           {
1561                   s += (ds = -2*fv1[OPENWRONG]);
1562 #ifdef DEBUG_EVAL
1563                   if ( debug_eval )
1564                     fprintf(debug_eval_file,"%d for wrong opening\n",ds);
1565 #endif             
1566           }
1567     } else {
1568       EnemyKingDistanceValue(sq,2,3);
1569     }
1570
1571     return (s);
1572 }
1573
1574 static inline int
1575 BishopValue (register short int sq, short int side)
1576 /*
1577  * Calculate the positional value for a bishop on 'sq'.
1578  */
1579
1580 {
1581     register short s=0, ds, ad;
1582
1583     if ( in_opening_stage ) {
1584         if ( GameType[c1] == RANGING_ROOK )
1585           {
1586             /* Bishops diagonal should not be open */
1587             if ( !on_csquare(c1,pawn,30) ) {
1588               s += (ds = -fv1[OPENWRONG]);
1589 #ifdef DEBUG_EVAL
1590               if ( debug_eval )
1591                     fprintf(debug_eval_file,"%d for open bishops diagonal\n",ds);
1592 #endif                                                                   
1593             }
1594           }
1595         else if ( GameType[c2] == RANGING_ROOK )
1596           {
1597             /* Bishops diagonal should be open */
1598             if ( csquare(c1,sq) == 10 && 
1599                  (!empty_csquare(c1,20) || !empty_csquare(c1,30)) ) {
1600               s += (ds = -fv1[OPENWRONG]);
1601 #ifdef DEBUG_EVAL
1602               if ( debug_eval )
1603                     fprintf(debug_eval_file,"%d for closed bishops diagonal\n",ds);
1604 #endif                                                                   
1605             } else if ( csquare(c1,sq) == 20 && !empty_csquare(c1,30) ) {
1606               s += (ds = -fv1[OPENWRONG]);
1607 #ifdef DEBUG_EVAL
1608               if ( debug_eval )
1609                     fprintf(debug_eval_file,"%d for closed bishops diagonal\n",ds);
1610 #endif                                                                   
1611             }
1612           }
1613     } else {
1614         EnemyKingDistanceValue(sq,1,3);
1615     }     
1616   
1617     return (s);
1618 }
1619
1620 static inline int
1621 RookValue (register short int sq, short int side)
1622 /*
1623  * Calculate the positional value for a rook on 'sq'.
1624  */
1625
1626 {
1627     register short s=0, ds, ad;
1628
1629     OpenFileValue (sq, 2*fv1[HOPN], 4*fv1[HOPN]);
1630                                
1631     if ( in_opening_stage ) {
1632       short WRONG = fv1[OPENWRONG], OPOK = WRONG/3;
1633       if ( GameType[c1] == STATIC_ROOK )
1634         {
1635           short c = ccolumn(c1,sq);
1636           /* Bonus for rook on 8th file */
1637           if ( c == 7 ) {
1638             s += (ds = OPOK);
1639 #ifdef DEBUG_EVAL
1640             if ( debug_eval )
1641               fprintf(debug_eval_file,"%d for rook on 8th file\n",ds);
1642 #endif                                                                   
1643           }
1644           /* Bonus for rook on right side, malus for rook on left side */
1645           c = 4 - c; ds = 0;
1646           if ( c < 0 ) {
1647             s += (ds = c + c + OPOK);
1648           } else if ( c >= 0 ) {
1649             s += (ds = -c - c - WRONG);
1650           }
1651 #ifdef DEBUG_EVAL
1652           if ( debug_eval && ds )
1653             fprintf(debug_eval_file,"%d for king on correct/wrong side\n",ds);
1654 #endif                                                                   
1655         }
1656       else if ( GameType[c1] == RANGING_ROOK )
1657         {
1658           /* Bonus for rook on left side and bishops diagonal closed, malus otherwise. */
1659           short c;
1660           c = 4 - ccolumn(c1,sq); ds = 0;
1661           if ( c >= 0 ) {
1662             /* Bishops diagonal should not be open */
1663             if ( on_csquare(c1,pawn,30) )
1664               s += (ds = OPOK);
1665             else
1666               s += (ds = -c - c - WRONG);
1667           } else if ( c < 0 ) {
1668             s += (ds = -c - c - WRONG);
1669             /* Malus for king not on initial square */
1670             if ( !on_csquare(side,king,4) ) {
1671                 s += -4*WRONG; ds += -4*WRONG;      
1672             }
1673           }
1674 #ifdef DEBUG_EVAL
1675           if ( debug_eval && ds )
1676             fprintf(debug_eval_file,"%d for bishops diagonal\n",ds);
1677 #endif                                                                   
1678         }
1679     } else {
1680         EnemyKingDistanceValue(sq,1,3);
1681     }
1682
1683     return (s);
1684 }
1685
1686 static inline int
1687 PPawnValue (register short int sq, short int side)
1688 /*
1689  * Calculate the positional value for a promoted pawn on 'sq'.
1690  */
1691
1692 {
1693     register short s = 0, ds, ad;
1694
1695     EnemyKingDistanceValue(sq,3,10);
1696
1697     return (s);
1698 }
1699
1700 static inline int
1701 PLanceValue (register short int sq, short int side)
1702 /*
1703  * Calculate the positional value for a promoted lance on 'sq'.
1704  */
1705
1706 {
1707     register short s = 0, ds, ad;
1708
1709     EnemyKingDistanceValue(sq,3,10);
1710
1711     return (s);
1712 }
1713
1714 static inline int
1715 PKnightValue (register short int sq, short int side)
1716 /*
1717  * Calculate the positional value for a promoted knight on 'sq'.
1718  */
1719
1720 {
1721     register short s = 0, ds, ad;
1722
1723     EnemyKingDistanceValue(sq,3,10);
1724
1725     return (s);
1726 }
1727
1728 static inline int
1729 PSilverValue (register short int sq, short int side)
1730 /*
1731  * Calculate the positional value for a promoted silver on 'sq'.
1732  */
1733
1734 {
1735     register short s = 0, ds, ad;
1736
1737     EnemyKingDistanceValue(sq,3,10);
1738
1739     return (s);
1740 }
1741
1742 static inline int
1743 PBishopValue (register short int sq, short int side)
1744 /*
1745  * Calculate the positional value for a promoted bishop on 'sq'.
1746  */
1747
1748 {
1749     register short s = 0, ds, ad;
1750
1751     EnemyKingDistanceValue(sq,3,4);
1752
1753     return (s);
1754 }
1755
1756 static inline int
1757 PRookValue (register short int sq, short int side)
1758 /*
1759  * Calculate the positional value for a promoted rook on 'sq'.
1760  */
1761
1762 {
1763     register short s = 0, ds, ad;
1764
1765     EnemyKingDistanceValue(sq,3,4);
1766
1767     OpenFileValue (sq, 3*fv1[HOPN], 2*fv1[HOPN]);
1768                                
1769     return (s);
1770 }
1771
1772 static inline int
1773 KingValue (register short int sq, short int side)
1774 /*
1775  * Calculate the positional value for a king on 'sq'.
1776  */
1777 {
1778     register short s = 0, ds;
1779
1780     if ( fv1[KSFTY] != 0 )
1781         s += KingScan (sq);
1782
1783     if ( in_opening_stage ) 
1784       if ( GameType[c1] != UNKNOWN && ccolumn(c1,sq) == 4 ) {
1785           s += (ds = -fv1[OPENWRONG]/3);
1786 #ifdef DEBUG_EVAL
1787           if ( debug_eval && ds )
1788             fprintf(debug_eval_file,"%d for center king\n",ds);
1789 #endif
1790       } else if ( GameType[c1] == STATIC_ROOK && on_right_side(c1,sq) ) {
1791         s += (ds = -fv1[OPENWRONG]/2);
1792 #ifdef DEBUG_EVAL
1793         if ( debug_eval && ds )
1794           fprintf(debug_eval_file,"%d for king on right side\n",ds);
1795 #endif
1796       } else if ( GameType[c1] == RANGING_ROOK && on_left_side(c1,sq) ) {
1797         s += (ds = -fv1[OPENWRONG]/2);
1798 #ifdef DEBUG_EVAL
1799         if ( debug_eval && ds )
1800           fprintf(debug_eval_file,"%d for king on left side\n",ds);
1801 #endif
1802       }
1803      
1804     if ( ds = fv1[HOPN] ) {           
1805       s += OpenFileValue(sq,-2*ds,-4*ds);
1806     }
1807
1808     return (s);
1809 }
1810
1811
1812
1813 static inline int
1814 PieceValue (register short int sq, short int side)
1815 /*
1816  * Calculate the positional value for a piece on 'sq'.
1817  */
1818
1819 {
1820     register short s, piece, ds;
1821     short mob;
1822
1823     piece = board[sq];
1824
1825     if ( piece == no_piece )
1826       return 0;
1827  
1828     s = (*Mpiece[piece])[c1][sq];
1829
1830 #ifdef DEBUG_EVAL
1831     if ( debug_eval )
1832       fprintf(debug_eval_file,"\ninital value for %s %s on %c%c: %d\n",
1833                 ColorStr[c1], PieceStr[piece], cxx[column(sq)], rxx[row(sq)], s);
1834 #endif
1835
1836     checked_trapped = false;
1837
1838     if ( sweep[piece] ) {
1839         /* pin/xray attack and mobility for sweeping pieces */
1840         s += (ds = BRLscan (sq, &mob));
1841 #ifdef DEBUG_EVAL
1842         if ( debug_eval )
1843           fprintf(debug_eval_file,"%d sum for sweeping piece\n", ds);
1844 #endif
1845         if ( piece == bishop || piece == pbishop ) 
1846           s += (ds = BMBLTY[mob] * fv1[MOBILITY] / 100);
1847         else if ( piece == rook || piece == prook ) 
1848           s += (ds = RMBLTY[mob] * fv1[MOBILITY] / 100);
1849         else
1850           s += (ds = LMBLTY[mob] * fv1[MOBILITY] / 100);
1851 #ifdef DEBUG_EVAL
1852         if ( debug_eval )
1853           fprintf(debug_eval_file,"%d for mobility of sweeping piece\n", ds);
1854 #endif
1855     } else {
1856         /* mobility for non-sweeping pieces */
1857     }
1858
1859     a2 = atk2[sq];
1860     a1 = atk1[sq];             
1861
1862     if (a2 > 0)
1863       {   /* opponent attacks piece */
1864           if (a1 == 0)
1865             { /* undefended piece */
1866               s += AttackedPieceValue (sq, side);
1867             }
1868           else
1869             { /* defended piece */
1870               short attack_value = value_of_weakest_attacker(a2);
1871               short piece_value = (*value)[stage][piece];
1872               if ( attack_value < piece_value )
1873                 { /* attacked by a weaker piece */
1874                   s += AttackedPieceValue (sq, side) / 2;
1875                 }
1876               else if ( abs(attack_value - piece_value) < 10 )
1877                 {
1878                   /* opponent has the option to exchange equal pieces */
1879                   s += (ds = -fv1[ATAKD]);
1880 #ifdef DEBUG_EVAL
1881                   if ( debug_eval )
1882                     fprintf(debug_eval_file,"exchange option: %d\n", ds);
1883 #endif
1884                 }
1885 #ifdef notdef
1886               else if (a1 < ctlP)
1887                 { /* piece is not defended by a pawn */
1888                   s += (ds = -fv1[ATAKD]);
1889 #ifdef DEBUG_EVAL
1890                   if ( debug_eval )
1891                     fprintf(debug_eval_file,"not defended by pawn: %d\n", ds);
1892 #endif
1893                 }
1894 #endif
1895             }
1896       }  
1897
1898     if ( piece != king ) {
1899
1900       if ( a1 > 0 ) {  
1901         /* piece is defended */
1902         s += (ds = (a1 & CNT_MASK)*fv1[PROTECT]);
1903 #ifdef DEBUG_EVAL
1904         if ( debug_eval )
1905           fprintf(debug_eval_file,"%d for protected piece\n", ds);
1906 #endif
1907       }
1908       
1909       if ( sseed[sq] ) {
1910         s += (ds = fv1[SEED]);
1911 #ifdef DEBUG_EVAL
1912         if ( debug_eval )
1913           fprintf(debug_eval_file,"%d for seed piece\n", ds);
1914 #endif
1915       }
1916     
1917       if ( sloose[sq] ) {
1918         s += (ds = -fv1[LOOSE]);
1919 #ifdef DEBUG_EVAL
1920         if ( debug_eval )
1921           fprintf(debug_eval_file,"%d for loose piece\n", ds);
1922 #endif
1923       }
1924
1925       if ( starget[c1][sq] ) {
1926         if ( sweep[piece] ) {
1927           s -= (ds = -fv1[ATAKD]/2);
1928 #ifdef DEBUG_EVAL
1929           if ( debug_eval )
1930             fprintf(debug_eval_file,"%d for sweeping piece on own target square\n", ds);
1931 #endif
1932         } else if ( piece == pawn ) {
1933           s += (ds = fv1[ATAKD]);
1934 #ifdef DEBUG_EVAL
1935           if ( debug_eval )
1936             fprintf(debug_eval_file,"%d for pawn on own target square\n", ds);
1937 #endif
1938         }
1939       }
1940
1941       if ( starget[c2][sq] ) {
1942         if ( piece != pawn ) {
1943           s -= (ds = -fv1[ATAKD]/3);
1944 #ifdef DEBUG_EVAL
1945           if ( debug_eval )
1946             fprintf(debug_eval_file,"%d for non-pawn on opponents target square\n", ds);
1947 #endif
1948         } else {
1949           s += (ds = fv1[ATAKD]);
1950 #ifdef DEBUG_EVAL
1951           if ( debug_eval )
1952             fprintf(debug_eval_file,"%d for pawn on opponents target square\n", ds);
1953 #endif
1954         }
1955       }
1956
1957       if ( Kdist[c1][sq] == 1 ) {
1958         s += (ds = fv1[KSFTY]);
1959 #ifdef DEBUG_EVAL
1960         if ( debug_eval )
1961           fprintf(debug_eval_file,"%d for piece near king\n", ds);
1962 #endif
1963       }  
1964
1965     }
1966                                     
1967     switch ( piece ) { 
1968       case pawn:
1969         s += PawnValue (sq, side);
1970         break;
1971       case lance:
1972         s += LanceValue (sq, side);
1973         break;
1974       case knight:
1975         s += KnightValue (sq, side);
1976         break;
1977       case silver:
1978         s += SilverValue (sq, side);
1979         break;
1980       case gold:
1981         s += GoldValue (sq, side);
1982         break;
1983       case bishop:
1984         s += BishopValue (sq, side);
1985         break;
1986       case rook:
1987         s += RookValue (sq, side);
1988         break;
1989       case king:
1990         s += KingValue (sq, side);
1991         break;
1992       case ppawn:
1993         s += PPawnValue (sq, side);
1994         break;
1995       case plance:
1996         s += PLanceValue (sq, side);
1997         break;
1998       case pknight:
1999         s += PKnightValue (sq, side);
2000         break;
2001       case psilver:
2002         s += PSilverValue (sq, side);
2003         break;
2004       case pbishop:
2005         s += PBishopValue (sq, side);
2006         break;
2007       case prook:
2008         s += PRookValue (sq, side);
2009         break;
2010     }
2011
2012     return (s);
2013 }
2014
2015      
2016 short
2017 ScorePatternDistance (short c1)
2018
2019 /*
2020  * Score distance to pattern regarding the game type which side plays.
2021  */
2022
2023
2024   short ds, s = 0;
2025   small_short *fv1 = fvalue[c1];
2026   short os = 0;
2027
2028 #ifdef DEBUG_EVAL
2029   char name[16];
2030   if ( debug_eval )
2031     fprintf(debug_eval_file,"scoring castle pattern distance for PCASTLE=%d\n",
2032                 fv1[PCASTLE]);
2033 #endif
2034
2035   if ( MAXCDIST > 0 && fv1[PCASTLE] != 0 && ((os = castle_opening_sequence[c1]) >= 0) )
2036     {
2037       ds = board_to_pattern_distance(c1,os,MAXCDIST,GameCnt);
2038       if ( ds != 0) {
2039         s += (ds *= fv1[PCASTLE]);
2040 #ifdef DEBUG_EVAL
2041         if ( debug_eval && ds != 0 ) {
2042           NameOfOpeningValue(OpeningSequence[os].opening_type,name);
2043           fprintf(debug_eval_file,
2044             "add %d for max gain of %s to reachable castle patterns %s\n", 
2045             ds, ColorStr[c1], name); 
2046         }
2047 #endif
2048       };
2049     }
2050 #ifdef DEBUG_EVAL
2051   else if ( debug_eval && os<0 )
2052     fprintf(debug_eval_file,"no castle pattern for %s\n",ColorStr[c1]);
2053 #endif
2054
2055 #ifdef DEBUG_EVAL
2056   if ( debug_eval )
2057     fprintf(debug_eval_file,"scoring attack pattern distance for PATTACK=%d\n",
2058                 fv1[PATTACK]);
2059 #endif
2060
2061   if ( MAXADIST > 0 && fv1[PATTACK] != 0 && ((os = attack_opening_sequence[c1]) >= 0) )
2062     {            
2063       ds = board_to_pattern_distance(c1,os,MAXADIST,GameCnt);
2064       if ( ds != 0 ) {
2065         s += (ds *= fv1[PATTACK]);
2066 #ifdef DEBUG_EVAL
2067         if ( debug_eval && ds != 0 ) {
2068           NameOfOpeningValue(OpeningSequence[os].opening_type,name);
2069           fprintf(debug_eval_file,
2070              "add %d for max gain of %s to reachable attack patterns %s\n",
2071              ds, ColorStr[c1], name);
2072         } 
2073 #endif
2074       }
2075     }
2076 #ifdef DEBUG_EVAL
2077   else if ( debug_eval && os<0 )
2078     fprintf(debug_eval_file,"no attack pattern for %s\n",ColorStr[c1]);
2079 #endif
2080
2081   return(s);
2082 }
2083
2084
2085
2086 static
2087 void
2088 UpdatePatterns (short int side, short int GameCnt)
2089
2090 /*
2091  * Determine castle and attack pattern which should be reached next.
2092  * Only patterns are considered, which have not been reached yet.
2093  */
2094
2095 {
2096   char s[12];
2097   short xside = side ^ 1;
2098   short os;
2099   short i, j, k, n = 0;
2100 #ifdef DEBUG_EVAL
2101   char name[16];
2102 #endif
2103
2104   strcpy(s,"CASTLE_?_?");
2105   s[7] = GameType[side];
2106   s[9] = GameType[xside];
2107   castle_opening_sequence[side] = os = locate_opening_sequence(side,s,GameCnt);
2108
2109   if ( flag.post && os!=END_OF_SEQUENCES )
2110     {     
2111       for (j=0; j<MAX_SEQUENCE; j++) {
2112         for (k=OpeningSequence[os].first_pattern[j]; k!=END_OF_PATTERNS; k=Pattern[k].next_pattern)     
2113           if ( Pattern[k].distance[side] >= 0 ) n++;
2114       }
2115     }
2116
2117   if ( os!=END_OF_SEQUENCES ) update_advance_bonus (side,os);
2118
2119 #ifdef DEBUG_EVAL
2120   if ( debug_eval )
2121     if (os!=END_OF_SEQUENCES )
2122       {
2123         NameOfOpeningValue(OpeningSequence[os].opening_type,name);
2124         fprintf(debug_eval_file,"castle pattern of %s is %s\n",
2125                  ColorStr[side], name);
2126         fprintf(debug_eval_file,"reachable patterns: ");
2127         for (j=0; j<MAX_SEQUENCE; j++)
2128           for (i=0,k=OpeningSequence[os].first_pattern[j]; k!=END_OF_PATTERNS; i++,k=Pattern[k].next_pattern)
2129             if ( Pattern[k].distance[side] >= 0 )
2130               fprintf(debug_eval_file,"%d(%d) ",i,j);
2131         fprintf(debug_eval_file,"\n");
2132       }
2133     else
2134       {
2135         fprintf(debug_eval_file,"no castle pattern %s for %s\n",
2136                  s, ColorStr[side]);
2137       }
2138 #endif
2139
2140   strcpy(s,"ATTACK_?_?");
2141   s[7] = GameType[side];
2142   s[9] = GameType[xside];
2143   attack_opening_sequence[side] = os = locate_opening_sequence(side,s,GameCnt);
2144   
2145   if ( flag.post && os!=END_OF_SEQUENCES )
2146     { 
2147       for (j=0; j<MAX_SEQUENCE; j++) {
2148         for (k=OpeningSequence[os].first_pattern[j]; k!=END_OF_PATTERNS; k=Pattern[k].next_pattern)
2149           if ( Pattern[k].distance[side] >= 0 ) n++;
2150       }
2151     }
2152
2153   if ( flag.post ) 
2154     {
2155       ShowPatternCount(side,n);
2156     }
2157
2158   if ( os!=END_OF_SEQUENCES ) update_advance_bonus (side,os);
2159
2160 #ifdef DEBUG_EVAL
2161   if ( debug_eval )
2162     if ( os!=END_OF_SEQUENCES )
2163       {
2164         NameOfOpeningValue(OpeningSequence[os].opening_type,name);
2165         fprintf(debug_eval_file,"attak pattern of %s is %s\n",
2166                   ColorStr[side], name);
2167         fprintf(debug_eval_file,"reachable patterns: "); 
2168         for (j=0; j<MAX_SEQUENCE; j++)
2169           for (i=0,k=OpeningSequence[os].first_pattern[j]; k!=END_OF_PATTERNS; k=Pattern[k].next_pattern)
2170             if ( Pattern[k].distance[side] >= 0 )
2171               fprintf(debug_eval_file,"%d(%d) ",i,j);
2172         fprintf(debug_eval_file,"\n");
2173       }
2174     else
2175       {
2176         fprintf(debug_eval_file,"no attak pattern %s for %s\n",
2177                   s, ColorStr[side]);
2178       }
2179 #endif
2180
2181
2182 }
2183
2184
2185
2186
2187 static
2188 void
2189 ScoreSquares (void)
2190 {
2191   register short sq;
2192   short ds, n, m;
2193
2194   for ( sq = 0; sq < NO_SQUARES; sq++ ) {
2195
2196     for ( c1 = black, c2 = white; c1 <= white; c1++, c2-- ) {
2197
2198         a1 = atak[c1][sq];
2199         a2 = atak[c2][sq];
2200         fv1 = fvalue[c1];
2201
2202         if ( InPromotionZone(c1,sq) ) {
2203           /* square in promotion zone */
2204           if ( a1 & control[pawn] ) {
2205             /* dangling pawn */
2206             pscore[c1] += (ds = 2*fv1[DNGLPC]);
2207 #ifdef DEBUG_EVAL
2208             if ( debug_eval ) {
2209               fprintf(debug_eval_file,"%d for %s dangling pawn\n",ds,ColorStr[c1]);
2210             }                                                                      
2211 #endif
2212           }
2213           if ( a1 & (control[lance] | control[knight]) ) {
2214             /* dangling lance or dangling knight */
2215             pscore[c1] += (ds = fv1[DNGLPC]);
2216 #ifdef DEBUG_EVAL
2217             if ( debug_eval ) {
2218               fprintf(debug_eval_file,"%d for %s dangling knight/silver\n",ds,ColorStr[c1]);
2219             }                                                                      
2220 #endif
2221           }
2222         }
2223         if ( a1 & control[king] ) {
2224           /* square controlled by own king */
2225           if ( (n = a1 & CNT_MASK) > 1 ) {
2226             pscore[c1] += (ds = (n-1)*fv1[KNGPROTECT]);
2227 #ifdef DEBUG_EVAL
2228             if ( debug_eval ) {
2229               fprintf(debug_eval_file,"%d for %s protects own king\n",ds,ColorStr[c1]);
2230             }                                                                      
2231 #endif
2232           }
2233         }  
2234         if ( a2 & control[king] ) {
2235           /* square controlled by enemy king */
2236           if ( (n = a1 & CNT_MASK) > 0 ) {
2237             pscore[c1] += (ds = n*fv1[KNGATTACK]);
2238 #ifdef DEBUG_EVAL
2239             if ( debug_eval ) {
2240               fprintf(debug_eval_file,"%d for %s controls enemy king\n",ds,ColorStr[c1]);
2241             }                                                                      
2242 #endif
2243           }
2244         }
2245         if ( (a2 & CNT_MASK) > 1 ) {
2246           /* enemy's focal point */
2247           if ( (n = a1 & CNT_MASK) > 0 ) {
2248             pscore[c1] += (ds = n*fv1[FCLATTACK]);
2249 #ifdef DEBUG_EVAL
2250             if ( debug_eval ) {
2251               fprintf(debug_eval_file,"%d for %s attacks enemy's focal point\n",ds,ColorStr[c1]);
2252             }                                                                      
2253 #endif
2254           } 
2255         }  
2256     }   
2257
2258     if ( (c1 = color[sq]) == neutral ) {
2259
2260         /* empty square */
2261
2262     } else {              
2263
2264         /* occupied square */ 
2265
2266         c2 = c1 ^ 1;
2267
2268         a1 = atak[c1][sq];
2269         a2 = atak[c2][sq];
2270         fv1 = fvalue[c1];
2271
2272         if ( a2 && sloose[sq] ) {
2273           pscore[c2] += (ds = fv1[LSATTACK]);
2274 #ifdef DEBUG_EVAL
2275           if ( debug_eval ) {
2276             fprintf(debug_eval_file,"%d for %s attacks loose piece\n",ds,ColorStr[c2]);
2277           }                                                                      
2278 #endif  
2279         }   
2280         if ( a2 && !Captured[c2][unpromoted[board[sq]]] ) {
2281           pscore[c2] += (ds = fv1[NIHATTACK]);
2282 #ifdef DEBUG_EVAL
2283           if ( debug_eval && ds ) {
2284             fprintf(debug_eval_file,"%d for %s attack piece not in hand\n",ds,ColorStr[c2]);
2285           }                                                                      
2286 #endif     
2287         }
2288       }
2289         
2290   }                                      
2291
2292 }
2293     
2294
2295
2296 static
2297 void
2298 ScoreCaptures (void)
2299 {
2300   short ds, col, n, m, piece;
2301
2302   if ( n = Captured[c1][pawn] ) {
2303     ds = m = 0;
2304     for ( col = 0; col < NO_COLS; col++ ) {
2305       if ( !PC1[col] ) {
2306         m++;
2307         ds += fv1[PWNDROP];
2308       }
2309     }
2310     pscore[c1] += (ds *= ((n > 2) ? 3 : n));
2311 #ifdef DEBUG_EVAL
2312     if ( debug_eval && ds ) {
2313           fprintf(debug_eval_file,"%d for %s %d captured pawns dropable to %d cols\n",
2314                         ds,ColorStr[c2],n,m);
2315     }
2316 #endif     
2317   }
2318       
2319   if ( m = seed[c1] ) {
2320     for ( piece = lance, n=0; piece <= rook; piece++ ) {
2321       if ( Captured[c1][piece] )
2322             n++;
2323     }   
2324     pscore[c1] += (ds = m*fv1[DFFDROP]);
2325 #ifdef DEBUG_EVAL
2326     if ( debug_eval && ds ) {
2327           fprintf(debug_eval_file,"%d for %s %d diff captures supported by %d seed pieces\n",
2328                         ds,ColorStr[c2],n,m);
2329     }                                                                      
2330 #endif     
2331   }
2332
2333   for ( piece = pawn, n = 0; piece <= rook; piece++ ) {
2334     if ( Captured[c1][piece] ) {
2335       switch ( piece ) {
2336         case bishop: ds = BMBLTY[MAX_BMBLTY-1]; break;
2337         case rook  : ds = RMBLTY[MAX_RMBLTY-1]; break;
2338         case lance : ds = LMBLTY[MAX_LMBLTY-1]; break;
2339         default    : ds = MBLTY[piece];
2340       }
2341       pscore[c1] += ds;
2342 #ifdef DEBUG_EVAL
2343       if ( debug_eval && ds ) {
2344         fprintf(debug_eval_file,"%d for %s's piece %s in hand mobility\n",
2345                         ds,ColorStr[c2],PieceStr[piece]);
2346       }                                                                      
2347 #endif     
2348       if ( !Captured[c2][piece] ) 
2349         n += relative_value[piece];
2350     }
2351   }
2352   if ( n ) {
2353        pscore[c1] += (ds = -n*fv1[OPPDROP]/2);
2354 #ifdef DEBUG_EVAL
2355         if ( debug_eval && ds ) {
2356           fprintf(debug_eval_file,"%d for %s's captured pieces not in %s's hand\n",
2357                         ds,ColorStr[c2],ColorStr[c1]);
2358         }                                                                      
2359 #endif     
2360   }
2361
2362 }
2363
2364
2365
2366
2367 short int
2368 ScorePosition (register short int side)
2369
2370 /*
2371  * Perform normal static evaluation of board position. A score is generated
2372  * for each piece and these are summed to get a score for each side.
2373  */
2374
2375 {
2376     register short int score;
2377     register short sq, i, xside;
2378     short int s;
2379     short int escore;
2380     short int ds;
2381
2382     xside = side ^ 1;
2383
2384     UpdateWeights (side);
2385
2386 #ifdef DEBUG_EVAL
2387     if ( debug_eval )
2388       fprintf (debug_eval_file, "side = %s, stage = %d, in_opening = %d\n",
2389         ColorStr[side], stage, in_opening_stage );
2390 #endif
2391
2392     hung[black] = hung[white] = pscore[black] = pscore[white] = 0;
2393
2394     array_zero(shung,sizeof(shung));
2395
2396 #ifdef CACHE
2397 #ifdef DEBUG_EVAL
2398     if (debug_eval || !(use_etable && ProbeEETable (side, &s)))
2399 #else
2400     if (!(use_etable && ProbeEETable (side, &s)))
2401 #endif
2402         { 
2403 #endif   
2404           for (c1 = black; c1 <= white; c1++)
2405             {
2406                 c2 = c1 ^ 1;
2407                 /* atk1 is array of atacks on squares by my side */
2408                 atk1 = atak[c1];
2409                 /* atk2 is array of atacks on squares by other side */
2410                 atk2 = atak[c2];
2411                 /* same for PC1 and PC2 */
2412                 PC1 = PawnCnt[c1];
2413                 PC2 = PawnCnt[c2];
2414                 /* same for fv1 and fv2 */
2415                 fv1 = fvalue[c1];
2416                 for (i = PieceCnt[c1]; i >= 0; i--)
2417                   {
2418                       sq = PieceList[c1][i];
2419 #if defined SAVE_SVALUE
2420                       pscore[c1] += PieceValue(sq,side);
2421 #else
2422                       pscore[c1] += (svalue[sq] = PieceValue(sq,side));
2423 #endif
2424                   }
2425                 ScoreCaptures();
2426             }
2427 #ifdef DEBUG_EVAL 
2428           if ( debug_eval ) {                      
2429             fprintf(debug_eval_file,"pscore[%s] = %d, pscore[%s] = %d\n",
2430                 ColorStr[side], pscore[side], ColorStr[xside], pscore[xside]);
2431 #if !defined SAVE_SVALUE
2432             debug_svalue(debug_eval_file);
2433 #endif
2434           }
2435 #endif
2436 #ifdef DEBUG_EVAL
2437           if ( debug_eval ) {
2438             char buffer[80];
2439             sprintf(buffer,"%d Black and %d White HUNG PIECES",hung[black],hung[white]);
2440             debug_table (debug_eval_file,shung,buffer);
2441           }
2442 #endif
2443           for ( c1=black,c2=white; c1<=white; c1++,c2-- ) 
2444             {
2445               short n;
2446
2447               fv1 = fvalue[c1];
2448
2449               /* Score fifth rank */
2450               for ( sq = 36, n=0; sq <= 44; sq++ ) 
2451                 if ( color[sq] == c1 || atak[c1][sq] != 0 )
2452                   n++;
2453
2454               if ( n != 0 ) {
2455                 pscore[c1] += (ds = n*fv1[CNTRL5TH]);
2456 #ifdef DEBUG_EVAL
2457                 if ( debug_eval )
2458                   fprintf(debug_eval_file,"%d for %s controls 5th rank with %d points\n",
2459                             ds, ColorStr[c1], n);
2460 #endif
2461               }
2462
2463               /* Score holes */
2464               for ( sq = ((c1==black)?0:54), n=0; sq<=((c1==black)?26:80); sq++ )
2465                 if ( board[sq] == no_piece && atak[c1][sq] == 0 )
2466                   n++;
2467
2468               if ( n != 0 ) {
2469                 pscore[c1] += (ds = -n*fv1[HOLES]);
2470 #ifdef DEBUG_EVAL
2471                 if ( debug_eval && ds )
2472                   fprintf(debug_eval_file,"%d for %s camp has %d holes\n",
2473                             ds, ColorStr[c1], n);
2474 #endif
2475               }
2476
2477               if (hung[c1] > 1) {
2478                 pscore[c1] += (ds = -fv1[HUNGX]);
2479 #ifdef DEBUG_EVAL
2480                 if ( debug_eval )
2481                   fprintf(debug_eval_file,"%d for %d hung pieces.\n",
2482                        ds, hung[c1]);
2483 #endif
2484               }
2485               /* Score opening features and castle/attack pattern distances */
2486               
2487               if ( in_opening_stage ) { 
2488                 pscore[c1] += (ds = ScoreKingOpeningFeatures ());          
2489 #ifdef DEBUG_EVAL
2490                 if ( debug_eval && ds)
2491                   fprintf(debug_eval_file,"%d for %s opening features\n",
2492                             ds, ColorStr[c1]);
2493 #endif
2494                 pscore[c1] += (ds = ScorePatternDistance (c1));         
2495 #ifdef DEBUG_EVAL
2496                 if ( debug_eval && ds )
2497                   fprintf(debug_eval_file,"%d for %s pattern distance\n",
2498                             ds, ColorStr[c1]);
2499 #endif
2500               }
2501             }
2502
2503           score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
2504
2505 #ifdef DEBUG_EVAL 
2506           if ( debug_eval ) {                      
2507             fprintf(debug_eval_file,"side=%s xside=%s %d - %d + %d - %d + 10 = %d\n",
2508                 ColorStr[side], ColorStr[xside],
2509                 mtl[side], mtl[xside], pscore[side], pscore[xside], score);
2510           }
2511 #endif
2512
2513 #ifdef notdef
2514           if (dither)
2515             {
2516               if (flag.hash)
2517                 gsrand (starttime + (unsigned int) hashbd);
2518               score += urand () % dither;
2519             }
2520 #endif
2521
2522 #ifdef CACHE
2523           if ( use_etable && PUTVAR )
2524             PutInEETable(side,score);
2525 #endif
2526 #ifdef DEBUG_EVAL
2527           if ( debug_eval )
2528             fprintf (debug_eval_file, "score = %d\n", score);
2529 #endif
2530           return(score);
2531 #ifdef CACHE
2532         }
2533 #ifdef DEBUG_EVAL
2534       else
2535         { 
2536           if ( debug_eval )
2537             fprintf (debug_eval_file, "Score cached!\n" );
2538         }
2539 #endif
2540                           
2541 #ifdef DEBUG_EVAL
2542     if ( debug_eval )
2543       fprintf (debug_eval_file, "s = %d\n", s);
2544 #endif
2545     return (s);
2546 #endif
2547
2548 }
2549
2550
2551
2552 inline static void
2553 GuessGameType (short side_to_move)
2554 {
2555   /*
2556    * Try to determine the game type of "side".
2557    */
2558
2559    short side, sq, gt, StaticRook[2] = {0,0}, RangingRook[2] = {0,0};
2560   
2561    for ( side=black; side<=white; side++ ) {         
2562
2563      /* computer should not change its mind */
2564            
2565      extern int bookflag;
2566
2567      gt = GameType[side];
2568
2569      if ( !bookflag && side == side_to_move )
2570         if ( gt == STATIC_ROOK )
2571           StaticRook[side] += 4;
2572         else if ( gt == RANGING_ROOK )
2573           RangingRook[side] += 4;
2574
2575      /* static rook conditions */
2576     
2577      if ( on_column(side,rook,7) )
2578        StaticRook[side] += 3;
2579      if ( on_csquare(side,pawn,34) )
2580        StaticRook[side] += 6;
2581      else if ( on_csquare(side,pawn,43) )
2582        StaticRook[side] += 4;
2583      else if ( !on_column(side,pawn,7) )
2584        StaticRook[side] += 5;
2585      if ( empty_csquare(side,5) || empty_csquare(side,6) )
2586        StaticRook[side] += 2;
2587      if ( on_left_side(side,king) )
2588        StaticRook[side] += 2;
2589
2590      /* ranging rook conditions */
2591  
2592      if ( on_left_side(side,rook) )
2593        RangingRook[side] += 5; 
2594      else if ( !on_column(side,rook,7) )
2595        RangingRook[side] += 3;
2596      if ( on_csquare(side,pawn,25) )
2597        RangingRook[side] += 1;
2598      if ( on_csquare(side,pawn,30) )
2599        RangingRook[side] += 1;
2600      else
2601        RangingRook[side] -= 2;
2602      if ( !on_right_side(side,rook) )
2603        RangingRook[side] += 4;
2604      if ( on_right_side(side,king) )
2605        RangingRook[side] += 4;
2606      if ( on_csquare(side,bishop,20) )
2607        if ( on_csquare(side,silver,11) || on_csquare(side,silver,12) ||
2608           on_csquare(side,silver,21) )
2609        RangingRook[side] += 3;
2610      
2611      if ( StaticRook[side] > 5 || RangingRook[side] > 5 )
2612          GameType[side] = (StaticRook[side] > RangingRook[side]) 
2613                                 ? STATIC_ROOK : RANGING_ROOK;
2614      else
2615          GameType[side] = UNKNOWN;
2616
2617    }
2618         
2619 #ifdef DEBUG_EVAL
2620 #define StringOfGameType(side)\
2621   (GameType[side] == STATIC_ROOK ? "Static Rook" :\
2622   (GameType[side] == RANGING_ROOK ? "Ranging Rook" : "UNKNOWN"))
2623
2624    if ( debug_eval )
2625       fprintf(debug_eval_file,"guessing game type: %s vs. %s\n",
2626         StringOfGameType(black), StringOfGameType(white));
2627 #endif          
2628
2629    if ( GameType[black] == UNKNOWN || GameType[white] == UNKNOWN )
2630       {
2631          for (side = black; side <= white; side++)
2632            if ( side == computer && GameType[side] == UNKNOWN ) {
2633                   /*
2634                    * Game type is UNKNOWN.
2635                    * Make a decision what type of game to play.
2636                    * To make computer games more interesting, make a
2637                    * random decision.
2638                    */
2639                    if ( !on_csquare(side,pawn,25) ) {
2640                      /* Play static rook if rook pawn has been pushed! */
2641                      GameType[side] = STATIC_ROOK;
2642                    } else {
2643                      unsigned int random = urand () % 100;
2644                      short d = StaticRook[side] - RangingRook[side];
2645                      switch ( GameType[side ^ 1] ) {
2646                        case STATIC_ROOK:
2647                          if ( random < 35 + d ) GameType[side] = STATIC_ROOK;
2648                          else if ( random < 95 ) GameType[side] = RANGING_ROOK;
2649                          break;
2650                        case RANGING_ROOK:
2651                          if ( random < 75 + d) GameType[side] = STATIC_ROOK;
2652                          else if ( random < 95 ) GameType[side] = RANGING_ROOK;
2653                          break;
2654                        default:          
2655                          if ( random < 33 + d) GameType[side] = STATIC_ROOK;
2656                          else if ( random < 66 ) GameType[side] = RANGING_ROOK;
2657                      }       
2658                    }
2659 #ifdef DEBUG_EVAL
2660              if ( debug_eval )
2661                fprintf(debug_eval_file,"decide game type: %s vs. %s\n",
2662                  StringOfGameType(black), StringOfGameType(white));
2663 #endif
2664            }
2665       }
2666
2667 }
2668
2669
2670 #ifdef DEBUG_EVAL
2671
2672 #define StringOfGameType(side)\
2673   (GameType[side] == STATIC_ROOK ? "Static Rook" :\
2674   (GameType[side] == RANGING_ROOK ? "Ranging Rook" : "UNKNOWN"))
2675
2676 #endif
2677
2678
2679 static
2680 void
2681 DetermineGameType (short side_to_move)
2682 {
2683     short int side;
2684
2685     GuessGameType(side_to_move);
2686
2687 #if !defined XSHOGI
2688     if ( flag.post )
2689       ShowGameType();
2690 #endif
2691
2692     array_zero (Mpawn, sizeof(Mpawn));
2693     array_zero (Mlance, sizeof(Mlance));
2694     array_zero (Mknight, sizeof(Mknight));
2695     array_zero (Msilver, sizeof(Msilver));
2696     array_zero (Mgold, sizeof(Mgold));
2697     array_zero (Mbishop, sizeof(Mbishop));
2698     array_zero (Mrook, sizeof(Mrook));
2699     array_zero (Mking, sizeof(Mking));
2700
2701     if ( in_opening_stage ) {
2702       for (side = black; side <= white; side++)
2703         UpdatePatterns (side, GameCnt);
2704     } else {
2705       ShowPatternCount(black,-1);
2706       ShowPatternCount(white,-1);
2707     }
2708
2709 }                 
2710
2711 void
2712 ExaminePosition (short side)
2713
2714 /*
2715  * This is done one time before the search is started. Set up arrays Mwpawn,
2716  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
2717  * to determine the positional value of each piece.
2718  */
2719
2720 {
2721     register short c1, piece, sq, i, bsq, wsq;
2722
2723     /* Build enemy king distance tables. */
2724                                     
2725     for (sq = 0, bsq = BlackKing, wsq = WhiteKing; sq < NO_SQUARES; sq++)
2726       {
2727         Kdist[black][sq] = distance(sq,bsq);
2728         Kdist[white][sq] = distance(sq,wsq);
2729       }
2730
2731     threats (black);
2732     threats (white);
2733
2734     ExamineSquares();
2735
2736     DetermineGameType(side);
2737     DetermineStage(side);
2738
2739     UpdateWeights(side);
2740
2741     array_zero (HasPiece, sizeof(HasPiece));
2742
2743     for (c1 = black; c1 <= white; c1++)
2744         for (i = PieceCnt[c1]; i >= 0; i--)
2745           {
2746             ++HasPiece[c1][piece=board[sq=PieceList[c1][i]]];
2747           }
2748
2749 #ifdef DEBUG_EVAL
2750     if ( debug_eval )
2751       for (c1=black; c1<=white; c1++)
2752         {
2753           fprintf(debug_eval_file,"%s's tables\n\n",ColorStr[c1]);
2754           debug_table(debug_eval_file,Mpawn[c1],"pawn");
2755           debug_table(debug_eval_file,Mlance[c1],"lance");
2756           debug_table(debug_eval_file,Mknight[c1],"knight");
2757           debug_table(debug_eval_file,Msilver[c1],"silver");
2758           debug_table(debug_eval_file,Mgold[c1],"gold");
2759           debug_table(debug_eval_file,Mbishop[c1],"bishop");
2760           debug_table(debug_eval_file,Mrook[c1],"rook");
2761           debug_table(debug_eval_file,Mking[c1],"king");
2762           debug_table(debug_eval_file,Kdist[c1],"distance to king");
2763         }
2764 #endif
2765
2766 }
2767
2768
2769
2770
2771 void
2772 DetermineStage (short side)
2773
2774 {
2775     short xside = side ^ 1, ds, db1, db2, c1,c2, feature;
2776
2777     /* Determine initial stage */
2778
2779     balance[side] = balance[xside] = 50;
2780  
2781     if ( GameType[side] == STATIC_ROOK && GameType[xside] == STATIC_ROOK ) {
2782       if ( GameCnt < 40 )
2783         stage = 0;
2784       else if ( GameCnt < 60 )
2785         stage = 15;
2786       else if ( GameCnt < 80 )
2787         stage = 25;
2788       else 
2789         stage = 30;
2790     } else if ( GameType[side] == RANGING_ROOK || GameType[xside] == RANGING_ROOK ) {
2791       if ( GameCnt < 30 )
2792         stage = 0;
2793       else if ( GameCnt < 50 )
2794         stage = 15;
2795       else if ( GameCnt < 70 )
2796         stage = 25;
2797       else 
2798         stage = 30;
2799     } else {   
2800       if ( GameCnt < 35 )
2801         stage = 0;
2802       else if ( GameCnt < 55 )
2803         stage = 15;
2804       else if ( GameCnt < 75 )
2805         stage = 25;
2806       else 
2807         stage = 30;
2808     }    
2809     
2810 #ifdef DEBUG_EVAL
2811         if ( debug_eval ) {
2812           fprintf(debug_eval_file,"initial stage value = %d\n",stage);
2813           fprintf(debug_eval_file,"initial balance values = %d,%d\n",
2814             balance[0], balance[1]);
2815         }
2816 #endif 
2817
2818     /* Update stage depending on board features and attack balance value */
2819
2820     if ( abs(ds = (mtl[side] - mtl[xside])) > (db1 = (*value)[stage][lance]) ) {
2821         db1 = abs(4 * ds / db1);
2822         if ( ds < 0 ) {
2823           balance[side] += db1;
2824         } else if ( ds > 0 ) {
2825           balance[xside] += db1; 
2826         };
2827         stage += (ds = db1);                                           
2828 #ifdef DEBUG_EVAL
2829         if ( debug_eval ) {
2830           fprintf(debug_eval_file,"%d stage bonus for material balance\n",ds);
2831           fprintf(debug_eval_file,"%d %s balance bonus for material balance\n",
2832                         db1, ColorStr[side]);
2833         }
2834 #endif 
2835     }
2836      
2837     for ( c1=black, c2=white; c1<=white; c1++, c2-- ) {
2838
2839       if ( (ds = seed[c1]) > 2 ) {
2840         balance[c1] += (db1 = ds * 2);   
2841         balance[c2] -= db1;
2842         if ( stage < 30 )
2843           stage = 30;   
2844         stage += ds;
2845 #ifdef DEBUG_EVAL
2846         if ( debug_eval ) {
2847           fprintf(debug_eval_file,"%d for seed pieces\n",ds);
2848           fprintf(debug_eval_file,"%d %s balance bonus for seed pieces\n",
2849                         db1, ColorStr[c1]);
2850           fprintf(debug_eval_file,"%d %s balance penalty for seed pieces\n",
2851                         -db1, ColorStr[c2]);
2852         }
2853 #endif 
2854       }
2855
2856       if ( (db1 = hung[c1]) > 2 ) {
2857         balance[c1] -= (db1 *= 2);                            
2858         balance[c2] += db1;
2859 #ifdef DEBUG_EVAL
2860         if ( debug_eval ) {
2861           fprintf(debug_eval_file,"%d %s balance penalty for hung pieces\n",
2862                         -db1, ColorStr[c1]);
2863           fprintf(debug_eval_file,"%d %s balance bonus for hung pieces\n",
2864                         db1, ColorStr[c2]);
2865         }
2866 #endif 
2867       }    
2868
2869       if ( (db1 = loose[c1]) > 4 ) {
2870         balance[c1] -= (db1 /= 2);                            
2871         balance[c2] += db1;
2872         stage += (ds = 1);
2873 #ifdef DEBUG_EVAL
2874         if ( debug_eval ) {
2875           fprintf(debug_eval_file,"%d stage bonus for loose piece\n",ds);
2876           fprintf(debug_eval_file,"%d %s balance penalty for loose pieces\n",
2877                         -db1, ColorStr[c1]);
2878           fprintf(debug_eval_file,"%d %s balance bonus for loose pieces\n",
2879                         db1, ColorStr[c2]);
2880         }
2881 #endif 
2882       }                  
2883
2884       if ( (ds = hole[c1]) ) {
2885         balance[c1] -= (db1 = ds);                            
2886         balance[c2] += db1;
2887         stage += (ds /= 2);
2888 #ifdef DEBUG_EVAL
2889         if ( debug_eval ) {
2890           fprintf(debug_eval_file,"%d stage bonus for holes\n",ds);
2891           fprintf(debug_eval_file,"%d %s balance penalty for holes\n",
2892                         -db1, ColorStr[c1]);
2893           fprintf(debug_eval_file,"%d %s balance bonus for holes\n",
2894                         db1, ColorStr[c2]);
2895         }
2896 #endif 
2897       }                  
2898
2899       if ( (db1 = target[c1]) > 3 ) {
2900         balance[c1] += (db1 /= 3);                            
2901         balance[c2] -= db1;
2902         stage += (ds = db1 / 4);
2903 #ifdef DEBUG_EVAL
2904         if ( debug_eval ) {
2905           fprintf(debug_eval_file,"%d stage bonus for targets\n",ds);
2906           fprintf(debug_eval_file,"%d %s balance bonus for targets\n",
2907                         db1, ColorStr[c1]);
2908           fprintf(debug_eval_file,"%d %s balance penalty for targets\n",
2909                         -db1, ColorStr[c2]);
2910         }
2911 #endif 
2912       }    
2913
2914       stage += (ds = captured[c1]/2);
2915 #ifdef DEBUG_EVAL
2916       if ( debug_eval && ds ) {
2917         fprintf(debug_eval_file,"%d stage bonus for captured pieces\n",ds);
2918       }
2919 #endif 
2920
2921       if ( (db1 = captured[c1]) > 4 ) {
2922         balance[c1] += (db1 /= 2);
2923         stage += (ds = 3);
2924 #ifdef DEBUG_EVAL
2925         if ( debug_eval ) {
2926           fprintf(debug_eval_file,"%d stage bonus for pieces in hand\n",ds);
2927           fprintf(debug_eval_file,"%d %s balance bonus for pieces in hand\n",
2928                         db1, ColorStr[c1]);
2929         }
2930 #endif 
2931       }
2932
2933       if ( (db1 = dcaptured[c1]) > 3 ) {
2934         balance[c1] += db1;
2935         stage += (ds = 3);
2936 #ifdef DEBUG_EVAL
2937         if ( debug_eval ) {
2938           fprintf(debug_eval_file,"%d stage bonus for different piece types in hand\n",ds);
2939           fprintf(debug_eval_file,"%d %s balance bonus for different piece types in hand\n",
2940                         db1, ColorStr[c1]);
2941         }
2942 #endif 
2943       }
2944    
2945       if ( balance[c1] > 99 ) balance[c1] = 99;
2946       else if ( balance[c1] < 0 ) balance[c1] = 0;
2947
2948     }
2949
2950 #ifdef DEBUG_EVAL
2951       if ( debug_eval )
2952         for ( c1 = black; c1 <= white; c1++ )
2953           fprintf(debug_eval_file,"balance[%s] = %d\n",ColorStr[c1],balance[c1]);
2954 #endif 
2955
2956     if ( stage > 99 ) stage = 99;
2957     else if ( stage < 0 ) stage = 0;
2958     
2959 #ifdef DEBUG_EVAL
2960     if ( debug_eval )
2961       fprintf(debug_eval_file,"stage = %d\n",stage);
2962       
2963 #endif 
2964
2965     if ( flag.post )
2966       ShowStage ();
2967
2968     /* Determine stage dependant weights */
2969    
2970     ADVNCM[pawn]   = 1; /* advanced pawn bonus increment*/
2971     ADVNCM[lance]  = 1;
2972     ADVNCM[knight] = 1;
2973     ADVNCM[silver] = 1; /* advanced silver bonus increment */
2974     ADVNCM[gold]   = 1; /* advanced gold bonus increment */
2975     ADVNCM[bishop] = 1;
2976     ADVNCM[rook]   = 1;
2977     ADVNCM[king]   = 1; /* advanced king bonus increment */
2978  
2979     MAXCDIST = (stage < 33 ) ? (33 - stage)/4 : 0;
2980     MAXADIST = (stage < 30 ) ? (30 - stage)/4 : 0;
2981        
2982 #ifdef DEBUG_EVAL
2983     if ( debug_eval ) {
2984       fprintf(debug_eval_file,"maximum distance to castle pattern: %d\n",MAXCDIST);
2985       fprintf(debug_eval_file,"maximum distance to attack pattern: %d\n",MAXADIST);
2986     }
2987 #endif
2988
2989     for ( c1 = black; c1 <= white; c1++ ) {
2990       for ( feature = 0; feature < NO_FEATURES; feature++ ) {
2991         fvalue[c1][feature] = 
2992            ((((*fscore)[stage][feature][0] * (99 - balance[c1])) + 50) / 100) 
2993          + ((((*fscore)[stage][feature][1] * balance[c1]) + 50) / 100);
2994       }                                    
2995     }
2996
2997 #ifdef DEBUG_EVAL
2998     if ( debug_eval ) {
2999       fprintf(debug_eval_file,"weighted and balanced feature values\n");
3000       fprintf(debug_eval_file,"    Black White\n");
3001       for ( feature = 0; feature < NO_FEATURES; feature++ ) {
3002         fprintf(debug_eval_file,"%3d %5d %5d\n",
3003           feature,fvalue[0][feature],fvalue[1][feature]);
3004       }
3005     }
3006 #endif
3007 }      
3008       
3009
3010 void
3011 UpdateWeights (short stage)
3012 {
3013 }
3014                    
3015
3016 /*
3017  * Compute stage dependent relative material values assuming
3018  * linearity between the main stages:
3019  *                         
3020  *   minstage < stage < maxstage => 
3021  *          stage - minstage        value - minvalue
3022  *         -------------------  =  -------------------
3023  *         maxstage - minstage     maxvalue - minvalue
3024  */
3025                                 
3026
3027 static short linear_piece_value (short piece, short stage, short i, short j)
3028 {
3029   short minvalue, maxvalue, minstage, maxstage;
3030   minstage = ispvalue[0][i];
3031   maxstage = ispvalue[0][j];
3032   minvalue = ispvalue[piece][i];
3033   maxvalue = ispvalue[piece][j];
3034   return ((stage-minstage)*(maxvalue-minvalue)/(maxstage-minstage))+minvalue;
3035 }
3036
3037 static short linear_feature_value (short feature, short stage, short i, short j)
3038 {
3039   short minvalue, maxvalue, minstage, maxstage;
3040   minstage = ispvalue[0][i];
3041   maxstage = ispvalue[0][j];
3042   minvalue = weight[feature][i];
3043   maxvalue = weight[feature][j];
3044   return ((stage-minstage)*(maxvalue-minvalue)/(maxstage-minstage))+minvalue;
3045 }
3046
3047
3048 /*
3049  * matweight = percentage_of_max_value * max_value(stage) / 100
3050  * max_value(0) = MAX_VALUE; max_value(100) = MIN_VALUE
3051  *  => max_value(stage) = a*stage+b; b=MAX_VALUE, a=(MIN_VALUE-MAX_VALUE)/100
3052  */
3053
3054 #define MIN_VALUE 300
3055 #define MAX_VALUE 1000
3056
3057 #define max_value(stage) ((long)(MIN_VALUE - MAX_VALUE) * stage + (long)100 * MAX_VALUE)
3058 #define matweight(value,stage) ((long)max_value(stage) * value / 10000)
3059
3060
3061 void
3062 Initialize_eval (void)
3063 {     
3064   register short stage, piece, feature, i;
3065   
3066   for ( stage = 0; stage < NO_STAGES; stage++ ) {
3067     for ( i = 0; i < MAIN_STAGES; i++ ) {
3068             if ( stage == ispvalue[0][i] ) {
3069               for ( piece = 0; piece < NO_PIECES; piece++ )
3070                 (*value)[stage][piece] = 
3071                   matweight(ispvalue[piece][i],stage);
3072               for ( feature = 0; feature < NO_FEATURES; feature++ ) {
3073                 (*fscore)[stage][feature][0] =
3074                   (weight[feature][i] * weight[feature][MAIN_STAGES] + 50) / 100;
3075                 (*fscore)[stage][feature][1] =
3076                   (weight[feature][i] * weight[feature][MAIN_STAGES+1] + 50) / 100;
3077               }
3078               break;
3079             } if ( stage < ispvalue[0][i+1] ) {
3080               for ( piece = 0; piece < NO_PIECES; piece++ )
3081                 (*value)[stage][piece] = 
3082                   matweight(linear_piece_value(piece,stage,i,i+1),stage); 
3083               for ( feature = 0; feature < NO_FEATURES; feature++ ) {
3084                 (*fscore)[stage][feature][0] = 
3085                   (linear_feature_value(feature,stage,i,i+1) 
3086                     * weight[feature][MAIN_STAGES] + 50) /100;       
3087                 (*fscore)[stage][feature][1] = 
3088                   (linear_feature_value(feature,stage,i,i+1) 
3089                     * weight[feature][MAIN_STAGES+1] + 50) /100;       
3090               }
3091               break;
3092             }
3093     }
3094   }        
3095
3096 #ifdef DEBUG_EVAL
3097    debug_eval = ((debug_eval_file = fopen(EVALFILE,"w")) != NULL);
3098    if ( debug_eval ) {
3099       fprintf(debug_eval_file,"stage dependent absolute material values\n\n");
3100       fprintf(debug_eval_file,"  #    -   P   L   N   S   G   B   R  +P  +L  +N  +S  +B  +R   K\n");
3101       for ( stage = 0; stage < NO_STAGES; stage++ ) {
3102         fprintf(debug_eval_file,"%3d:",stage);
3103         for ( piece = 0; piece < NO_PIECES; piece++ ) {
3104           fprintf(debug_eval_file,"%4d",(*value)[stage][piece]);
3105         }                                           
3106         fprintf(debug_eval_file,"\n");
3107       }
3108       fprintf(debug_eval_file,"\n");
3109       fprintf(debug_eval_file,"stage dependent absolute feature scores\n\n");
3110       fprintf(debug_eval_file,"  # ");
3111       for ( feature = 0; feature < NO_FEATURES; feature++ )
3112         fprintf(debug_eval_file,"%5d   ",feature);
3113       fprintf(debug_eval_file,"\n");      
3114       for ( stage = 0; stage < NO_STAGES; stage++ ) {
3115         fprintf(debug_eval_file,"%3d:",stage);
3116         for ( feature = 0; feature < NO_FEATURES; feature++ ) {
3117           fprintf(debug_eval_file," %3d,%3d",
3118             (*fscore)[stage][feature][0], (*fscore)[stage][feature][1]);
3119         }                                           
3120         fprintf(debug_eval_file,"\n");
3121       }
3122       fprintf(debug_eval_file,"\n");
3123       fclose(debug_eval_file);
3124       debug_eval = false;
3125    };
3126 #endif
3127 }
3128