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