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