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
9 * GNU SHOGI is based on GNU CHESS
11 * Copyright (c) 1988, 1989, 1990 John Stanback
12 * Copyright (c) 1992 Free Software Foundation
14 * This file is part of GNU SHOGI.
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.
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
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 * ----------------------------------------------------------------------
39 /* Hash table for preventing multiple scoring of the same position */
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? */
46 /* Pieces and colors of initial board setup */
49 const small_short Stboard[NO_SQUARES] =
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
63 const small_short Stcolor[NO_SQUARES] =
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
85 const small_short Stboard[NO_SQUARES] =
87 king, gold, silver, bishop, rook,
91 rook, bishop, silver, gold, king,
95 const small_short Stcolor[NO_SQUARES] =
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
105 /* Actual pieces and colors */
107 small_short board[NO_SQUARES], color[NO_SQUARES];
110 /* relative piece values at the beginning of main stages */
112 #define MAIN_STAGES 4
114 static small_short ispvalue[NO_PIECES][MAIN_STAGES] =
116 { 0, 35, 70, 99 }, /* main stage borders */
117 /* ------------------------------------------ */
118 { 7, 7, 8, 10 }, /* Pawn */
120 { 20, 35, 45, 60 }, /* Lance */
121 { 20, 35, 45, 60 }, /* Knight */
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 */
129 { 25, 45, 55, 65 }, /* promoted Lance */
130 { 25, 45, 55, 65 }, /* promoted Knight */
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 */
138 /* Features and Weights */
165 #define KNGPROTECT 25
173 static small_short weight[NO_FEATURES + 1][MAIN_STAGES + 2] =
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 */
209 short ADVNCM[NO_PIECES];
211 /* distance to enemy king */
212 static const short EnemyKingDistanceBonus[10] =
213 { 0, 6, 4, -1, -3, -4, -6, -8, -10, -12 };
215 /* distance to own king */
216 static const short OwnKingDistanceBonus[10] =
217 { 0, 5, 2, 1, 0, -1, -2, -3, -4, -5 };
219 /* distance to promotion zone */
221 static const int PromotionZoneDistanceBonus[NO_ROWS] =
222 { 0, 0, 0, 0, 2, 6, 6, 8, 8 };
224 static const int PromotionZoneDistanceBonus[NO_ROWS] =
225 { 0, 0, 2, 6, 8 }; /* FIXME ? */
228 #define MAX_BMBLTY 20
229 #define MAX_RMBLTY 20
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 };
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 };
241 /* Lance mobility bonus indexed by # reachable squares */
242 static const short LMBLTY[MAX_LMBLTY] =
243 { 0, 0, 0, 0, 4, 6, 8, 10 };
246 static const short MBLTY[NO_PIECES] =
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 };
262 static small_short fvalue[2][NO_FEATURES];
264 long attack[2][NO_SQUARES]; /* threats to squares */
265 small_short sseed[NO_SQUARES]; /* square occupied by a seed piece? */
267 struct signature threats_signature[2] = /* statistics valid for position.. */
268 { { -1, -1 }, { -1, -1 } }; /* attack and sseed available */
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? */
276 struct signature squares_signature = /* statistics valid for position ... */
277 { 0, 0 }; /* starget, sloose, shole, shung available */
279 short target[2], seed[2], loose[2], hole[2];
281 short captured[2]; /* number of captured pieces */
282 short dcaptured[2]; /* different types of captured pieces */
284 small_short Kdist[2][NO_SQUARES]; /* distance to king */
286 short MAXADIST, MAXCDIST; /* maximum half move distance to pattern */
288 char GameType[2] = { UNKNOWN, UNKNOWN }; /* chosen game type of each side */
291 static short attack_opening_sequence[2]; /* current castle patterns */
292 static short castle_opening_sequence[2]; /* current attack formations */
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];
299 static small_short Mlance [2][NO_SQUARES];
300 static small_short Mknight[2][NO_SQUARES];
302 static small_short Mbishop[2][NO_SQUARES];
303 static small_short Mrook [2][NO_SQUARES];
305 static Mpiece_array Mpawn,
309 Msilver, Mgold, Mbishop, Mrook, Mking;
311 Mpiece_array *Mpiece[NO_PIECES] =
316 &Msilver, &Mgold, &Mbishop, &Mrook,
321 &Mgold, &Mbishop, &Mrook, &Mking };
325 static small_short *PC1, *PC2;
326 static small_short *fv1;
327 static long *atk1, *atk2;
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))
336 on_csquare(short side, short piece, short square)
339 /* FIXME: un-obfuscate this! */
340 return ((board[sq = csquare(side, square)] == piece)
341 && (color[sq] == side));
346 on_column(short side, short piece, short c)
350 for (sq = c; sq < NO_SQUARES; sq += NO_COLS)
352 if (on_csquare(side, piece, sq))
360 #define empty_csquare(side, square) \
361 (board[csquare(side, square)] == no_piece)
364 on_left_side(short side, short piece)
368 for (c = 0; c < 4; c++)
370 if (on_column(side, piece, c))
379 on_right_side(short side, short piece)
383 for (c = 5; c < NO_COLS; c++)
385 if (on_column(side, piece, c))
393 short pscore[2]; /* piece score for each side */
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.
414 unsigned char *ppos, *pdir;
416 short i, kd, piece, xside;
419 if (MatchSignature(threats_signature[side]))
421 /* data valid for current positional signature */
428 array_zero(a, NO_SQUARES * sizeof(a[0]));
430 PL = PieceList[side];
432 for (i = PieceCnt[side]; i >= 0; i--)
438 ptyp = ptype[side][piece];
441 u = first_direction(ptyp, &d, sq);
443 ppos = (*nextpos[ptyp])[sq];
444 pdir = (*nextdir[ptyp])[sq];
450 a[u] = ((a[u] + 1) | c);
452 if ((kd = Kdist[xside][u]) < 2)
459 u = ((color[u] == neutral)
460 ? next_position(ptyp, &d, sq, u)
461 : next_direction(ptyp, &d, sq));
463 u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
469 /* data valid for current positional signature */
470 CopySignature(threats_signature[side]);
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
483 add_target(short sq, short side, short id)
485 short isq, tsq, xside;
487 tsq = (side == black) ? nunmap[isq + id] : nunmap[isq - id];
491 target[xside = side^1]++;
493 if (attack[side][tsq])
494 starget[xside][tsq]++; /* protected target square */
496 starget[xside][tsq] += 2; /* unprotected target square */
503 * Target squares can be vertically ahead, diagonally ahead
504 * or diagonally behind.
508 CheckTargetPiece(short sq, short side)
512 case pawn: /* vertically ahead if unprotected */
513 if (!attack[side][sq])
514 add_target(sq, side, 11);
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);
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);
530 case bishop: /* vertically ahead */
531 add_target(sq, side, 11);
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);
547 ScoreKingOpeningFeatures(void)
549 short s = 0, sq = OwnKing, ds;
551 if (GameType[c1] == STATIC_ROOK)
553 /* Penalty for king on right side or fifth file */
555 c = 4 - ccolumn(c1, sq);
557 if ((c < 0) || ((c == 0) && (sq != kingP[c1])))
558 s += (ds = -c - c - fv1[OPENWRONG]);
560 else if (GameType[c1] == RANGING_ROOK)
562 /* Penalty for king on left side or fifth file */
564 c = 4 - ccolumn(c1, sq);
566 if ((c > 0) || ((c == 0) && (sq != kingP[c1])))
568 s += (ds = -c - c - fv1[OPENWRONG]);
571 /* Penalty for king moved before rook switch */
574 if (on_csquare(c1, rook, 16))
576 s += (ds = -4 * fv1[OPENWRONG]);
581 /* Penalty for sitting king after rook switch */
582 if (!on_csquare(c1, rook, 16))
584 s += (ds = -2 * fv1[OPENWRONG]);
588 /* Penalty for defending general moved
589 * before king switch to right side */
590 if (ccolumn(c1, sq) < 6)
592 if (Mvboard[csquare(c1, 5)] || Mvboard[csquare(c1, 6)])
594 s += (ds = -2 * fv1[OPENWRONG]);
608 short sq, side, piece, n;
610 if (MatchSignature(squares_signature))
612 /* data valid for current positional signature */
616 array_zero(shole, sizeof(shole));
617 array_zero(sloose, sizeof(sloose));
618 array_zero(starget, sizeof(starget));
620 hole[0] = hole[1] = loose[0] = loose[1]
621 = target[0] = target[1] = 0;
623 for (sq = 0; sq < NO_SQUARES; sq++)
625 if ((side = color[sq]) == neutral)
629 if (!attack[white][sq])
635 else if (InBlackCamp(sq))
637 if (!attack[black][sq])
646 /* occupied by "side" piece */
647 if (!attack[side][sq])
653 CheckTargetPiece(sq, side);
657 for (side = black; side <= white; side++)
659 captured[side] = dcaptured[side] = 0;
661 for (piece = pawn; piece <= rook; piece++)
663 if ((n = Captured[side][piece]) != 0)
673 /* Data valid for current positional signature */
674 CopySignature(squares_signature);
679 /* ............ POSITIONAL EVALUATION ROUTINES ............ */
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
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.
716 short *InChk, /* output Check flag */
717 short *blockable) /* king threat blockable */
723 s = -Pscore[ply - 1] + mtl[side] - mtl[xside] /* - INCscore */;
724 hung[black] = hung[white] = 0;
726 /* should we use the estimete or score the position */
729 || (ply > Sdepth && s >= (alpha - 30) && s <= (beta + 30))
731 || (use_etable && CheckEETable(side))
737 /* score the position */
738 array_zero(sseed, sizeof(sseed));
740 seed[0] = seed[1] = 0;
743 if (Anyattack(side, sq = PieceList[xside][0]) && (board[sq] == king))
745 *InChk = (board[sq = PieceList[side][0]] == king)
746 ? SqAttacked(sq, xside, blockable)
749 return ((SCORE_LIMIT + 1001) - ply);
753 *InChk = (board[sq = PieceList[side][0]] == king)
754 ? Anyattack(xside, sq)
763 s = ScorePosition(side);
768 /* use the estimate but look at check */
771 *InChk = (board[sq = PieceList[side][0]] == king)
772 ? SqAttacked(sq, xside, blockable)
775 if ((board[sq = PieceList[xside][0]] == king)
776 && SqAttacked(sq, side, blockable))
778 return ((SCORE_LIMIT + 1001) - ply);
782 Pscore[ply] = s - mtl[side] + mtl[xside];
783 ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] : 0);
791 value_of_weakest_attacker(long a2)
795 min_value = SCORE_LIMIT;
797 for (piece = pawn; piece <= king; piece++)
799 if (control[piece] & a2)
801 if (min_value > (v = (*value)[stage][piece]))
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.
823 BRLscan(short sq, short *mob)
828 unsigned char *ppos, *pdir;
832 short u, xu, pin, ptyp, csq = column(sq);
833 short piece, upiece, xupiece, rvalue, ds;
834 small_short *Kd = Kdist[c2];
839 rvalue = (*value)[stage][piece];
840 ptyp = ptype[c1][upiece = unpromoted[piece]];
841 rvalue = (*value)[stage][upiece];
844 u = first_direction(ptyp, &d, sq);
846 ppos = (*nextpos[ptyp])[sq];
847 pdir = (*nextdir[ptyp])[sq];
851 pin = -1; /* start new direction */
857 s += (ds = fv1[CTRLK] * (2 - Kd[u]));
860 if ((ds = starget[c1][u]) != 0)
862 /* threatening a target square */
863 if ((pin < 0) /* direct threat */
864 || (color[pin] == c2)) /* pin threat */
866 s += (ds *= fv1[TARGET]);
870 if ((ds = shole[u]) != 0)
872 /* attacking or protecting a hole */
873 s += (ds = fv1[HOLES]);
875 else if (InPromotionZone(c1, u))
877 /* attacking a square in promotion zone */
878 s += (ds = fv1[HOLES] / 2);
881 if (color[u] == neutral)
885 xu = next_position(ptyp, &d, sq, u);
887 if (xu == next_direction(ptyp, &dd, sq))
888 pin = -1; /* oops new direction */
891 if ((xu = ppos[u]) == pdir[u])
892 pin = -1; /* oops new direction */
899 /* there is a piece in current direction */
902 /* it's the first piece in the current direction */
906 /* own intercepting piece in x-ray attack */
910 if (board[u] == pawn)
912 s += (ds = 2*fv1[PROTECT]);
914 else if (in_opening_stage)
916 s += (ds = -2*fv1[PROTECT]);
922 /* bishop or rook x-ray */
923 if ((upiece == bishop) && (board[u] == pawn)
924 && (GameType[c1] == STATIC_ROOK))
926 s += (ds = -2*fv1[HCLSD]);
929 else if ((upiece == rook) && (board[u] == lance)
930 && (GameType[c1] == STATIC_ROOK)
931 && (column(u) == csq))
933 s += (ds = fv1[XRAY]);
940 /* enemy's intercepting piece in pin attack */
944 /* lance pin attack */
945 if (board[u] == pawn)
947 s += (ds = -2*fv1[PROTECT]);
949 else if (in_opening_stage)
951 s += (ds = 2 * fv1[PROTECT]);
957 /* bishop or rook pin attack */
958 if (board[u] == pawn)
960 s += (ds = -fv1[HCLSD]);
967 xu = next_position(ptyp, &d, sq, u);
969 if (xu != next_direction(ptyp, &dd, sq))
970 pin = u; /* not on the edge and on to find a pin */
972 if ((xu = ppos[u]) != pdir[u])
973 pin = u; /* not on the edge and on to find a pin */
979 /* it's the second piece in the current direction */
983 /* second piece is an own piece */
984 if ((upiece == bishop) && (board[u] == pawn)
985 && (GameType[c1] == STATIC_ROOK))
987 s += (ds = -fv1[HCLSD]);
992 /* second piece is an enemy piece */
993 if (upiece == bishop && board[u] == pawn)
995 s += (ds = -fv1[HCLSD]/2);
998 if (((*value)[stage][xupiece = unpromoted[board[u]]]
1002 if (color[pin] == c2)
1004 if ((xupiece == king) && (in_endgame_stage))
1006 s += (ds = 2 * fv1[PINVAL]);
1010 s += (ds = fv1[PINVAL]);
1013 if ((atk2[pin] == 0)
1014 || (atk1[pin] > control[board[pin]] + 1))
1023 if (upiece == lance)
1025 s += (ds = fv1[XRAY] / 2);
1030 s += (ds = fv1[XRAY]);
1036 pin = -1; /* new direction */
1039 u = next_direction(ptyp, &d, sq);
1054 #define ctlSG (ctlS | ctlG | ctlPp | ctlLp | ctlNp | ctlSp)
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.
1063 * The following must be true:
1064 * board[sq] == king, c1 == color[sq], c2 == otherside[c1]
1067 #define SCORETHREAT \
1069 if (color[u] != c2) \
1071 if ((atk1[u] == 0) || ((atk2[u] & CNT_MASK) != 0)) \
1077 s += (ds = -fv1[CTRLK]); \
1093 unsigned char *ppos, *pdir;
1100 /* Penalties, if a king can be threatened by checks. */
1108 for (p = pawn; p < king; p++)
1110 if (HasPiece[c2][p] || Captured[c2][p])
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.
1119 ptyp = ptype[c1][p];
1122 u = first_direction(ptyp, &d, sq);
1124 ppos = (*nextpos[ptyp])[sq];
1125 pdir = (*nextdir[ptyp])[sq];
1131 /* If a p piece can reach (controls or can drop to)
1132 * square u, then score threat.
1135 if (atk2[u] & control[p])
1137 else if ((Captured[c2][p] && color[u]) == neutral)
1141 u = ((color[u] == neutral)
1142 ? next_position(ptyp, &d, sq, u)
1143 : next_direction(ptyp, &d, sq));
1145 u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
1153 s += (ds = fv1[KSFTY] * KTHRT[cnt] / 16);
1155 /* Penalties, if squares near king are controlled by enemy. */
1159 ptyp = ptype[c1][king];
1162 u = first_direction(ptyp, &d, sq);
1164 pdir = (*nextpos[ptyp])[sq];
1170 if (!ok && color[u] == c1)
1172 short ptype_piece = ptype[black][board[u]];
1174 if ((ptype_piece == ptype_silver) || (ptype_piece == ptype_gold))
1178 if (atk2[u] > atk1[u])
1182 if (atk2[u] & ctlSG)
1184 s += (ds = -fv1[KSFTY] / 2);
1189 u = next_direction(ptyp, &d, sq);
1196 if (!ok || (cnt > 1))
1199 s += (ds = -fv1[KSFTY]/2);
1201 s += (ds = -fv1[KSFTY]);
1208 static short checked_trapped;
1212 * See if the attacked piece has unattacked squares to move to. The following
1213 * must be true: c1 == color[sq] c2 == otherside[c1]
1223 unsigned char *ppos, *pdir;
1229 rvalue = (*value)[stage][piece];
1230 ptyp = ptype[c1][piece];
1233 u = first_direction(ptyp, &d, sq);
1235 ppos = (*nextpos[ptyp])[sq];
1236 pdir = (*nextdir[ptyp])[sq];
1244 if ((atk2[u] == 0) || ((*value)[stage][board[u]] >= rvalue))
1249 u = ((color[u] == neutral)
1250 ? next_position(ptyp, &d, sq, u)
1251 : next_direction(ptyp, &d, sq));
1253 u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
1258 checked_trapped = true;
1266 AttackedPieceValue(short sq, short side)
1272 ds = -fv1[HUNGP] * 2;
1288 OpenFileValue(short sq, short hopn, short hopnx)
1292 if (PC1[fyle = column(sq)] == 0)
1308 /* Distance bonus */
1310 #define PromotionZoneDistanceValue(sq, dd) \
1311 if ((ds = fv1[PROMD])) \
1313 s += (ds = ds * PromotionZoneDistanceBonus[crow(c1, sq)] * dd); \
1316 #define OwnKingDistanceValue(sq, dd, maxd) \
1317 if ((ds = fv1[KINGOD]) && ((ad = Kdist[c1][sq]) <= maxd)) \
1319 s += (ds = ds * OwnKingDistanceBonus[ad] * dd); \
1322 #define EnemyKingDistanceValue(sq, dd, maxd) \
1323 if ((ds = fv1[KINGOD]) && ((ad = Kdist[c2][sq]) <= maxd)) \
1325 s += (ds = ds * EnemyKingDistanceBonus[ad] * dd); \
1333 * Calculate the positional value for a pawn on 'sq'.
1337 PawnValue(short sq, short side)
1341 short ccol = ccolumn(c1, sq);
1343 PromotionZoneDistanceValue(sq, 3);
1346 if (color[(c1 == black) ? (sq + NO_COLS) : (sq - NO_COLS)] == neutral)
1348 s += (ds = MBLTY[pawn]);
1351 if ((a1 & ((ctlR | ctlRp) | ctlL)))
1353 s += (ds = fv1[ATTACKED]);
1356 if (in_opening_stage)
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.
1364 if (crow(c1, sq) == 2) /* pawn on 3d rank */
1366 if (board[(c1 == black) ?
1367 (sq + 3*NO_COLS) : (sq - 3*NO_COLS)] == pawn)
1369 /* opposing pawn has been moved (even column == (sq & 1)) */
1377 m = (side == c1) ? 3 : 5;
1381 m = (side == c1) ? 2 : 3;
1385 m = (side == c1) ? 1 : 2;
1389 s += (ds = -m * MBLTY[pawn]);
1393 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1394 * board - and anyway we don't know the stage really :)
1396 if ((GameType[c1] == STATIC_ROOK) && (sq == csquare(c1, 43)))
1398 if ((atk2[csquare(c1, 52)] & CNT_MASK) < 2)
1400 s += (ds = fv1[ATTACKED]);
1404 if ((GameType[c2] == STATIC_ROOK) && (ccol == 1))
1406 if (sq == csquare(c1, 28))
1408 s += (ds = -fv1[ATTACKED]);
1411 if (((atk1[csquare(c1, 19)] & CNT_MASK) < 2)
1412 && ((atk1[csquare(c1, 28)] & CNT_MASK) < 2))
1414 s += (ds = -2 * fv1[ATTACKED]);
1426 * Calculate the positional value for a lance on 'sq'.
1430 LanceValue(short sq, short side)
1432 short s = 0, ds, ad;
1434 OwnKingDistanceValue(sq, 1, 2);
1436 OpenFileValue(sq, -fv1[HOPN], fv1[HOPN]);
1438 if (!checked_trapped && (crow(c1, sq) > 2))
1440 if (in_opening_stage || trapped(sq))
1442 s += (ds = -3 * fv1[ATTACKED]);
1446 s += (ds = -2 * fv1[ATTACKED]);
1456 * Calculate the positional value for a knight on 'sq'.
1460 KnightValue(short sq, short side)
1463 short ds, checked_trapped = false;
1464 short c = column(sq);
1466 PromotionZoneDistanceValue(sq, 1);
1467 OwnKingDistanceValue(sq, 1, 2);
1469 if (!checked_trapped && (crow(c1, sq) > 2))
1473 s += (ds = -4 * fv1[ATTACKED]);
1477 s += (ds = -3 * fv1[ATTACKED]);
1481 if ((c == 0) || (c == 8))
1483 s += (ds = -fv1[ATTACKED]);
1493 * Calculate the positional value for a silver on 'sq'.
1497 SilverValue(short sq, short side)
1501 OwnKingDistanceValue(sq, 2, 3);
1503 if ((Kdist[c1][sq] < 3)
1504 && (atk1[sq] & (control[gold] | control[silver])))
1506 s += (ds = fv1[COHESION]);
1509 if (in_opening_stage)
1512 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1513 * board - and anyway we don't know the stage really :)
1515 if (GameType[c1] == STATIC_ROOK)
1517 if (csquare(c1, sq) == 12)
1521 if ((board[csq = csquare(c1, 20)] == bishop)
1522 && (color[csq] == c1))
1524 s += (ds = -2 * fv1[OPENWRONG]);
1532 EnemyKingDistanceValue(sq, 2, 3);
1541 * Calculate the positional value for a gold on 'sq'.
1545 GoldValue(short sq, short side)
1547 short s = 0, ds, ad;
1549 OwnKingDistanceValue(sq, 2, 3);
1551 if ((Kdist[c1][sq] < 3)
1552 && (atk1[sq] & (control[gold] | control[silver])))
1554 s += (ds = fv1[COHESION]);
1557 if (in_opening_stage)
1560 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1561 * board - and anyway we don't know the stage really :)
1563 if ((GameType[c1] == STATIC_ROOK) && (GameType[c2] != STATIC_ROOK))
1565 if (Mvboard[csquare(c1, 3)])
1567 s += (ds = -2 * fv1[OPENWRONG]);
1574 EnemyKingDistanceValue(sq, 2, 3);
1583 * Calculate the positional value for a bishop on 'sq'.
1587 BishopValue(short sq, short side)
1589 short s = 0, ds, ad;
1591 if (in_opening_stage)
1594 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1595 * board - and anyway we don't know the stage really :)
1597 if (GameType[c1] == RANGING_ROOK)
1599 /* Bishops diagonal should not be open */
1600 if (!on_csquare(c1, pawn, 30))
1602 s += (ds = -fv1[OPENWRONG]);
1605 else if (GameType[c2] == RANGING_ROOK)
1607 /* Bishops diagonal should be open */
1608 if ((csquare(c1, sq) == 10)
1609 && (!empty_csquare(c1, 20) || !empty_csquare(c1, 30)))
1611 s += (ds = -fv1[OPENWRONG]);
1613 else if ((csquare(c1, sq) == 20) && !empty_csquare(c1, 30))
1615 s += (ds = -fv1[OPENWRONG]);
1622 EnemyKingDistanceValue(sq, 1, 3);
1631 * Calculate the positional value for a rook on 'sq'.
1635 RookValue(short sq, short side)
1637 short s = 0, ds, ad;
1639 OpenFileValue(sq, 2 * fv1[HOPN], 4*fv1[HOPN]);
1641 if (in_opening_stage)
1644 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1645 * board - and anyway we don't know the stage really :)
1647 short WRONG = fv1[OPENWRONG], OPOK = WRONG / 3;
1649 if (GameType[c1] == STATIC_ROOK)
1651 short c = ccolumn(c1, sq);
1653 /* Bonus for rook on 8th file */
1660 * Bonus for rook on right side,
1661 * penalty for rook on left side
1669 s += (ds = c + c + OPOK);
1673 s += (ds = -c - c - WRONG);
1676 else if (GameType[c1] == RANGING_ROOK)
1678 /* Bonus for rook on left side and
1679 * bishops diagonal closed, penalty otherwise. */
1682 c = 4 - ccolumn(c1, sq);
1687 /* Bishops diagonal should not be open. */
1688 if (on_csquare(c1, pawn, 30))
1691 s += (ds = -c - c - WRONG);
1695 s += (ds = -c - c - WRONG);
1697 /* Penalty for king not on initial square. */
1698 if (!on_csquare(side, king, 4))
1709 EnemyKingDistanceValue(sq, 1, 3);
1718 * Calculate the positional value for a promoted pawn on 'sq'.
1722 PPawnValue(short sq, short side)
1724 short s = 0, ds, ad;
1726 EnemyKingDistanceValue(sq, 3, 10);
1735 * Calculate the positional value for a promoted lance on 'sq'.
1739 PLanceValue(short sq, short side)
1741 short s = 0, ds, ad;
1743 EnemyKingDistanceValue(sq, 3, 10);
1751 * Calculate the positional value for a promoted knight on 'sq'.
1755 PKnightValue(short sq, short side)
1757 short s = 0, ds, ad;
1759 EnemyKingDistanceValue(sq, 3, 10);
1768 * Calculate the positional value for a promoted silver on 'sq'.
1772 PSilverValue(short sq, short side)
1774 short s = 0, ds, ad;
1776 EnemyKingDistanceValue(sq, 3, 10);
1784 * Calculate the positional value for a promoted bishop on 'sq'.
1788 PBishopValue(short sq, short side)
1790 short s = 0, ds, ad;
1792 EnemyKingDistanceValue(sq, 3, 4);
1800 * Calculate the positional value for a promoted rook on 'sq'.
1804 PRookValue(short sq, short side)
1806 short s = 0, ds, ad;
1808 EnemyKingDistanceValue(sq, 3, 4);
1810 OpenFileValue(sq, 3 * fv1[HOPN], 2 * fv1[HOPN]);
1818 * Calculate the positional value for a king on 'sq'.
1822 KingValue(short sq, short side)
1826 if (fv1[KSFTY] != 0)
1830 /* FIXME: calculations below are wrong for minishogi, all done for 9x9
1831 * board - and anyway we don't know the stage really :)
1833 if (in_opening_stage)
1835 if ((GameType[c1] != UNKNOWN) && (ccolumn(c1, sq) == 4))
1837 s += (ds = -fv1[OPENWRONG] / 3);
1839 else if ((GameType[c1] == STATIC_ROOK) && on_right_side(c1, sq))
1841 s += (ds = -fv1[OPENWRONG] / 2);
1843 else if ((GameType[c1] == RANGING_ROOK) && on_left_side(c1, sq))
1845 s += (ds = -fv1[OPENWRONG] / 2);
1850 /* CHECKME: is this correct? */
1851 if ((ds = fv1[HOPN]))
1853 s += OpenFileValue(sq, -2 * ds, -4 * ds);
1862 * Calculate the positional value for a piece on 'sq'.
1866 PieceValue(short sq, short side)
1873 if (piece == no_piece)
1876 s = (*Mpiece[piece])[c1][sq];
1878 checked_trapped = false;
1882 /* pin/x-ray attack and mobility for sweeping pieces */
1883 s += (ds = BRLscan(sq, &mob));
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);
1891 s += (ds = LMBLTY[mob] * fv1[MOBILITY] / 100);
1896 /* mobility for non-sweeping pieces */
1904 /* opponent attacks piece */
1907 /* undefended piece */
1908 s += AttackedPieceValue(sq, side);
1912 /* defended piece */
1913 short attack_value = value_of_weakest_attacker(a2);
1914 short piece_value = (*value)[stage][piece];
1916 if (attack_value < piece_value)
1918 /* attacked by a weaker piece */
1919 s += AttackedPieceValue(sq, side) / 2;
1921 else if (abs(attack_value - piece_value) < 10)
1923 /* opponent has the option to exchange equal pieces */
1924 s += (ds = -fv1[ATTACKED]);
1934 /* piece is defended */
1935 s += (ds = (a1 & CNT_MASK) * fv1[PROTECT]);
1940 s += (ds = fv1[SEED]);
1945 s += (ds = -fv1[LOOSE]);
1948 if (starget[c1][sq])
1952 s -= (ds = -fv1[ATTACKED]/2);
1954 else if (piece == pawn)
1956 s += (ds = fv1[ATTACKED]);
1960 if (starget[c2][sq])
1964 s -= (ds = -fv1[ATTACKED] / 3);
1968 s += (ds = fv1[ATTACKED]);
1972 if (Kdist[c1][sq] == 1)
1974 s += (ds = fv1[KSFTY]);
1981 s += PawnValue(sq, side);
1986 s += LanceValue(sq, side);
1990 s += KnightValue(sq, side);
1995 s += SilverValue(sq, side);
1999 s += GoldValue(sq, side);
2003 s += BishopValue(sq, side);
2007 s += RookValue(sq, side);
2011 s += KingValue(sq, side);
2015 s += PPawnValue(sq, side);
2020 s += PLanceValue(sq, side);
2024 s += PKnightValue(sq, side);
2029 s += PSilverValue(sq, side);
2033 s += PBishopValue(sq, side);
2037 s += PRookValue(sq, side);
2047 * Score distance to pattern regarding the game type which side plays.
2051 ScorePatternDistance(short c1)
2054 small_short *fv1 = fvalue[c1];
2057 if ((MAXCDIST > 0) && (fv1[PCASTLE] != 0)
2058 && ((os = castle_opening_sequence[c1]) >= 0))
2060 ds = board_to_pattern_distance(c1, os, MAXCDIST, GameCnt);
2064 s += (ds *= fv1[PCASTLE]);
2068 if ((MAXADIST > 0) && (fv1[PATTACK] != 0)
2069 && ((os = attack_opening_sequence[c1]) >= 0))
2071 ds = board_to_pattern_distance(c1, os, MAXADIST, GameCnt);
2075 s += (ds *= fv1[PATTACK]);
2086 * Determine castle and attack pattern which should be reached next.
2087 * Only patterns are considered, which have not been reached yet.
2091 UpdatePatterns(short side, short GameCnt)
2094 short xside = side ^ 1;
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);
2104 if (flag.post && (os != END_OF_SEQUENCES))
2106 for (j = 0; j < MAX_SEQUENCE; j++)
2108 for (k = OpeningSequence[os].first_pattern[j];
2109 k != END_OF_PATTERNS;
2110 k = Pattern[k].next_pattern)
2112 if (Pattern[k].distance[side] >= 0)
2118 if (os != END_OF_SEQUENCES)
2119 update_advance_bonus(side, os);
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);
2127 if (flag.post && (os != END_OF_SEQUENCES))
2129 for (j = 0; j < MAX_SEQUENCE; j++)
2131 for (k = OpeningSequence[os].first_pattern[j];
2132 k != END_OF_PATTERNS;
2133 k = Pattern[k].next_pattern)
2135 if (Pattern[k].distance[side] >= 0)
2142 ShowPatternCount(side, n);
2144 if (os != END_OF_SEQUENCES)
2145 update_advance_bonus(side, os);
2153 short ds, col, n, m, piece;
2155 if ((n = Captured[c1][pawn]))
2159 for (col = 0; col < NO_COLS; col++)
2168 /* FIXME! another great obfuscated line... */
2169 pscore[c1] += (ds *= ((n > 2) ? 3 : n));
2174 for (piece = pawn+1, n = 0; piece <= rook; piece++)
2176 if (Captured[c1][piece])
2180 pscore[c1] += (ds = m * fv1[DFFDROP]);
2183 for (piece = pawn, n = 0; piece <= rook; piece++)
2185 if (Captured[c1][piece])
2190 ds = BMBLTY[MAX_BMBLTY - 1];
2194 ds = RMBLTY[MAX_RMBLTY - 1];
2199 ds = LMBLTY[MAX_LMBLTY - 1];
2209 if (!Captured[c2][piece])
2210 n += relative_value[piece];
2216 pscore[c1] += (ds = -n * fv1[OPPDROP] / 2);
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.
2230 ScorePosition(short side)
2239 UpdateWeights(side);
2241 hung[black] = hung[white] = pscore[black] = pscore[white] = 0;
2243 array_zero(shung, sizeof(shung));
2246 if (!(use_etable && ProbeEETable(side, &s)))
2249 for (c1 = black; c1 <= white; c1++)
2253 /* atk1 is array of attacks on squares by my side */
2256 /* atk2 is array of attacks on squares by other side */
2259 /* same for PC1 and PC2 */
2263 /* same for fv1 and fv2 */
2266 for (i = PieceCnt[c1]; i >= 0; i--)
2268 sq = PieceList[c1][i];
2270 #if defined SAVE_SVALUE
2271 pscore[c1] += PieceValue(sq, side);
2273 pscore[c1] += (svalue[sq] = PieceValue(sq, side));
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
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
2295 for (c1 = black, c2 = white; c1 <= white; c1++, c2--)
2301 /* Score fifth rank */
2302 for (sq = MIDDLEROW_START, n = 0; sq <= MIDDLEROW_END; sq++)
2304 if ((color[sq] == c1) || (attack[c1][sq] != 0))
2310 pscore[c1] += (ds = n * fv1[CNTRL5TH]);
2314 for (sq = ((c1 == black) ? BLACKHOME_START : WHITEHOME_START), n = 0;
2315 sq <= ((c1 == black) ? BLACKHOME_END : WHITEHOME_END);
2318 if (board[sq] == no_piece && attack[c1][sq] == 0)
2324 pscore[c1] += (ds = -n * fv1[HOLES]);
2329 pscore[c1] += (ds = -fv1[HUNGX]);
2332 /* Score opening features and
2333 * castle/attack pattern distances */
2335 if (in_opening_stage)
2337 pscore[c1] += (ds = ScoreKingOpeningFeatures());
2338 pscore[c1] += (ds = ScorePatternDistance(c1));
2342 score = mtl[side] - mtl[xside]
2343 + pscore[side] - pscore[xside] + 10;
2346 if (use_etable && PUTVAR)
2347 PutInEETable(side, score);
2351 #ifdef CACHE /* CHECKME: this looks bad */
2361 * Try to determine the game type of "side".
2366 GuessGameType(short side_to_move)
2369 short StaticRook[2] = { 0, 0 };
2370 short RangingRook[2] = { 0, 0 };
2372 for (side = black; side <= white; side++)
2374 /* computer should not change its mind */
2376 extern int bookflag;
2378 gt = GameType[side];
2380 if (!bookflag && (side == side_to_move))
2382 if (gt == STATIC_ROOK)
2383 StaticRook[side] += 4;
2384 else if (gt == RANGING_ROOK)
2385 RangingRook[side] += 4;
2388 /* static rook conditions */
2390 if (on_column(side, rook, 7))
2391 StaticRook[side] += 3;
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;
2400 if (empty_csquare(side, 5) || empty_csquare(side, 6))
2401 StaticRook[side] += 2;
2403 if (on_left_side(side, king))
2404 StaticRook[side] += 2;
2406 /* ranging rook conditions */
2408 if (on_left_side(side, rook))
2409 RangingRook[side] += 5;
2410 else if (!on_column(side, rook, 7))
2411 RangingRook[side] += 3;
2413 if (on_csquare(side, pawn, 25))
2414 RangingRook[side] += 1;
2416 if (on_csquare(side, pawn, 30))
2417 RangingRook[side] += 1;
2419 RangingRook[side] -= 2;
2421 if (!on_right_side(side, rook))
2422 RangingRook[side] += 4;
2424 if (on_right_side(side, king))
2425 RangingRook[side] += 4;
2427 if (on_csquare(side, bishop, 20))
2429 if (on_csquare(side, silver, 11)
2430 || on_csquare(side, silver, 12)
2431 || on_csquare(side, silver, 21))
2433 RangingRook[side] += 3;
2437 if ((StaticRook[side] > 5) || (RangingRook[side] > 5))
2439 GameType[side] = (StaticRook[side] > RangingRook[side])
2440 ? STATIC_ROOK : RANGING_ROOK;
2444 GameType[side] = UNKNOWN;
2448 if ((GameType[black] == UNKNOWN) || (GameType[white] == UNKNOWN))
2450 for (side = black; side <= white; side++)
2452 if ((side == computer) && (GameType[side] == UNKNOWN))
2455 * Game type is UNKNOWN.
2456 * Make a decision what type of game to play.
2457 * To make computer games more interesting, make a
2461 if (!on_csquare(side, pawn, 25))
2463 /* Play static rook if rook pawn has been pushed! */
2464 GameType[side] = STATIC_ROOK;
2468 unsigned int random = urand() % 100;
2469 short d = StaticRook[side] - RangingRook[side];
2471 switch (GameType[side ^ 1])
2474 if (random < 35 + d)
2475 GameType[side] = STATIC_ROOK;
2476 else if (random < 95)
2477 GameType[side] = RANGING_ROOK;
2481 if (random < 75 + d)
2482 GameType[side] = STATIC_ROOK;
2483 else if (random < 95)
2484 GameType[side] = RANGING_ROOK;
2488 if (random < 33 + d)
2489 GameType[side] = STATIC_ROOK;
2490 else if (random < 66)
2491 GameType[side] = RANGING_ROOK;
2504 DetermineGameType(short side_to_move)
2509 /* FIXME: calculations below are wrong for minishogi, all done for 9x9 */
2510 GuessGameType(side_to_move);
2512 GameType[black] = UNKNOWN;
2513 GameType[white] = UNKNOWN;
2516 array_zero(Mpawn, sizeof(Mpawn));
2518 array_zero(Mlance, sizeof(Mlance));
2519 array_zero(Mknight, sizeof(Mknight));
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));
2527 if (in_opening_stage)
2529 for (side = black; side <= white; side++)
2530 UpdatePatterns(side, GameCnt);
2534 ShowPatternCount(black, -1);
2535 ShowPatternCount(white, -1);
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.
2548 ExaminePosition(short side)
2550 short c1, piece, sq, i, bsq, wsq;
2552 /* Build enemy king distance tables. */
2554 for (sq = 0, bsq = BlackKing, wsq = WhiteKing; sq < NO_SQUARES; sq++)
2556 Kdist[black][sq] = distance(sq, bsq);
2557 Kdist[white][sq] = distance(sq, wsq);
2565 DetermineGameType(side);
2566 DetermineStage(side);
2568 UpdateWeights(side);
2570 array_zero(HasPiece, sizeof(HasPiece));
2572 for (c1 = black; c1 <= white; c1++)
2574 for (i = PieceCnt[c1]; i >= 0; i--)
2576 ++HasPiece[c1][piece = board[sq = PieceList[c1][i]]];
2583 /* FIXME: calculations below are wrong for minishogi, all done for 9x9 */
2585 DetermineStage(short side)
2587 short xside = side ^ 1, ds, db1, c1, c2, feature;
2589 /* Determine initial stage */
2591 balance[side] = balance[xside] = 50;
2593 if ((GameType[side] == STATIC_ROOK)
2594 && (GameType[xside] == STATIC_ROOK))
2598 else if (GameCnt < 60)
2600 else if (GameCnt < 80)
2605 else if ((GameType[side] == RANGING_ROOK)
2606 || (GameType[xside] == RANGING_ROOK))
2610 else if (GameCnt < 50)
2612 else if (GameCnt < 70)
2621 else if (GameCnt < 55)
2623 else if (GameCnt < 75)
2630 /* Update stage depending on board features and attack balance value */
2632 if (abs(ds = (mtl[side] - mtl[xside]))
2633 > (db1 = (*value)[stage][lance]))
2635 db1 = abs(4 * ds / db1);
2638 balance[side] += db1;
2640 balance[xside] += db1;
2642 stage += (ds = db1);
2646 for (c1 = black, c2 = white; c1 <= white; c1++, c2--)
2648 if ((ds = seed[c1]) > 2)
2650 balance[c1] += (db1 = ds * 2);
2659 if ((db1 = hung[c1]) > 2)
2661 balance[c1] -= (db1 *= 2);
2665 if ((db1 = loose[c1]) > 4)
2667 balance[c1] -= (db1 /= 2);
2672 if ((ds = hole[c1]))
2674 balance[c1] -= (db1 = ds);
2679 if ((db1 = target[c1]) > 3)
2681 balance[c1] += (db1 /= 3);
2683 stage += (ds = db1 / 4);
2686 stage += (ds = captured[c1] / 2);
2688 if ((db1 = captured[c1]) > 4)
2690 balance[c1] += (db1 /= 2);
2694 if ((db1 = dcaptured[c1]) > 3)
2700 if (balance[c1] > 99)
2702 else if (balance[c1] < 0)
2714 /* Determine stage dependant weights */
2716 ADVNCM[pawn] = 1; /* advanced pawn bonus increment */
2721 ADVNCM[silver] = 1; /* advanced silver bonus increment */
2722 ADVNCM[gold] = 1; /* advanced gold bonus increment */
2725 ADVNCM[king] = 1; /* advanced king bonus increment */
2727 MAXCDIST = (stage < 33) ? (33 - stage) / 4 : 0;
2728 MAXADIST = (stage < 30) ? (30 - stage) / 4 : 0;
2730 for (c1 = black; c1 <= white; c1++)
2732 for (feature = 0; feature < NO_FEATURES; feature++)
2734 fvalue[c1][feature] =
2735 ((((*fscore)[stage][feature][0] * (99 - balance[c1])) + 50)
2737 + ((((*fscore)[stage][feature][1] * balance[c1]) + 50)
2746 UpdateWeights(short stage)
2753 * Compute stage dependent relative material values assuming
2754 * linearity between the main stages:
2756 * minstage < stage < maxstage =>
2757 * stage - minstage value - minvalue
2758 * ------------------- = -------------------
2759 * maxstage - minstage maxvalue - minvalue
2764 linear_piece_value(short piece, short stage, short i, short j)
2766 short minvalue, maxvalue, minstage, maxstage;
2768 minstage = ispvalue[0][i];
2769 maxstage = ispvalue[0][j];
2770 minvalue = ispvalue[piece][i];
2771 maxvalue = ispvalue[piece][j];
2773 /* FIXME: set a variable then return it, puh-leeze! */
2774 return ((stage - minstage) * (maxvalue - minvalue)
2775 / (maxstage - minstage)) + minvalue;
2781 linear_feature_value(short feature, short stage, short i, short j)
2783 short minvalue, maxvalue, minstage, maxstage;
2785 minstage = ispvalue[0][i];
2786 maxstage = ispvalue[0][j];
2787 minvalue = weight[feature][i];
2788 maxvalue = weight[feature][j];
2790 /* FIXME: set a variable then return it, puh-leeze! */
2791 return ((stage - minstage) * (maxvalue - minvalue)
2792 / (maxstage - minstage)) + minvalue;
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
2803 #define MIN_VALUE 300
2804 #define MAX_VALUE 1000
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)
2814 Initialize_eval(void)
2816 short stage, piece, feature, i;
2818 for (stage = 0; stage < NO_STAGES; stage++)
2820 for (i = 0; i < MAIN_STAGES; i++)
2822 if (stage == ispvalue[0][i])
2824 for (piece = 0; piece < NO_PIECES; piece++)
2826 (*value)[stage][piece] =
2827 matweight(ispvalue[piece][i], stage);
2830 for (feature = 0; feature < NO_FEATURES; feature++)
2832 (*fscore)[stage][feature][0] =
2834 * weight[feature][MAIN_STAGES] + 50) / 100;
2836 (*fscore)[stage][feature][1] =
2838 * weight[feature][MAIN_STAGES + 1] + 50) / 100;
2844 if (stage < ispvalue[0][i + 1])
2846 for (piece = 0; piece < NO_PIECES; piece++)
2848 (*value)[stage][piece] =
2850 linear_piece_value(piece, stage, i, i + 1),
2854 for (feature = 0; feature < NO_FEATURES; feature++)
2856 (*fscore)[stage][feature][0] =
2857 (linear_feature_value(feature, stage, i, i + 1)
2858 * weight[feature][MAIN_STAGES] + 50) / 100;
2860 (*fscore)[stage][feature][1] =
2861 (linear_feature_value(feature, stage, i, i + 1)
2862 * weight[feature][MAIN_STAGES + 1] + 50) / 100;