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