X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=gnushogi%2Feval.c;h=97b748e8218b98198d8a61b0ba3e48e6e828012a;hb=9621a4712b7df55d6fe4fff44789c8e4c7476013;hp=15509e2bf194eaf8ba21a494c633fba1b5f595a7;hpb=1aca00e04580e7b3effefa535edb469876ecce74;p=gnushogi.git diff --git a/gnushogi/eval.c b/gnushogi/eval.c index 15509e2..97b748e 100644 --- a/gnushogi/eval.c +++ b/gnushogi/eval.c @@ -4,6 +4,7 @@ * ---------------------------------------------------------------------- * Copyright (c) 1993, 1994, 1995 Matthias Mutz * Copyright (c) 1999 Michael Vanier and the Free Software Foundation + * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation * * GNU SHOGI is based on GNU CHESS * @@ -14,8 +15,8 @@ * * GNU Shogi is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 1, or (at your option) any - * later version. + * Free Software Foundation; either version 3 of the License, + * or (at your option) any later version. * * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or @@ -23,8 +24,8 @@ * for more details. * * You should have received a copy of the GNU General Public License along - * with GNU Shogi; see the file COPYING. If not, write to the Free - * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * with GNU Shogi; see the file COPYING. If not, see + * . * ---------------------------------------------------------------------- * */ @@ -32,9 +33,6 @@ #include "gnushogi.h" #include "pattern.h" -extern void -ShowStage(void); - /* Hash table for preventing multiple scoring of the same position */ int EADD = 0; /* number of writes to the cache table */ @@ -44,6 +42,7 @@ int PUTVAR = false; /* shall the current scoring be cached? */ /* Pieces and colors of initial board setup */ +#ifndef MINISHOGI const small_short Stboard[NO_SQUARES] = { lance, knight, silver, gold, king, gold, silver, knight, lance, @@ -79,7 +78,26 @@ const small_short Stcolor[NO_SQUARES] = white, white, white, white, white, white, white, white, white }; +#else +const small_short Stboard[NO_SQUARES] = +{ + king, gold, silver, bishop, rook, + pawn, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, pawn, + rook, bishop, silver, gold, king, +}; + +const small_short Stcolor[NO_SQUARES] = +{ + black, black, black, black, black, + black, neutral, neutral, neutral, neutral, + neutral, neutral, neutral, neutral, neutral, + neutral, neutral, neutral, neutral, white, + white, white, white, white, white +}; +#endif /* Actual pieces and colors */ @@ -95,15 +113,19 @@ static small_short ispvalue[NO_PIECES][MAIN_STAGES] = { 0, 35, 70, 99 }, /* main stage borders */ /* ------------------------------------------ */ { 7, 7, 8, 10 }, /* Pawn */ +#ifndef MINISHOGI { 20, 35, 45, 60 }, /* Lance */ { 20, 35, 45, 60 }, /* Knight */ +#endif { 35, 40, 60, 80 }, /* Silver */ { 35, 50, 65, 80 }, /* Gold */ { 90, 90, 90, 90 }, /* Bishop */ { 95, 95, 95, 95 }, /* Rook */ { 15, 25, 40, 65 }, /* promoted Pawn */ +#ifndef MINISHOGI { 25, 45, 55, 65 }, /* promoted Lance */ { 25, 45, 55, 65 }, /* promoted Knight */ +#endif { 35, 55, 75, 75 }, /* promoted Silver */ { 99, 99, 99, 99 }, /* promoted Bishop */ { 97, 97, 99, 99 }, /* promoted Rook */ @@ -192,8 +214,13 @@ static const short OwnKingDistanceBonus[10] = { 0, 5, 2, 1, 0, -1, -2, -3, -4, -5 }; /* distance to promotion zone */ +#ifndef MINISHOGI static const int PromotionZoneDistanceBonus[NO_ROWS] = { 0, 0, 0, 0, 2, 6, 6, 8, 8 }; +#else +static const int PromotionZoneDistanceBonus[NO_ROWS] = +{ 0, 0, 2, 6, 8 }; /* FIXME ? */ +#endif #define MAX_BMBLTY 20 #define MAX_RMBLTY 20 @@ -207,12 +234,22 @@ static const short BMBLTY[MAX_BMBLTY] = static const short RMBLTY[MAX_RMBLTY] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 16, 16, 16, 16 }; +#ifndef MINISHOGI /* Lance mobility bonus indexed by # reachable squares */ static const short LMBLTY[MAX_LMBLTY] = { 0, 0, 0, 0, 4, 6, 8, 10 }; +#endif static const short MBLTY[NO_PIECES] = -{ 0, 2, 1, 10, 5, 5, 1, 1, 5, 5, 5, 5, 1, 1, 4 }; +{ 0, 2, +#ifndef MINISHOGI + 1, 10, +#endif + 5, 5, 1, 1, 5, +#ifndef MINISHOGI + 5, 5, +#endif + 5, 1, 1, 4 }; static const short KTHRT[36] = { 0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80, @@ -255,17 +292,30 @@ static small_short Mpawn [2][NO_SQUARES]; static small_short Msilver[2][NO_SQUARES]; static small_short Mgold [2][NO_SQUARES]; static small_short Mking [2][NO_SQUARES]; +#ifndef MINISHOGI static small_short Mlance [2][NO_SQUARES]; static small_short Mknight[2][NO_SQUARES]; +#endif static small_short Mbishop[2][NO_SQUARES]; static small_short Mrook [2][NO_SQUARES]; -static Mpiece_array Mpawn, Mlance, Mknight, Msilver, Mgold, - Mbishop, Mrook, Mking; +static Mpiece_array Mpawn, +#ifndef MINISHOGI + Mlance, Mknight, +#endif + Msilver, Mgold, Mbishop, Mrook, Mking; Mpiece_array *Mpiece[NO_PIECES] = -{ NULL, &Mpawn, &Mlance, &Mknight, &Msilver, &Mgold, &Mbishop, &Mrook, - &Mgold, &Mgold, &Mgold, &Mgold, &Mbishop, &Mrook, &Mking }; +{ NULL, &Mpawn, +#ifndef MINISHOGI + &Mlance, &Mknight, +#endif + &Msilver, &Mgold, &Mbishop, &Mrook, + &Mgold, +#ifndef MINISHOGI + &Mgold, &Mgold, +#endif + &Mgold, &Mbishop, &Mrook, &Mking }; static short c1, c2; @@ -274,7 +324,7 @@ static small_short *fv1; static long *atk1, *atk2; static long a1, a2; -#define csquare(side, sq) ((side == black) ? sq : (NO_SQUARES_1 - sq)) +#define csquare(side, sq) ((side == black) ? sq : (NO_SQUARES - 1 - sq)) #define crow(side, sq) row(csquare(side, sq)) #define ccolumn(side, sq) column(csquare(side, sq)) @@ -289,12 +339,13 @@ on_csquare(short side, short piece, short square) } +#ifndef MINISHOGI inline static short on_column(short side, short piece, short c) { short sq; - for (sq = c; sq < NO_SQUARES; sq += 9) + for (sq = c; sq < NO_SQUARES; sq += NO_COLS) { if (on_csquare(side, piece, sq)) return true; @@ -335,13 +386,12 @@ on_right_side(short side, short piece) return false; } +#endif short pscore[2]; /* piece score for each side */ - - /* * Fill array attack[side][] with info about attacks to a square. Bits * 16-31 are set if the piece (king .. pawn) attacks the square. Bits 0-15 @@ -478,11 +528,13 @@ CheckTargetPiece(short sq, short side) add_target(sq, side, 11); break; +#ifndef MINISHOGI case knight: /* vertically ahead if advanced */ /* FIXME: gotta love them magic numbers... */ if ((sq != 1) && (sq != 7) && (sq != 73) && (sq != 79)) add_target(sq, side, 11); break; +#endif } } @@ -774,7 +826,10 @@ BRLscan(short sq, short *mob) #endif short s, mobx; - short u, xu, pin, ptyp, csq = column(sq); + short u, xu, pin, ptyp; +#ifndef MINISHOGI + short csq = column(sq); +#endif short piece, upiece, xupiece, rvalue, ds; small_short *Kd = Kdist[c2]; @@ -847,6 +902,7 @@ BRLscan(short sq, short *mob) /* it's the first piece in the current direction */ if (color[u] == c1) { +#ifndef MINISHOGI /* own intercepting piece in x-ray attack */ if (upiece == lance) { @@ -861,6 +917,7 @@ BRLscan(short sq, short *mob) } } else +#endif { /* bishop or rook x-ray */ if ((upiece == bishop) && (board[u] == pawn) @@ -868,17 +925,20 @@ BRLscan(short sq, short *mob) { s += (ds = -2*fv1[HCLSD]); } +#ifndef MINISHOGI else if ((upiece == rook) && (board[u] == lance) && (GameType[c1] == STATIC_ROOK) && (column(u) == csq)) { s += (ds = fv1[XRAY]); } +#endif } } else { /* enemy's intercepting piece in pin attack */ +#ifndef MINISHOGI if (upiece == lance) { /* lance pin attack */ @@ -892,6 +952,7 @@ BRLscan(short sq, short *mob) } } else +#endif { /* bishop or rook pin attack */ if (board[u] == pawn) @@ -958,11 +1019,13 @@ BRLscan(short sq, short *mob) } else { +#ifndef MINISHOGI if (upiece == lance) { s += (ds = fv1[XRAY] / 2); } else +#endif { s += (ds = fv1[XRAY]); } @@ -1005,7 +1068,7 @@ BRLscan(short sq, short *mob) { \ if (color[u] != c2) \ { \ - if ((atk1[u] == 0) || ((atk2[u] & CNT_MASK) > 1)) \ + if ((atk1[u] == 0) || ((atk2[u] & CNT_MASK) != 0)) \ { \ ++cnt; \ } \ @@ -1200,13 +1263,12 @@ trapped(short sq) static int -AttackedPieceValue(short sq, short side) +AttackedPieceValue(short sq) { - short s, ds; + short s; s = 0; - ds = -fv1[HUNGP] * 2; hung[c1]++; shung[sq]++; @@ -1275,12 +1337,14 @@ PawnValue(short sq, short side) { short s = 0; short ds; +#ifndef MINISHOGI short ccol = ccolumn(c1, sq); +#endif PromotionZoneDistanceValue(sq, 3); /* pawn mobility */ - if (color[(c1 == black) ? (sq + 9) : (sq - 9)] == neutral) + if (color[(c1 == black) ? (sq + NO_COLS) : (sq - NO_COLS)] == neutral) { s += (ds = MBLTY[pawn]); } @@ -1292,9 +1356,16 @@ PawnValue(short sq, short side) if (in_opening_stage) { +#ifndef MINISHOGI +/* FIXME: [HGM] The 3rd-rank Pawn section is meaningless in mini-Shogi, + * (which does not have opposing Pawns), and can do out-of-bound access, + * as the promotion zone is only 1 rank, so Pawns can be closer than 3 ranks + * to the board edge. + */ if (crow(c1, sq) == 2) /* pawn on 3d rank */ { - if (board[(c1 == black) ? (sq + 27) : (sq - 27)] == pawn) + if (board[(c1 == black) ? + (sq + 3*NO_COLS) : (sq - 3*NO_COLS)] == pawn) { /* opposing pawn has been moved (even column == (sq & 1)) */ @@ -1320,6 +1391,9 @@ PawnValue(short sq, short side) } } +/* FIXME: calculations below are wrong for minishogi, all done for 9x9 + * board - and anyway we don't know the stage really :) + */ if ((GameType[c1] == STATIC_ROOK) && (sq == csquare(c1, 43))) { if ((atk2[csquare(c1, 52)] & CNT_MASK) < 2) @@ -1341,19 +1415,20 @@ PawnValue(short sq, short side) s += (ds = -2 * fv1[ATTACKED]); } } +#endif } return s; } - +#ifndef MINISHOGI /* * Calculate the positional value for a lance on 'sq'. */ static inline int -LanceValue(short sq, short side) +LanceValue(short sq) { short s = 0, ds, ad; @@ -1383,7 +1458,7 @@ LanceValue(short sq, short side) */ static inline int -KnightValue(short sq, short side) +KnightValue(short sq) { short s = 0, ad; short ds, checked_trapped = false; @@ -1411,6 +1486,7 @@ KnightValue(short sq, short side) return s; } +#endif @@ -1419,7 +1495,7 @@ KnightValue(short sq, short side) */ static inline int -SilverValue(short sq, short side) +SilverValue(short sq) { short s= 0, ds, ad; @@ -1433,6 +1509,10 @@ SilverValue(short sq, short side) if (in_opening_stage) { +#ifndef MINISHOGI +/* FIXME: calculations below are wrong for minishogi, all done for 9x9 + * board - and anyway we don't know the stage really :) + */ if (GameType[c1] == STATIC_ROOK) { if (csquare(c1, sq) == 12) @@ -1446,6 +1526,7 @@ SilverValue(short sq, short side) } } } +#endif } else { @@ -1462,7 +1543,7 @@ SilverValue(short sq, short side) */ static inline int -GoldValue(short sq, short side) +GoldValue(short sq) { short s = 0, ds, ad; @@ -1476,6 +1557,10 @@ GoldValue(short sq, short side) if (in_opening_stage) { +#ifndef MINISHOGI +/* FIXME: calculations below are wrong for minishogi, all done for 9x9 + * board - and anyway we don't know the stage really :) + */ if ((GameType[c1] == STATIC_ROOK) && (GameType[c2] != STATIC_ROOK)) { if (Mvboard[csquare(c1, 3)]) @@ -1483,6 +1568,7 @@ GoldValue(short sq, short side) s += (ds = -2 * fv1[OPENWRONG]); } } +#endif } else { @@ -1499,12 +1585,16 @@ GoldValue(short sq, short side) */ static inline int -BishopValue(short sq, short side) +BishopValue(short sq) { short s = 0, ds, ad; if (in_opening_stage) { +#ifndef MINISHOGI +/* FIXME: calculations below are wrong for minishogi, all done for 9x9 + * board - and anyway we don't know the stage really :) + */ if (GameType[c1] == RANGING_ROOK) { /* Bishops diagonal should not be open */ @@ -1526,6 +1616,7 @@ BishopValue(short sq, short side) s += (ds = -fv1[OPENWRONG]); } } +#endif } else { @@ -1550,6 +1641,10 @@ RookValue(short sq, short side) if (in_opening_stage) { +#ifndef MINISHOGI +/* FIXME: calculations below are wrong for minishogi, all done for 9x9 + * board - and anyway we don't know the stage really :) + */ short WRONG = fv1[OPENWRONG], OPOK = WRONG / 3; if (GameType[c1] == STATIC_ROOK) @@ -1608,6 +1703,7 @@ RookValue(short sq, short side) } } } +#endif } else { @@ -1624,7 +1720,7 @@ RookValue(short sq, short side) */ static inline int -PPawnValue(short sq, short side) +PPawnValue(short sq) { short s = 0, ds, ad; @@ -1635,12 +1731,13 @@ PPawnValue(short sq, short side) +#ifndef MINISHOGI /* * Calculate the positional value for a promoted lance on 'sq'. */ static inline int -PLanceValue(short sq, short side) +PLanceValue(short sq) { short s = 0, ds, ad; @@ -1656,7 +1753,7 @@ PLanceValue(short sq, short side) */ static inline int -PKnightValue(short sq, short side) +PKnightValue(short sq) { short s = 0, ds, ad; @@ -1664,6 +1761,7 @@ PKnightValue(short sq, short side) return s; } +#endif @@ -1672,7 +1770,7 @@ PKnightValue(short sq, short side) */ static inline int -PSilverValue(short sq, short side) +PSilverValue(short sq) { short s = 0, ds, ad; @@ -1688,7 +1786,7 @@ PSilverValue(short sq, short side) */ static inline int -PBishopValue(short sq, short side) +PBishopValue(short sq) { short s = 0, ds, ad; @@ -1704,7 +1802,7 @@ PBishopValue(short sq, short side) */ static inline int -PRookValue(short sq, short side) +PRookValue(short sq) { short s = 0, ds, ad; @@ -1722,13 +1820,17 @@ PRookValue(short sq, short side) */ static inline int -KingValue(short sq, short side) +KingValue(short sq) { short s = 0, ds; if (fv1[KSFTY] != 0) s += KingScan(sq); +#ifndef MINISHOGI +/* FIXME: calculations below are wrong for minishogi, all done for 9x9 + * board - and anyway we don't know the stage really :) + */ if (in_opening_stage) { if ((GameType[c1] != UNKNOWN) && (ccolumn(c1, sq) == 4)) @@ -1744,6 +1846,7 @@ KingValue(short sq, short side) s += (ds = -fv1[OPENWRONG] / 2); } } +#endif /* CHECKME: is this correct? */ if ((ds = fv1[HOPN])) @@ -1784,8 +1887,10 @@ PieceValue(short sq, short side) s += (ds = BMBLTY[mob] * fv1[MOBILITY] / 100); else if ((piece == rook) || (piece == prook)) s += (ds = RMBLTY[mob] * fv1[MOBILITY] / 100); +#ifndef MINISHOGI else s += (ds = LMBLTY[mob] * fv1[MOBILITY] / 100); +#endif } else { @@ -1801,7 +1906,7 @@ PieceValue(short sq, short side) if (a1 == 0) { /* undefended piece */ - s += AttackedPieceValue(sq, side); + s += AttackedPieceValue(sq); } else { @@ -1812,7 +1917,7 @@ PieceValue(short sq, short side) if (attack_value < piece_value) { /* attacked by a weaker piece */ - s += AttackedPieceValue(sq, side) / 2; + s += AttackedPieceValue(sq) / 2; } else if (abs(attack_value - piece_value) < 10) { @@ -1877,24 +1982,26 @@ PieceValue(short sq, short side) s += PawnValue(sq, side); break; +#ifndef MINISHOGI case lance: - s += LanceValue(sq, side); + s += LanceValue(sq); break; case knight: - s += KnightValue(sq, side); + s += KnightValue(sq); break; +#endif case silver: - s += SilverValue(sq, side); + s += SilverValue(sq); break; case gold: - s += GoldValue(sq, side); + s += GoldValue(sq); break; case bishop: - s += BishopValue(sq, side); + s += BishopValue(sq); break; case rook: @@ -1902,31 +2009,33 @@ PieceValue(short sq, short side) break; case king: - s += KingValue(sq, side); + s += KingValue(sq); break; case ppawn: - s += PPawnValue(sq, side); + s += PPawnValue(sq); break; +#ifndef MINISHOGI case plance: - s += PLanceValue(sq, side); + s += PLanceValue(sq); break; case pknight: - s += PKnightValue(sq, side); + s += PKnightValue(sq); break; +#endif case psilver: - s += PSilverValue(sq, side); + s += PSilverValue(sq); break; case pbishop: - s += PBishopValue(sq, side); + s += PBishopValue(sq); break; case prook: - s += PRookValue(sq, side); + s += PRookValue(sq); break; } @@ -2031,7 +2140,7 @@ UpdatePatterns(short side, short GameCnt) } if (flag.post) - ShowPatternCount(side, n); + dsp->ShowPatternCount(side, n); if (os != END_OF_SEQUENCES) update_advance_bonus(side, os); @@ -2063,7 +2172,7 @@ ScoreCaptures(void) if ((m = seed[c1])) { - for (piece = lance, n = 0; piece <= rook; piece++) + for (piece = pawn+1, n = 0; piece <= rook; piece++) { if (Captured[c1][piece]) n++; @@ -2086,9 +2195,11 @@ ScoreCaptures(void) ds = RMBLTY[MAX_RMBLTY - 1]; break; +#ifndef MINISHOGI case lance: ds = LMBLTY[MAX_LMBLTY - 1]; break; +#endif default: ds = MBLTY[piece]; @@ -2167,6 +2278,21 @@ ScorePosition(short side) ScoreCaptures(); } +#ifndef MINISHOGI +# define BLACKHOME_START 0 +# define BLACKHOME_END 26 +# define MIDDLEROW_START 36 +# define MIDDLEROW_END 44 +# define WHITEHOME_START 54 +# define WHITEHOME_END 80 +#else +# define BLACKHOME_START 0 +# define BLACKHOME_END 4 +# define MIDDLEROW_START 10 +# define MIDDLEROW_END 14 +# define WHITEHOME_START 19 +# define WHITEHOME_END 24 +#endif for (c1 = black, c2 = white; c1 <= white; c1++, c2--) { short n; @@ -2174,7 +2300,7 @@ ScorePosition(short side) fv1 = fvalue[c1]; /* Score fifth rank */ - for (sq = 36, n = 0; sq <= 44; sq++) + for (sq = MIDDLEROW_START, n = 0; sq <= MIDDLEROW_END; sq++) { if ((color[sq] == c1) || (attack[c1][sq] != 0)) n++; @@ -2186,8 +2312,8 @@ ScorePosition(short side) } /* Score holes */ - for (sq = ((c1 == black) ? 0 : 54), n = 0; - sq <= ((c1 == black) ? 26 : 80); + for (sq = ((c1 == black) ? BLACKHOME_START : WHITEHOME_START), n = 0; + sq <= ((c1 == black) ? BLACKHOME_END : WHITEHOME_END); sq++) { if (board[sq] == no_piece && attack[c1][sq] == 0) @@ -2236,6 +2362,7 @@ ScorePosition(short side) * Try to determine the game type of "side". */ +#ifndef MINISHOGI inline static void GuessGameType(short side_to_move) { @@ -2369,6 +2496,7 @@ GuessGameType(short side_to_move) } } } +#endif @@ -2378,11 +2506,19 @@ DetermineGameType(short side_to_move) { short side; +#ifndef MINISHOGI + /* FIXME: calculations below are wrong for minishogi, all done for 9x9 */ GuessGameType(side_to_move); +#else + GameType[black] = UNKNOWN; + GameType[white] = UNKNOWN; +#endif array_zero(Mpawn, sizeof(Mpawn)); +#ifndef MINISHOGI array_zero(Mlance, sizeof(Mlance)); array_zero(Mknight, sizeof(Mknight)); +#endif array_zero(Msilver, sizeof(Msilver)); array_zero(Mgold, sizeof(Mgold)); array_zero(Mbishop, sizeof(Mbishop)); @@ -2396,8 +2532,8 @@ DetermineGameType(short side_to_move) } else { - ShowPatternCount(black, -1); - ShowPatternCount(white, -1); + dsp->ShowPatternCount(black, -1); + dsp->ShowPatternCount(white, -1); } } @@ -2445,6 +2581,7 @@ ExaminePosition(short side) +/* FIXME: calculations below are wrong for minishogi, all done for 9x9 */ void DetermineStage(short side) { @@ -2490,6 +2627,7 @@ DetermineStage(short side) stage = 30; } +#ifndef MINISHOGI /* Update stage depending on board features and attack balance value */ if (abs(ds = (mtl[side] - mtl[xside])) @@ -2504,6 +2642,7 @@ DetermineStage(short side) stage += (ds = db1); } +#endif for (c1 = black, c2 = white; c1 <= white; c1++, c2--) { @@ -2571,13 +2710,15 @@ DetermineStage(short side) stage = 0; if (flag.post) - ShowStage(); + dsp->ShowStage(); /* Determine stage dependant weights */ ADVNCM[pawn] = 1; /* advanced pawn bonus increment */ +#ifndef MINISHOGI ADVNCM[lance] = 1; ADVNCM[knight] = 1; +#endif ADVNCM[silver] = 1; /* advanced silver bonus increment */ ADVNCM[gold] = 1; /* advanced gold bonus increment */ ADVNCM[bishop] = 1; @@ -2605,6 +2746,7 @@ DetermineStage(short side) void UpdateWeights(short stage) { + /* FIXME: this was emptied between 1.1p02 ans 1.2p03, do we keep it ? */ }