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