12197a2ad1567cb038ce1544d390712c64554af0
[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 inline static short
343 on_column(short side, short piece, short c)
344 {
345     short sq;
346
347     for (sq = c; sq < NO_SQUARES; sq += NO_COLS)
348     {
349         if (on_csquare(side, piece, sq))
350             return true;
351     }
352
353     return false;
354 }
355
356
357 #define empty_csquare(side, square) \
358   (board[csquare(side, square)] == no_piece)
359
360 inline static short
361 on_left_side(short side, short piece)
362 {
363     short c;
364
365     for (c = 0; c < 4; c++)
366     {
367         if (on_column(side, piece, c))
368             return true;
369     }
370
371     return false;
372 }
373
374
375 inline static short
376 on_right_side(short side, short piece)
377 {
378     short c;
379
380     for (c = 5; c < NO_COLS; c++)
381     {
382         if (on_column(side, piece, c))
383             return true;
384     }
385
386     return false;
387 }
388
389
390 short pscore[2];  /* piece score for each side */
391
392
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, csq = column(sq);
830     short piece, upiece, xupiece, rvalue, ds;
831     small_short *Kd = Kdist[c2];
832
833     mobx = s = 0;
834     piece = board[sq];
835
836     rvalue = (*value)[stage][piece];
837     ptyp = ptype[c1][upiece = unpromoted[piece]];
838     rvalue = (*value)[stage][upiece];
839
840 #ifdef SAVE_NEXTPOS
841     u = first_direction(ptyp, &d, sq);
842 #else
843     ppos = (*nextpos[ptyp])[sq];
844     pdir = (*nextdir[ptyp])[sq];
845     u = ppos[sq];
846 #endif
847
848     pin = -1;           /* start new direction */
849
850     do
851     {
852         if (Kd[u] < 2)
853         {
854             s += (ds = fv1[CTRLK] * (2 - Kd[u]));
855         }
856
857         if ((ds = starget[c1][u]) != 0)
858         {
859             /* threatening a target square */
860             if ((pin < 0)               /* direct threat */
861                 || (color[pin] == c2))  /* pin threat    */
862             {
863                 s += (ds *= fv1[TARGET]);
864             }
865         }
866
867         if ((ds = shole[u]) != 0)
868         {
869             /* attacking or protecting a hole */
870             s += (ds = fv1[HOLES]);
871         }
872         else if (InPromotionZone(c1, u))
873         {
874             /* attacking a square in promotion zone */
875             s += (ds = fv1[HOLES] / 2);
876         }
877
878         if (color[u] == neutral)
879         {
880 #ifdef SAVE_NEXTPOS
881             dd = d;
882             xu = next_position(ptyp, &d, sq, u);
883
884             if (xu == next_direction(ptyp, &dd, sq))
885                 pin = -1;   /* oops new direction */
886 #else
887
888             if ((xu = ppos[u]) == pdir[u])
889                 pin = -1;   /* oops new direction */
890 #endif
891             u = xu;
892             mobx++;
893         }
894         else
895         {
896             /* there is a piece in current direction */
897             if (pin < 0)
898             {
899                 /* it's the first piece in the current direction */
900                 if (color[u] == c1)
901                 {
902 #ifndef MINISHOGI
903                     /* own intercepting piece in x-ray attack */
904                     if (upiece == lance)
905                     {
906                         /* lance x-ray */
907                         if (board[u] == pawn)
908                         {
909                             s += (ds = 2*fv1[PROTECT]);
910                         }
911                         else if (in_opening_stage)
912                         {
913                             s += (ds = -2*fv1[PROTECT]);
914                         }
915                     }
916                     else
917 #endif
918                     {
919                         /* bishop or rook x-ray */
920                         if ((upiece == bishop) && (board[u] == pawn)
921                             && (GameType[c1] == STATIC_ROOK))
922                         {
923                             s += (ds = -2*fv1[HCLSD]);
924                         }
925 #ifndef MINISHOGI
926                         else if ((upiece == rook) && (board[u] == lance)
927                                  && (GameType[c1] == STATIC_ROOK)
928                                  && (column(u) == csq))
929                         {
930                             s += (ds = fv1[XRAY]);
931                         }
932 #endif
933                     }
934                 }
935                 else
936                 {
937                     /* enemy's intercepting piece in pin attack */
938 #ifndef MINISHOGI
939                     if (upiece == lance)
940                     {
941                         /* lance pin attack */
942                         if (board[u] == pawn)
943                         {
944                             s += (ds = -2*fv1[PROTECT]);
945                         }
946                         else if (in_opening_stage)
947                         {
948                             s += (ds = 2 * fv1[PROTECT]);
949                         }
950                     }
951                     else
952 #endif
953                     {
954                         /* bishop or rook pin attack */
955                         if (board[u] == pawn)
956                         {
957                             s += (ds = -fv1[HCLSD]);
958                         }
959                     }
960                 }
961
962 #ifdef SAVE_NEXTPOS
963                 dd = d;
964                 xu = next_position(ptyp, &d, sq, u);
965
966                 if (xu != next_direction(ptyp, &dd, sq))
967                     pin = u;    /* not on the edge and on to find a pin */
968 #else
969                 if ((xu = ppos[u]) != pdir[u])
970                     pin = u;    /* not on the edge and on to find a pin */
971 #endif
972                 u = xu;
973             }
974             else
975             {
976                 /* it's the second piece in the current direction */
977
978                 if (color[u] == c1)
979                 {
980                     /* second piece is an own piece */
981                     if ((upiece == bishop) && (board[u] == pawn)
982                         && (GameType[c1] == STATIC_ROOK))
983                     {
984                         s += (ds = -fv1[HCLSD]);
985                     }
986                 }
987                 else
988                 {
989                     /* second piece is an enemy piece */
990                     if (upiece == bishop && board[u] == pawn)
991                     {
992                         s += (ds = -fv1[HCLSD]/2);
993                     }
994
995                     if (((*value)[stage][xupiece = unpromoted[board[u]]]
996                          > rvalue)
997                         || (atk2[u] == 0))
998                     {
999                         if (color[pin] == c2)
1000                         {
1001                             if ((xupiece == king) && (in_endgame_stage))
1002                             {
1003                                 s += (ds = 2 * fv1[PINVAL]);
1004                             }
1005                             else
1006                             {
1007                                 s += (ds = fv1[PINVAL]);
1008                             }
1009
1010                             if ((atk2[pin] == 0)
1011                                 || (atk1[pin] > control[board[pin]] + 1))
1012                             {
1013                                 hung[c2]++;
1014                                 shung[u]++;
1015                             }
1016                         }
1017                         else
1018                         {
1019 #ifndef MINISHOGI
1020                             if (upiece == lance)
1021                             {
1022                                 s += (ds = fv1[XRAY] / 2);
1023                             }
1024                             else
1025 #endif
1026                             {
1027                                 s += (ds = fv1[XRAY]);
1028                             }
1029                         }
1030                     }
1031                 }
1032
1033                 pin = -1;   /* new direction */
1034
1035 #ifdef SAVE_NEXTPOS
1036                 u = next_direction(ptyp, &d, sq);
1037 #else
1038                 u = pdir[u];
1039 #endif
1040             }
1041         }
1042     }
1043     while (u != sq);
1044
1045     *mob = mobx;
1046
1047     return s;
1048 }
1049
1050
1051 #define ctlSG (ctlS | ctlG | ctlPp | ctlLp | ctlNp | ctlSp)
1052
1053
1054
1055 /*
1056  * Assign penalties if king can be threatened by checks, if squares near
1057  * the king are controlled by the enemy (especially by promoted pieces), or
1058  * if there are no own generals near the king.
1059  *
1060  * The following must be true:
1061  * board[sq] == king, c1 == color[sq], c2 == otherside[c1]
1062  */
1063
1064 #define SCORETHREAT \
1065 { \
1066     if (color[u] != c2) \
1067     { \
1068         if ((atk1[u] == 0) || ((atk2[u] & CNT_MASK) != 0)) \
1069         { \
1070             ++cnt; \
1071         } \
1072         else \
1073         { \
1074             s += (ds = -fv1[CTRLK]); \
1075         } \
1076     } \
1077 }
1078
1079
1080
1081
1082 inline short
1083 KingScan(short sq)
1084 {
1085     short cnt;
1086
1087 #ifdef SAVE_NEXTPOS
1088     short d;
1089 #else
1090     unsigned char  *ppos, *pdir;
1091 #endif
1092
1093     short s;
1094     short u, ptyp;
1095     short ok, ds;
1096
1097     /* Penalties, if a king can be threatened by checks. */
1098
1099     s = 0;
1100     cnt = 0;
1101
1102     {
1103         short p;
1104
1105         for (p = pawn; p < king; p++)
1106         {
1107             if (HasPiece[c2][p] || Captured[c2][p])
1108             {
1109                 short ptyp;
1110
1111                 /* if a c1 piece can reach u from sq,
1112                  * then a c2 piece can reach sq from u.
1113                  * That means, each u is a square, from which a
1114                  * piece of type p and color c2 threats square sq.
1115                  */
1116                 ptyp = ptype[c1][p];
1117
1118 #ifdef SAVE_NEXTPOS
1119                 u = first_direction(ptyp, &d, sq);
1120 #else
1121                 ppos = (*nextpos[ptyp])[sq];
1122                 pdir = (*nextdir[ptyp])[sq];
1123                 u = ppos[sq];
1124 #endif
1125
1126                 do
1127                 {
1128                     /* If a p piece can reach (controls or can drop to)
1129                      * square u, then score threat.
1130                      */
1131
1132                     if (atk2[u] & control[p])
1133                         SCORETHREAT
1134                     else if ((Captured[c2][p] && color[u]) == neutral)
1135                         SCORETHREAT
1136
1137 #ifdef SAVE_NEXTPOS
1138                     u = ((color[u] == neutral)
1139                          ? next_position(ptyp, &d, sq, u)
1140                          : next_direction(ptyp, &d, sq));
1141 #else
1142                     u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
1143 #endif
1144                 }
1145                 while (u != sq);
1146             }
1147         }
1148     }
1149
1150     s += (ds = fv1[KSFTY] * KTHRT[cnt] / 16);
1151
1152     /* Penalties, if squares near king are controlled by enemy. */
1153
1154     cnt = 0;
1155     ok = false;
1156     ptyp = ptype[c1][king];
1157
1158 #ifdef SAVE_NEXTPOS
1159     u = first_direction(ptyp, &d, sq);
1160 #else
1161     pdir = (*nextpos[ptyp])[sq];
1162     u = pdir[sq];
1163 #endif
1164
1165     do
1166     {
1167         if (!ok && color[u] == c1)
1168         {
1169             short ptype_piece = ptype[black][board[u]];
1170
1171             if ((ptype_piece == ptype_silver) || (ptype_piece == ptype_gold))
1172                 ok = true;
1173         }
1174
1175         if (atk2[u] > atk1[u])
1176         {
1177             ++cnt;
1178
1179             if (atk2[u] & ctlSG)
1180             {
1181                 s += (ds = -fv1[KSFTY] / 2);
1182             }
1183         }
1184
1185 #ifdef SAVE_NEXTPOS
1186         u = next_direction(ptyp, &d, sq);
1187 #else
1188         u = pdir[u];
1189 #endif
1190     }
1191     while (u != sq);
1192
1193     if (!ok || (cnt > 1))
1194     {
1195         if (cnt > 1)
1196             s += (ds = -fv1[KSFTY]/2);
1197         else
1198             s += (ds = -fv1[KSFTY]);
1199     }
1200
1201     return s;
1202 }
1203
1204
1205 static short checked_trapped;
1206
1207
1208 /*
1209  * See if the attacked piece has unattacked squares to move to. The following
1210  * must be true: c1 == color[sq] c2 == otherside[c1]
1211  */
1212
1213 inline int
1214 trapped(short sq)
1215 {
1216     short u, ptyp;
1217 #ifdef SAVE_NEXTPOS
1218     short d;
1219 #else
1220     unsigned char *ppos, *pdir;
1221 #endif
1222     short piece;
1223     short rvalue;
1224
1225     piece  = board[sq];
1226     rvalue = (*value)[stage][piece];
1227     ptyp   = ptype[c1][piece];
1228
1229 #ifdef SAVE_NEXTPOS
1230     u = first_direction(ptyp, &d, sq);
1231 #else
1232     ppos = (*nextpos[ptyp])[sq];
1233     pdir = (*nextdir[ptyp])[sq];
1234     u = ppos[sq];
1235 #endif
1236
1237     do
1238     {
1239         if (color[u] != c1)
1240         {
1241             if ((atk2[u] == 0) || ((*value)[stage][board[u]] >= rvalue))
1242                 return false;
1243         }
1244
1245 #ifdef SAVE_NEXTPOS
1246         u = ((color[u] == neutral)
1247              ? next_position(ptyp, &d, sq, u)
1248              : next_direction(ptyp, &d, sq));
1249 #else
1250         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
1251 #endif
1252     }
1253     while (u != sq);
1254
1255     checked_trapped = true;
1256
1257     return true;
1258 }
1259
1260
1261
1262 static int
1263 AttackedPieceValue(short sq)
1264 {
1265     short s;
1266
1267     s = 0;
1268
1269     hung[c1]++;
1270     shung[sq]++;
1271
1272     if (trapped(sq))
1273     {
1274         hung[c1]  += 2;
1275         shung[sq] += 2;
1276     }
1277
1278     return s;
1279 }
1280
1281
1282
1283 static inline int
1284 OpenFileValue(short sq, short hopn, short hopnx)
1285 {
1286     short s = 0, fyle;
1287
1288     if (PC1[fyle = column(sq)] == 0)
1289     {
1290         s += hopn;
1291     }
1292
1293     if (PC2[fyle] == 0)
1294     {
1295         s += hopnx;
1296     }
1297
1298     return s;
1299 }
1300
1301
1302
1303
1304 /* Distance bonus */
1305
1306 #define PromotionZoneDistanceValue(sq, dd) \
1307 if ((ds = fv1[PROMD])) \
1308 { \
1309     s += (ds = ds * PromotionZoneDistanceBonus[crow(c1, sq)] * dd); \
1310 }
1311
1312 #define OwnKingDistanceValue(sq, dd, maxd) \
1313 if ((ds = fv1[KINGOD]) && ((ad = Kdist[c1][sq]) <= maxd)) \
1314 { \
1315     s += (ds = ds * OwnKingDistanceBonus[ad] * dd); \
1316 }
1317
1318 #define EnemyKingDistanceValue(sq, dd, maxd) \
1319 if ((ds = fv1[KINGOD]) && ((ad = Kdist[c2][sq]) <= maxd)) \
1320 { \
1321     s += (ds = ds * EnemyKingDistanceBonus[ad] * dd); \
1322 }
1323
1324
1325
1326
1327
1328 /*
1329  * Calculate the positional value for a pawn on 'sq'.
1330  */
1331
1332 static inline int
1333 PawnValue(short sq, short side)
1334 {
1335     short s = 0;
1336     short ds;
1337     short ccol = ccolumn(c1, sq);
1338
1339     PromotionZoneDistanceValue(sq, 3);
1340
1341     /* pawn mobility */
1342     if (color[(c1 == black) ? (sq + NO_COLS) : (sq - NO_COLS)] == neutral)
1343     {
1344         s += (ds = MBLTY[pawn]);
1345     }
1346
1347     if ((a1 & ((ctlR | ctlRp) | ctlL)))
1348     {
1349         s += (ds = fv1[ATTACKED]);
1350     }
1351
1352     if (in_opening_stage)
1353     {
1354 #ifndef MINISHOGI
1355 /* FIXME: [HGM] The 3rd-rank Pawn section is meaningless in mini-Shogi,
1356  * (which does not have opposing Pawns), and can do out-of-bound access,
1357  * as the promotion zone is only 1 rank, so Pawns can be closer than 3 ranks
1358  * to the board edge.
1359  */
1360         if (crow(c1, sq) == 2) /* pawn on 3d rank */
1361         {
1362             if (board[(c1 == black) ?
1363                       (sq + 3*NO_COLS) : (sq - 3*NO_COLS)] == pawn)
1364             {
1365                 /* opposing pawn has been moved (even column == (sq & 1)) */
1366
1367                 short m;
1368
1369                 switch (ccol)
1370                 {
1371                 case 0:
1372                 case 8:
1373                     m = (side == c1) ? 3 : 5;
1374                     break;
1375
1376                 case 4:
1377                     m = (side == c1) ? 2 : 3;
1378                     break;
1379
1380                 default:
1381                     m = (side == c1) ? 1 : 2;
1382                     break;
1383                 }
1384
1385                 s += (ds = -m * MBLTY[pawn]);
1386             }
1387         }
1388
1389 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1390  * board - and anyway we don't know the stage really :)
1391  */
1392         if ((GameType[c1] == STATIC_ROOK) && (sq == csquare(c1, 43)))
1393         {
1394             if ((atk2[csquare(c1, 52)] & CNT_MASK) < 2)
1395             {
1396                 s += (ds = fv1[ATTACKED]);
1397             }
1398         }
1399
1400         if ((GameType[c2] == STATIC_ROOK) && (ccol == 1))
1401         {
1402             if (sq == csquare(c1, 28))
1403             {
1404                 s += (ds = -fv1[ATTACKED]);
1405             }
1406
1407             if (((atk1[csquare(c1, 19)] & CNT_MASK) < 2)
1408                 && ((atk1[csquare(c1, 28)] & CNT_MASK) < 2))
1409             {
1410                 s += (ds = -2 * fv1[ATTACKED]);
1411             }
1412         }
1413 #endif
1414     }
1415
1416     return s;
1417 }
1418
1419
1420 #ifndef MINISHOGI
1421 /*
1422  * Calculate the positional value for a lance on 'sq'.
1423  */
1424
1425 static inline int
1426 LanceValue(short sq)
1427 {
1428     short s = 0, ds, ad;
1429
1430     OwnKingDistanceValue(sq, 1, 2);
1431
1432     OpenFileValue(sq, -fv1[HOPN], fv1[HOPN]);
1433
1434     if (!checked_trapped && (crow(c1, sq) > 2))
1435     {
1436         if (in_opening_stage || trapped(sq))
1437         {
1438             s += (ds = -3 * fv1[ATTACKED]);
1439         }
1440         else
1441         {
1442             s += (ds = -2 * fv1[ATTACKED]);
1443         }
1444     }
1445
1446     return s;
1447 }
1448
1449
1450
1451 /*
1452  * Calculate the positional value for a knight on 'sq'.
1453  */
1454
1455 static inline int
1456 KnightValue(short sq)
1457 {
1458     short s = 0, ad;
1459     short ds, checked_trapped = false;
1460     short c = column(sq);
1461
1462     PromotionZoneDistanceValue(sq, 1);
1463     OwnKingDistanceValue(sq, 1, 2);
1464
1465     if (!checked_trapped && (crow(c1, sq) > 2))
1466     {
1467         if (trapped(sq))
1468         {
1469             s += (ds = -4 * fv1[ATTACKED]);
1470         }
1471         else
1472         {
1473             s += (ds = -3 * fv1[ATTACKED]);
1474         }
1475     }
1476
1477     if ((c == 0) || (c == 8))
1478     {
1479         s += (ds = -fv1[ATTACKED]);
1480     }
1481
1482     return s;
1483 }
1484 #endif
1485
1486
1487
1488 /*
1489  * Calculate the positional value for a silver on 'sq'.
1490  */
1491
1492 static inline int
1493 SilverValue(short sq)
1494 {
1495     short s= 0, ds, ad;
1496
1497     OwnKingDistanceValue(sq, 2, 3);
1498
1499     if ((Kdist[c1][sq] < 3)
1500         && (atk1[sq] & (control[gold] | control[silver])))
1501     {
1502         s += (ds = fv1[COHESION]);
1503     }
1504
1505     if (in_opening_stage)
1506     {
1507 #ifndef MINISHOGI
1508 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1509  * board - and anyway we don't know the stage really :)
1510  */
1511         if (GameType[c1] == STATIC_ROOK)
1512         {
1513             if (csquare(c1, sq) == 12)
1514             {
1515                 short csq;
1516
1517                 if ((board[csq = csquare(c1, 20)] == bishop)
1518                     && (color[csq] == c1))
1519                 {
1520                     s += (ds = -2 * fv1[OPENWRONG]);
1521                 }
1522             }
1523         }
1524 #endif
1525     }
1526     else
1527     {
1528         EnemyKingDistanceValue(sq, 2, 3);
1529     }
1530
1531     return s;
1532 }
1533
1534
1535
1536 /*
1537  * Calculate the positional value for a gold on 'sq'.
1538  */
1539
1540 static inline int
1541 GoldValue(short sq)
1542 {
1543     short s = 0, ds, ad;
1544
1545     OwnKingDistanceValue(sq, 2, 3);
1546
1547     if ((Kdist[c1][sq] < 3)
1548         && (atk1[sq] & (control[gold] | control[silver])))
1549     {
1550         s += (ds = fv1[COHESION]);
1551     }
1552
1553     if (in_opening_stage)
1554     {
1555 #ifndef MINISHOGI
1556 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1557  * board - and anyway we don't know the stage really :)
1558  */
1559         if ((GameType[c1] == STATIC_ROOK) && (GameType[c2] != STATIC_ROOK))
1560         {
1561             if (Mvboard[csquare(c1, 3)])
1562             {
1563                 s += (ds = -2 * fv1[OPENWRONG]);
1564             }
1565         }
1566 #endif
1567     }
1568     else
1569     {
1570         EnemyKingDistanceValue(sq, 2, 3);
1571     }
1572
1573     return s;
1574 }
1575
1576
1577
1578 /*
1579  * Calculate the positional value for a bishop on 'sq'.
1580  */
1581
1582 static inline int
1583 BishopValue(short sq)
1584 {
1585     short s = 0, ds, ad;
1586
1587     if (in_opening_stage)
1588     {
1589 #ifndef MINISHOGI
1590 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1591  * board - and anyway we don't know the stage really :)
1592  */
1593         if (GameType[c1] == RANGING_ROOK)
1594         {
1595             /* Bishops diagonal should not be open */
1596             if (!on_csquare(c1, pawn, 30))
1597             {
1598                 s += (ds = -fv1[OPENWRONG]);
1599             }
1600         }
1601         else if (GameType[c2] == RANGING_ROOK)
1602         {
1603             /* Bishops diagonal should be open */
1604             if ((csquare(c1, sq) == 10)
1605                 && (!empty_csquare(c1, 20) || !empty_csquare(c1, 30)))
1606             {
1607                 s += (ds = -fv1[OPENWRONG]);
1608             }
1609             else if ((csquare(c1, sq) == 20) && !empty_csquare(c1, 30))
1610             {
1611                 s += (ds = -fv1[OPENWRONG]);
1612             }
1613         }
1614 #endif
1615     }
1616     else
1617     {
1618         EnemyKingDistanceValue(sq, 1, 3);
1619     }
1620
1621     return s;
1622 }
1623
1624
1625
1626 /*
1627  * Calculate the positional value for a rook on 'sq'.
1628  */
1629
1630 static inline int
1631 RookValue(short sq, short side)
1632 {
1633     short s = 0, ds, ad;
1634
1635     OpenFileValue(sq, 2 * fv1[HOPN], 4*fv1[HOPN]);
1636
1637     if (in_opening_stage)
1638     {
1639 #ifndef MINISHOGI
1640 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1641  * board - and anyway we don't know the stage really :)
1642  */
1643         short WRONG = fv1[OPENWRONG], OPOK = WRONG / 3;
1644
1645         if (GameType[c1] == STATIC_ROOK)
1646         {
1647             short c = ccolumn(c1, sq);
1648
1649             /* Bonus for rook on 8th file */
1650             if (c == 7)
1651             {
1652                  s += (ds = OPOK);
1653             }
1654
1655             /*
1656              * Bonus for rook on right side,
1657              * penalty for rook on left side
1658              */
1659
1660             c = 4 - c;
1661             ds = 0;
1662
1663             if (c < 0)
1664             {
1665                 s += (ds = c + c + OPOK);
1666             }
1667             else if (c >= 0)
1668             {
1669                 s += (ds = -c - c - WRONG);
1670             }
1671         }
1672         else if (GameType[c1] == RANGING_ROOK)
1673         {
1674             /* Bonus for rook on left side and
1675              * bishops diagonal closed, penalty otherwise. */
1676
1677             short c;
1678             c = 4 - ccolumn(c1, sq);
1679             ds = 0;
1680
1681             if (c >= 0)
1682             {
1683                 /* Bishops diagonal should not be open. */
1684                 if (on_csquare(c1, pawn, 30))
1685                     s += (ds = OPOK);
1686                 else
1687                     s += (ds = -c - c - WRONG);
1688             }
1689             else if (c < 0)
1690             {
1691                 s += (ds = -c - c - WRONG);
1692
1693                 /* Penalty for king not on initial square. */
1694                 if (!on_csquare(side, king, 4))
1695                 {
1696                     s  += -4 * WRONG;
1697                     ds += -4 * WRONG;
1698                 }
1699             }
1700         }
1701 #endif
1702     }
1703     else
1704     {
1705         EnemyKingDistanceValue(sq, 1, 3);
1706     }
1707
1708     return s;
1709 }
1710
1711
1712
1713 /*
1714  * Calculate the positional value for a promoted pawn on 'sq'.
1715  */
1716
1717 static inline int
1718 PPawnValue(short sq)
1719 {
1720     short s = 0, ds, ad;
1721
1722     EnemyKingDistanceValue(sq, 3, 10);
1723
1724     return s;
1725 }
1726
1727
1728
1729 #ifndef MINISHOGI
1730 /*
1731  * Calculate the positional value for a promoted lance on 'sq'.
1732  */
1733
1734 static inline int
1735 PLanceValue(short sq)
1736 {
1737     short s = 0, ds, ad;
1738
1739     EnemyKingDistanceValue(sq, 3, 10);
1740
1741     return s;
1742 }
1743
1744
1745
1746 /*
1747  * Calculate the positional value for a promoted knight on 'sq'.
1748  */
1749
1750 static inline int
1751 PKnightValue(short sq)
1752 {
1753     short s = 0, ds, ad;
1754
1755     EnemyKingDistanceValue(sq, 3, 10);
1756
1757     return s;
1758 }
1759 #endif
1760
1761
1762
1763 /*
1764  * Calculate the positional value for a promoted silver on 'sq'.
1765  */
1766
1767 static inline int
1768 PSilverValue(short sq)
1769 {
1770     short s = 0, ds, ad;
1771
1772     EnemyKingDistanceValue(sq, 3, 10);
1773
1774     return s;
1775 }
1776
1777
1778
1779 /*
1780  * Calculate the positional value for a promoted bishop on 'sq'.
1781  */
1782
1783 static inline int
1784 PBishopValue(short sq)
1785 {
1786     short s = 0, ds, ad;
1787
1788     EnemyKingDistanceValue(sq, 3, 4);
1789
1790     return s;
1791 }
1792
1793
1794
1795 /*
1796  * Calculate the positional value for a promoted rook on 'sq'.
1797  */
1798
1799 static inline int
1800 PRookValue(short sq)
1801 {
1802     short s = 0, ds, ad;
1803
1804     EnemyKingDistanceValue(sq, 3, 4);
1805
1806     OpenFileValue(sq, 3 * fv1[HOPN], 2 * fv1[HOPN]);
1807
1808     return s;
1809 }
1810
1811
1812
1813 /*
1814  * Calculate the positional value for a king on 'sq'.
1815  */
1816
1817 static inline int
1818 KingValue(short sq)
1819 {
1820     short s = 0, ds;
1821
1822     if (fv1[KSFTY] != 0)
1823         s += KingScan(sq);
1824
1825 #ifndef MINISHOGI
1826 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1827  * board - and anyway we don't know the stage really :)
1828  */
1829     if (in_opening_stage)
1830     {
1831         if ((GameType[c1] != UNKNOWN) && (ccolumn(c1, sq) == 4))
1832         {
1833             s += (ds = -fv1[OPENWRONG] / 3);
1834         }
1835         else if ((GameType[c1] == STATIC_ROOK) && on_right_side(c1, sq))
1836         {
1837             s += (ds = -fv1[OPENWRONG] / 2);
1838         }
1839         else if ((GameType[c1] == RANGING_ROOK) && on_left_side(c1, sq))
1840         {
1841             s += (ds = -fv1[OPENWRONG] / 2);
1842         }
1843     }
1844 #endif
1845
1846     /* CHECKME: is this correct? */
1847     if ((ds = fv1[HOPN]))
1848     {
1849         s += OpenFileValue(sq, -2 * ds, -4 * ds);
1850     }
1851
1852     return s;
1853 }
1854
1855
1856
1857 /*
1858  * Calculate the positional value for a piece on 'sq'.
1859  */
1860
1861 static inline int
1862 PieceValue(short sq, short side)
1863 {
1864     short s, piece, ds;
1865     short mob;
1866
1867     piece = board[sq];
1868
1869     if (piece == no_piece)
1870         return 0;
1871
1872     s = (*Mpiece[piece])[c1][sq];
1873
1874     checked_trapped = false;
1875
1876     if (sweep[piece])
1877     {
1878         /* pin/x-ray attack and mobility for sweeping pieces */
1879         s += (ds = BRLscan(sq, &mob));
1880
1881         if ((piece == bishop) || (piece == pbishop))
1882             s += (ds = BMBLTY[mob] * fv1[MOBILITY] / 100);
1883         else if ((piece == rook) || (piece == prook))
1884             s += (ds = RMBLTY[mob] * fv1[MOBILITY] / 100);
1885 #ifndef MINISHOGI
1886         else
1887             s += (ds = LMBLTY[mob] * fv1[MOBILITY] / 100);
1888 #endif
1889     }
1890     else
1891     {
1892         /* mobility for non-sweeping pieces */
1893     }
1894
1895     a2 = atk2[sq];
1896     a1 = atk1[sq];
1897
1898     if (a2 > 0)
1899     {
1900         /* opponent attacks piece */
1901         if (a1 == 0)
1902         {
1903             /* undefended piece */
1904             s += AttackedPieceValue(sq);
1905         }
1906         else
1907         {
1908             /* defended piece */
1909             short attack_value = value_of_weakest_attacker(a2);
1910             short piece_value = (*value)[stage][piece];
1911
1912             if (attack_value < piece_value)
1913             {
1914                 /* attacked by a weaker piece */
1915                 s += AttackedPieceValue(sq) / 2;
1916             }
1917             else if (abs(attack_value - piece_value) < 10)
1918             {
1919                 /* opponent has the option to exchange equal pieces */
1920                 s += (ds = -fv1[ATTACKED]);
1921             }
1922         }
1923     }
1924
1925     if (piece != king)
1926     {
1927
1928         if (a1 > 0)
1929         {
1930             /* piece is defended */
1931             s += (ds = (a1 & CNT_MASK) * fv1[PROTECT]);
1932         }
1933
1934         if (sseed[sq])
1935         {
1936             s += (ds = fv1[SEED]);
1937         }
1938
1939         if (sloose[sq])
1940         {
1941             s += (ds = -fv1[LOOSE]);
1942         }
1943
1944         if (starget[c1][sq])
1945         {
1946             if (sweep[piece])
1947             {
1948                 s -= (ds = -fv1[ATTACKED]/2);
1949             }
1950             else if (piece == pawn)
1951             {
1952                 s += (ds = fv1[ATTACKED]);
1953             }
1954         }
1955
1956         if (starget[c2][sq])
1957         {
1958             if (piece != pawn)
1959             {
1960                 s -= (ds = -fv1[ATTACKED] / 3);
1961             }
1962             else
1963             {
1964                 s += (ds = fv1[ATTACKED]);
1965             }
1966         }
1967
1968         if (Kdist[c1][sq] == 1)
1969         {
1970             s += (ds = fv1[KSFTY]);
1971         }
1972     }
1973
1974     switch (piece)
1975     {
1976     case pawn:
1977         s += PawnValue(sq, side);
1978         break;
1979
1980 #ifndef MINISHOGI
1981     case lance:
1982         s += LanceValue(sq);
1983         break;
1984
1985     case knight:
1986         s += KnightValue(sq);
1987         break;
1988 #endif
1989
1990     case silver:
1991         s += SilverValue(sq);
1992         break;
1993
1994     case gold:
1995         s += GoldValue(sq);
1996         break;
1997
1998     case bishop:
1999         s += BishopValue(sq);
2000         break;
2001
2002     case rook:
2003         s += RookValue(sq, side);
2004         break;
2005
2006     case king:
2007         s += KingValue(sq);
2008         break;
2009
2010     case ppawn:
2011         s += PPawnValue(sq);
2012         break;
2013
2014 #ifndef MINISHOGI
2015     case plance:
2016         s += PLanceValue(sq);
2017         break;
2018
2019     case pknight:
2020         s += PKnightValue(sq);
2021         break;
2022 #endif
2023
2024     case psilver:
2025         s += PSilverValue(sq);
2026         break;
2027
2028     case pbishop:
2029         s += PBishopValue(sq);
2030         break;
2031
2032     case prook:
2033         s += PRookValue(sq);
2034         break;
2035     }
2036
2037     return s;
2038 }
2039
2040
2041
2042 /*
2043  * Score distance to pattern regarding the game type which side plays.
2044  */
2045
2046 short
2047 ScorePatternDistance(short c1)
2048 {
2049     short ds, s = 0;
2050     small_short *fv1 = fvalue[c1];
2051     short os = 0;
2052
2053     if ((MAXCDIST > 0) && (fv1[PCASTLE] != 0)
2054         && ((os = castle_opening_sequence[c1]) >= 0))
2055     {
2056         ds = board_to_pattern_distance(c1, os, MAXCDIST, GameCnt);
2057
2058         if (ds != 0)
2059         {
2060             s += (ds *= fv1[PCASTLE]);
2061         }
2062     }
2063
2064     if ((MAXADIST > 0) && (fv1[PATTACK] != 0)
2065         && ((os = attack_opening_sequence[c1]) >= 0))
2066     {
2067         ds = board_to_pattern_distance(c1, os, MAXADIST, GameCnt);
2068
2069         if (ds != 0)
2070         {
2071             s += (ds *= fv1[PATTACK]);
2072         }
2073     }
2074
2075     return s;
2076 }
2077
2078
2079
2080
2081 /*
2082  * Determine castle and attack pattern which should be reached next.
2083  * Only patterns are considered, which have not been reached yet.
2084  */
2085
2086 static void
2087 UpdatePatterns(short side, short GameCnt)
2088 {
2089     char s[12];
2090     short xside = side ^ 1;
2091     short os;
2092     short j, k, n = 0;
2093
2094     strcpy(s, "CASTLE_?_?");
2095     s[7] = GameType[side];
2096     s[9] = GameType[xside];
2097     castle_opening_sequence[side] = os
2098         = locate_opening_sequence(side, s, GameCnt);
2099
2100     if (flag.post && (os != END_OF_SEQUENCES))
2101     {
2102         for (j = 0; j < MAX_SEQUENCE; j++)
2103         {
2104             for (k = OpeningSequence[os].first_pattern[j];
2105                  k != END_OF_PATTERNS;
2106                  k = Pattern[k].next_pattern)
2107             {
2108                 if (Pattern[k].distance[side] >= 0)
2109                     n++;
2110             }
2111         }
2112     }
2113
2114     if (os != END_OF_SEQUENCES)
2115         update_advance_bonus(side, os);
2116
2117     strcpy(s, "ATTACK_?_?");
2118     s[7] = GameType[side];
2119     s[9] = GameType[xside];
2120     attack_opening_sequence[side] = os
2121         = locate_opening_sequence(side, s, GameCnt);
2122
2123     if (flag.post && (os != END_OF_SEQUENCES))
2124     {
2125         for (j = 0; j < MAX_SEQUENCE; j++)
2126         {
2127             for (k = OpeningSequence[os].first_pattern[j];
2128                  k != END_OF_PATTERNS;
2129                  k = Pattern[k].next_pattern)
2130             {
2131                 if (Pattern[k].distance[side] >= 0)
2132                     n++;
2133             }
2134         }
2135     }
2136
2137     if (flag.post)
2138         dsp->ShowPatternCount(side, n);
2139
2140     if (os != END_OF_SEQUENCES)
2141         update_advance_bonus(side, os);
2142 }
2143
2144
2145
2146 static void
2147 ScoreCaptures(void)
2148 {
2149     short ds, col, n, m, piece;
2150
2151     if ((n = Captured[c1][pawn]))
2152     {
2153         ds = m = 0;
2154
2155         for (col = 0; col < NO_COLS; col++)
2156         {
2157             if (!PC1[col])
2158             {
2159                 m++;
2160                 ds += fv1[PWNDROP];
2161             }
2162         }
2163
2164         /* FIXME! another great obfuscated line... */
2165         pscore[c1] += (ds *= ((n > 2) ? 3 : n));
2166     }
2167
2168     if ((m = seed[c1]))
2169     {
2170         for (piece = pawn+1, n = 0; piece <= rook; piece++)
2171         {
2172             if (Captured[c1][piece])
2173                 n++;
2174         }
2175
2176         pscore[c1] += (ds = m * fv1[DFFDROP]);
2177     }
2178
2179     for (piece = pawn, n = 0; piece <= rook; piece++)
2180     {
2181         if (Captured[c1][piece])
2182         {
2183             switch (piece)
2184             {
2185             case bishop:
2186                 ds = BMBLTY[MAX_BMBLTY - 1];
2187                 break;
2188
2189             case rook:
2190                 ds = RMBLTY[MAX_RMBLTY - 1];
2191                 break;
2192
2193 #ifndef MINISHOGI
2194             case lance:
2195                 ds = LMBLTY[MAX_LMBLTY - 1];
2196                 break;
2197 #endif
2198
2199             default:
2200                 ds = MBLTY[piece];
2201             }
2202
2203             pscore[c1] += ds;
2204
2205             if (!Captured[c2][piece])
2206                 n += relative_value[piece];
2207         }
2208     }
2209
2210     if (n)
2211     {
2212         pscore[c1] += (ds = -n * fv1[OPPDROP] / 2);
2213     }
2214 }
2215
2216
2217
2218
2219
2220 /*
2221  * Perform normal static evaluation of board position. A score is generated
2222  * for each piece and these are summed to get a score for each side.
2223  */
2224
2225 short
2226 ScorePosition(short side)
2227 {
2228     short score;
2229     short sq, i, xside;
2230     short s;
2231     short ds;
2232
2233     xside = side ^ 1;
2234
2235     UpdateWeights(side);
2236
2237     hung[black] = hung[white] = pscore[black] = pscore[white] = 0;
2238
2239     array_zero(shung, sizeof(shung));
2240
2241 #ifdef CACHE
2242     if (!(use_etable && ProbeEETable(side, &s)))
2243     {
2244 #endif
2245         for (c1 = black; c1 <= white; c1++)
2246         {
2247             c2 = c1 ^ 1;
2248
2249             /* atk1 is array of attacks on squares by my side */
2250             atk1 = attack[c1];
2251
2252             /* atk2 is array of attacks on squares by other side */
2253             atk2 = attack[c2];
2254
2255             /* same for PC1 and PC2 */
2256             PC1 = PawnCnt[c1];
2257             PC2 = PawnCnt[c2];
2258
2259             /* same for fv1 and fv2 */
2260             fv1 = fvalue[c1];
2261
2262             for (i = PieceCnt[c1]; i >= 0; i--)
2263             {
2264                 sq = PieceList[c1][i];
2265
2266 #if defined SAVE_SVALUE
2267                 pscore[c1] += PieceValue(sq, side);
2268 #else
2269                 pscore[c1] += (svalue[sq] = PieceValue(sq, side));
2270 #endif
2271             }
2272
2273             ScoreCaptures();
2274         }
2275
2276 #ifndef MINISHOGI
2277 # define BLACKHOME_START  0
2278 # define BLACKHOME_END   26
2279 # define MIDDLEROW_START 36
2280 # define MIDDLEROW_END   44
2281 # define WHITEHOME_START 54
2282 # define WHITEHOME_END   80
2283 #else
2284 # define BLACKHOME_START  0
2285 # define BLACKHOME_END    4
2286 # define MIDDLEROW_START 10
2287 # define MIDDLEROW_END   14
2288 # define WHITEHOME_START 19
2289 # define WHITEHOME_END   24
2290 #endif
2291         for (c1 = black, c2 = white; c1 <= white; c1++, c2--)
2292         {
2293             short n;
2294
2295             fv1 = fvalue[c1];
2296
2297             /* Score fifth rank */
2298             for (sq = MIDDLEROW_START, n = 0; sq <= MIDDLEROW_END; sq++)
2299             {
2300                 if ((color[sq] == c1) || (attack[c1][sq] != 0))
2301                     n++;
2302             }
2303
2304             if (n != 0)
2305             {
2306                 pscore[c1] += (ds = n * fv1[CNTRL5TH]);
2307             }
2308
2309             /* Score holes */
2310             for (sq = ((c1 == black) ? BLACKHOME_START : WHITEHOME_START), n = 0;
2311                  sq <= ((c1 == black) ? BLACKHOME_END : WHITEHOME_END);
2312                  sq++)
2313             {
2314                 if (board[sq] == no_piece && attack[c1][sq] == 0)
2315                     n++;
2316             }
2317
2318             if (n != 0)
2319             {
2320                 pscore[c1] += (ds = -n * fv1[HOLES]);
2321             }
2322
2323             if (hung[c1] > 1)
2324             {
2325                 pscore[c1] += (ds = -fv1[HUNGX]);
2326             }
2327
2328             /* Score opening features and
2329              * castle/attack pattern distances */
2330
2331             if (in_opening_stage)
2332             {
2333                 pscore[c1] += (ds = ScoreKingOpeningFeatures());
2334                 pscore[c1] += (ds = ScorePatternDistance(c1));
2335             }
2336         }
2337
2338         score = mtl[side] - mtl[xside]
2339             + pscore[side] - pscore[xside] + 10;
2340
2341 #ifdef CACHE
2342         if (use_etable && PUTVAR)
2343             PutInEETable(side, score);
2344 #endif
2345
2346         return score;
2347 #ifdef CACHE /* CHECKME: this looks bad */
2348     }
2349
2350     return s;
2351 #endif
2352 }
2353
2354
2355
2356 /*
2357  * Try to determine the game type of "side".
2358  */
2359
2360 #ifndef MINISHOGI
2361 inline static void
2362 GuessGameType(short side_to_move)
2363 {
2364     short side, gt;
2365     short StaticRook[2]  = { 0, 0 };
2366     short RangingRook[2] = { 0, 0 };
2367
2368     for (side = black; side <= white; side++)
2369     {
2370         /* computer should not change its mind */
2371
2372         extern int bookflag;
2373
2374         gt = GameType[side];
2375
2376         if (!bookflag && (side == side_to_move))
2377         {
2378             if (gt == STATIC_ROOK)
2379                 StaticRook[side] += 4;
2380             else if (gt == RANGING_ROOK)
2381                 RangingRook[side] += 4;
2382         }
2383
2384         /* static rook conditions */
2385
2386         if (on_column(side, rook, 7))
2387             StaticRook[side] += 3;
2388
2389         if (on_csquare(side, pawn, 34))
2390             StaticRook[side] += 6;
2391         else if (on_csquare(side, pawn, 43))
2392             StaticRook[side] += 4;
2393         else if (!on_column(side, pawn, 7))
2394             StaticRook[side] += 5;
2395
2396         if (empty_csquare(side, 5) || empty_csquare(side, 6))
2397             StaticRook[side] += 2;
2398
2399         if (on_left_side(side, king))
2400             StaticRook[side] += 2;
2401
2402         /* ranging rook conditions */
2403
2404         if (on_left_side(side, rook))
2405             RangingRook[side] += 5;
2406         else if (!on_column(side, rook, 7))
2407             RangingRook[side] += 3;
2408
2409         if (on_csquare(side, pawn, 25))
2410             RangingRook[side] += 1;
2411
2412         if (on_csquare(side, pawn, 30))
2413             RangingRook[side] += 1;
2414         else
2415             RangingRook[side] -= 2;
2416
2417         if (!on_right_side(side, rook))
2418             RangingRook[side] += 4;
2419
2420         if (on_right_side(side, king))
2421             RangingRook[side] += 4;
2422
2423         if (on_csquare(side, bishop, 20))
2424         {
2425             if (on_csquare(side, silver, 11)
2426                 || on_csquare(side, silver, 12)
2427                 || on_csquare(side, silver, 21))
2428             {
2429                 RangingRook[side] += 3;
2430             }
2431         }
2432
2433         if ((StaticRook[side] > 5) || (RangingRook[side] > 5))
2434         {
2435             GameType[side] = (StaticRook[side] > RangingRook[side])
2436                 ? STATIC_ROOK : RANGING_ROOK;
2437         }
2438         else
2439         {
2440             GameType[side] = UNKNOWN;
2441         }
2442     }
2443
2444     if ((GameType[black] == UNKNOWN) || (GameType[white] == UNKNOWN))
2445     {
2446         for (side = black; side <= white; side++)
2447         {
2448             if ((side == computer) && (GameType[side] == UNKNOWN))
2449             {
2450                 /*
2451                  * Game type is UNKNOWN.
2452                  * Make a decision what type of game to play.
2453                  * To make computer games more interesting, make a
2454                  * random decision.
2455                  */
2456
2457                 if (!on_csquare(side, pawn, 25))
2458                 {
2459                     /* Play static rook if rook pawn has been pushed! */
2460                     GameType[side] = STATIC_ROOK;
2461                 }
2462                 else
2463                 {
2464                     unsigned int random = urand() % 100;
2465                     short d = StaticRook[side] - RangingRook[side];
2466
2467                     switch (GameType[side ^ 1])
2468                     {
2469                     case STATIC_ROOK:
2470                         if (random < 35 + d)
2471                             GameType[side] = STATIC_ROOK;
2472                         else if (random < 95)
2473                             GameType[side] = RANGING_ROOK;
2474                         break;
2475
2476                     case RANGING_ROOK:
2477                         if (random < 75 + d)
2478                             GameType[side] = STATIC_ROOK;
2479                         else if (random < 95)
2480                             GameType[side] = RANGING_ROOK;
2481                         break;
2482
2483                     default:
2484                         if (random < 33 + d)
2485                             GameType[side] = STATIC_ROOK;
2486                         else if (random < 66)
2487                             GameType[side] = RANGING_ROOK;
2488                     }
2489                 }
2490             }
2491         }
2492     }
2493 }
2494 #endif
2495
2496
2497
2498
2499 static void
2500 DetermineGameType(short side_to_move)
2501 {
2502     short side;
2503
2504 #ifndef MINISHOGI
2505     /* FIXME: calculations below are wrong for minishogi, all done for 9x9 */
2506     GuessGameType(side_to_move);
2507 #else
2508     GameType[black] = UNKNOWN;
2509     GameType[white] = UNKNOWN;
2510 #endif
2511
2512     array_zero(Mpawn,   sizeof(Mpawn));
2513 #ifndef MINISHOGI
2514     array_zero(Mlance,  sizeof(Mlance));
2515     array_zero(Mknight, sizeof(Mknight));
2516 #endif
2517     array_zero(Msilver, sizeof(Msilver));
2518     array_zero(Mgold,   sizeof(Mgold));
2519     array_zero(Mbishop, sizeof(Mbishop));
2520     array_zero(Mrook,   sizeof(Mrook));
2521     array_zero(Mking,   sizeof(Mking));
2522
2523     if (in_opening_stage)
2524     {
2525         for (side = black; side <= white; side++)
2526             UpdatePatterns(side, GameCnt);
2527     }
2528     else
2529     {
2530         dsp->ShowPatternCount(black, -1);
2531         dsp->ShowPatternCount(white, -1);
2532     }
2533 }
2534
2535
2536
2537 /*
2538  * This is done one time before the search is started. Set up arrays
2539  * Mwpawn, Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue()
2540  * function to determine the positional value of each piece.
2541  */
2542
2543 void
2544 ExaminePosition(short side)
2545 {
2546     short c1, piece, sq, i, bsq, wsq;
2547
2548     /* Build enemy king distance tables. */
2549
2550     for (sq = 0, bsq = BlackKing, wsq = WhiteKing; sq < NO_SQUARES; sq++)
2551     {
2552         Kdist[black][sq] = distance(sq, bsq);
2553         Kdist[white][sq] = distance(sq, wsq);
2554     }
2555
2556     threats(black);
2557     threats(white);
2558
2559     ExamineSquares();
2560
2561     DetermineGameType(side);
2562     DetermineStage(side);
2563
2564     UpdateWeights(side);
2565
2566     array_zero(HasPiece, sizeof(HasPiece));
2567
2568     for (c1 = black; c1 <= white; c1++)
2569     {
2570         for (i = PieceCnt[c1]; i >= 0; i--)
2571         {
2572             ++HasPiece[c1][piece = board[sq = PieceList[c1][i]]];
2573         }
2574     }
2575 }
2576
2577
2578
2579 /* FIXME: calculations below are wrong for minishogi, all done for 9x9 */
2580 void
2581 DetermineStage(short side)
2582 {
2583     short xside = side ^ 1, ds, db1, c1, c2, feature;
2584
2585     /* Determine initial stage */
2586
2587     balance[side] = balance[xside] = 50;
2588
2589     if ((GameType[side] == STATIC_ROOK)
2590         && (GameType[xside] == STATIC_ROOK))
2591     {
2592         if (GameCnt < 40)
2593             stage = 0;
2594         else if (GameCnt < 60)
2595             stage = 15;
2596         else if (GameCnt < 80)
2597             stage = 25;
2598         else
2599             stage = 30;
2600     }
2601     else if ((GameType[side] == RANGING_ROOK)
2602              || (GameType[xside] == RANGING_ROOK))
2603     {
2604         if (GameCnt < 30)
2605             stage = 0;
2606         else if (GameCnt < 50)
2607             stage = 15;
2608         else if (GameCnt < 70)
2609             stage = 25;
2610         else
2611             stage = 30;
2612     }
2613     else
2614     {
2615         if (GameCnt < 35)
2616             stage = 0;
2617         else if (GameCnt < 55)
2618             stage = 15;
2619         else if (GameCnt < 75)
2620             stage = 25;
2621         else
2622             stage = 30;
2623     }
2624
2625 #ifndef MINISHOGI
2626     /* Update stage depending on board features and attack balance value */
2627
2628     if (abs(ds = (mtl[side] - mtl[xside]))
2629         > (db1 = (*value)[stage][lance]))
2630     {
2631         db1 = abs(4 * ds / db1);
2632
2633         if (ds < 0)
2634             balance[side] += db1;
2635         else if (ds > 0)
2636             balance[xside] += db1;
2637
2638         stage += (ds = db1);
2639     }
2640 #endif
2641
2642     for (c1 = black, c2 = white; c1 <= white; c1++, c2--)
2643     {
2644         if ((ds = seed[c1]) > 2)
2645         {
2646             balance[c1] += (db1 = ds * 2);
2647             balance[c2] -= db1;
2648
2649             if (stage < 30)
2650                 stage = 30;
2651
2652             stage += ds;
2653         }
2654
2655         if ((db1 = hung[c1]) > 2)
2656         {
2657             balance[c1] -= (db1 *= 2);
2658             balance[c2] += db1;
2659         }
2660
2661         if ((db1 = loose[c1]) > 4)
2662         {
2663             balance[c1] -= (db1 /= 2);
2664             balance[c2] += db1;
2665             stage += (ds = 1);
2666         }
2667
2668         if ((ds = hole[c1]))
2669         {
2670             balance[c1] -= (db1 = ds);
2671             balance[c2] += db1;
2672             stage += (ds /= 2);
2673         }
2674
2675         if ((db1 = target[c1]) > 3)
2676         {
2677             balance[c1] += (db1 /= 3);
2678             balance[c2] -= db1;
2679             stage += (ds = db1 / 4);
2680         }
2681
2682         stage += (ds = captured[c1] / 2);
2683
2684         if ((db1 = captured[c1]) > 4)
2685         {
2686             balance[c1] += (db1 /= 2);
2687             stage += (ds = 3);
2688         }
2689
2690         if ((db1 = dcaptured[c1]) > 3)
2691         {
2692             balance[c1] += db1;
2693             stage += (ds = 3);
2694         }
2695
2696         if (balance[c1] > 99)
2697             balance[c1] = 99;
2698         else if (balance[c1] < 0)
2699             balance[c1] = 0;
2700     }
2701
2702     if (stage > 99)
2703         stage = 99;
2704     else if (stage < 0)
2705         stage = 0;
2706
2707     if (flag.post)
2708         dsp->ShowStage();
2709
2710     /* Determine stage dependant weights */
2711
2712     ADVNCM[pawn]   = 1; /* advanced pawn bonus increment   */
2713 #ifndef MINISHOGI
2714     ADVNCM[lance]  = 1;
2715     ADVNCM[knight] = 1;
2716 #endif
2717     ADVNCM[silver] = 1; /* advanced silver bonus increment */
2718     ADVNCM[gold]   = 1; /* advanced gold bonus increment   */
2719     ADVNCM[bishop] = 1;
2720     ADVNCM[rook]   = 1;
2721     ADVNCM[king]   = 1; /* advanced king bonus increment   */
2722
2723     MAXCDIST = (stage < 33) ? (33 - stage) / 4 : 0;
2724     MAXADIST = (stage < 30) ? (30 - stage) / 4 : 0;
2725
2726     for (c1 = black; c1 <= white; c1++)
2727     {
2728         for (feature = 0; feature < NO_FEATURES; feature++)
2729         {
2730             fvalue[c1][feature] =
2731                 ((((*fscore)[stage][feature][0] * (99 - balance[c1])) + 50)
2732                  / 100)
2733                 + ((((*fscore)[stage][feature][1] * balance[c1]) + 50)
2734                    / 100);
2735         }
2736     }
2737 }
2738
2739
2740
2741 void
2742 UpdateWeights(short stage)
2743 {
2744   /* FIXME: this was emptied between 1.1p02 ans 1.2p03, do we keep it ? */
2745 }
2746
2747
2748
2749 /*
2750  * Compute stage dependent relative material values assuming
2751  * linearity between the main stages:
2752  *
2753  *   minstage < stage < maxstage =>
2754  *          stage - minstage        value - minvalue
2755  *         -------------------  =  -------------------
2756  *         maxstage - minstage     maxvalue - minvalue
2757  */
2758
2759
2760 static short
2761 linear_piece_value(short piece, short stage, short i, short j)
2762 {
2763     short minvalue, maxvalue, minstage, maxstage;
2764
2765     minstage = ispvalue[0][i];
2766     maxstage = ispvalue[0][j];
2767     minvalue = ispvalue[piece][i];
2768     maxvalue = ispvalue[piece][j];
2769
2770     /* FIXME: set a variable then return it, puh-leeze! */
2771     return ((stage - minstage) * (maxvalue - minvalue)
2772             / (maxstage - minstage)) + minvalue;
2773 }
2774
2775
2776
2777 static short
2778 linear_feature_value(short feature, short stage, short i, short j)
2779 {
2780     short minvalue, maxvalue, minstage, maxstage;
2781
2782     minstage = ispvalue[0][i];
2783     maxstage = ispvalue[0][j];
2784     minvalue = weight[feature][i];
2785     maxvalue = weight[feature][j];
2786
2787     /* FIXME: set a variable then return it, puh-leeze! */
2788     return ((stage - minstage) * (maxvalue - minvalue)
2789             / (maxstage - minstage)) + minvalue;
2790 }
2791
2792
2793 /*
2794  * matweight = percentage_of_max_value * max_value(stage) / 100
2795  * max_value(0) = MAX_VALUE; max_value(100) = MIN_VALUE
2796  *  => max_value(stage) = a * stage + b; b = MAX_VALUE,
2797  *     a = (MIN_VALUE - MAX_VALUE)/100
2798  */
2799
2800 #define MIN_VALUE 300
2801 #define MAX_VALUE 1000
2802
2803 #define max_value(stage) \
2804 ((long)(MIN_VALUE - MAX_VALUE) * stage + (long)100 * MAX_VALUE)
2805 #define matweight(value, stage) \
2806 ((long)max_value(stage) * value / 10000)
2807
2808
2809
2810 void
2811 Initialize_eval(void)
2812 {
2813     short stage, piece, feature, i;
2814
2815     for (stage = 0; stage < NO_STAGES; stage++)
2816     {
2817         for (i = 0; i < MAIN_STAGES; i++)
2818         {
2819             if (stage == ispvalue[0][i])
2820             {
2821                 for (piece = 0; piece < NO_PIECES; piece++)
2822                 {
2823                     (*value)[stage][piece] =
2824                         matweight(ispvalue[piece][i], stage);
2825                 }
2826
2827                 for (feature = 0; feature < NO_FEATURES; feature++)
2828                 {
2829                     (*fscore)[stage][feature][0] =
2830                         (weight[feature][i]
2831                          * weight[feature][MAIN_STAGES] + 50) / 100;
2832
2833                     (*fscore)[stage][feature][1] =
2834                         (weight[feature][i]
2835                          * weight[feature][MAIN_STAGES + 1] + 50) / 100;
2836                 }
2837
2838                 break;
2839             }
2840
2841             if (stage < ispvalue[0][i + 1])
2842             {
2843                 for (piece = 0; piece < NO_PIECES; piece++)
2844                 {
2845                     (*value)[stage][piece] =
2846                         matweight(
2847                             linear_piece_value(piece, stage, i, i + 1),
2848                             stage);
2849                 }
2850
2851                 for (feature = 0; feature < NO_FEATURES; feature++)
2852                 {
2853                     (*fscore)[stage][feature][0] =
2854                         (linear_feature_value(feature, stage, i, i + 1)
2855                          * weight[feature][MAIN_STAGES] + 50) / 100;
2856
2857                     (*fscore)[stage][feature][1] =
2858                         (linear_feature_value(feature, stage, i, i + 1)
2859                          * weight[feature][MAIN_STAGES + 1] + 50) / 100;
2860                 }
2861
2862                 break;
2863             }
2864         }
2865     }
2866 }
2867