home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 3.ddi / CHESS.ZIP / EVALU.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  19.7 KB  |  513 lines

  1. // ObjectWindows - (C) Copyright 1992 by Borland International
  2.  
  3. #include <math.h>
  4. #include "wcdefs.h"
  5. #include "externs.h"
  6.  
  7. MAXTYPE RootValue;
  8. BOARDTYPE Board[0x78];
  9.  
  10. #undef max
  11. #undef min
  12. #define max(a, b)  (((a) > (b)) ? (a) : (b))
  13. #define min(a, b)  (((a) < (b)) ? (a) : (b))
  14.  
  15. #define     TOLERANCE           8  /*  Tolerance width  */
  16. #define     EXCHANGEVALUE      32
  17.      /*  Value for exchanging pieces when ahead (not pawns)  */
  18. #define     ISOLATEDPAWN       20
  19.     /*  Isolated pawn.  Double isolated pawn is 3 * 20  */
  20. #define     DOUBLEPAWN          8   /*  Double pawn  */
  21. #define     SIDEPAWN            6   /*  Having a pawn on the side  */
  22. #define     CHAINPAWN           3   /*  Being covered by a pawn  */
  23. #define     COVERPAWN           3   /*  covering a pawn  */
  24. #define     NOTMOVEPAWN         2   /*  Penalty for moving pawn  */
  25. #define     BISHOPBLOCKVALUE   20
  26.     /*  Penalty for bishop blocking d2/e2 pawn  */
  27. #define     ROOKBEHINDPASSPAWN 16   /*  Bonus for Rook behind passed pawn  */
  28.  
  29.  
  30. typedef unsigned char FILETYPE;  /*  file numbers  */
  31. typedef unsigned char RANKTYPE;  /*  rank numbers  */
  32. typedef unsigned char SETOFFILE;
  33. typedef struct
  34.     {
  35.         SETOFFILE one, dob;
  36.     } PAWNBITTYPE[2];
  37.  
  38. /*
  39.  *  Global variables for this module
  40.  */
  41.  
  42. int PieceValue[7] = {0, 0x1000, 0x900, 0x4c0, 0x300, 0x300, 0x100};
  43. const char distan[8] = { 3, 2, 1, 0, 0, 1, 2, 3 };
  44.     /*  The value of a pawn is the sum of Rank and file values.
  45.         The file value is equal to PawnFileFactor * (Rank Number + 2) */
  46. const char pawnrank[8] = {0, 0, 0, 2, 4, 8, 30, 0};
  47. const char passpawnrank[8] = {0, 0, 10, 20, 40, 60, 70, 0};
  48. const char pawnfilefactor[8] = {0, 0, 2, 5, 6, 2, 0, 0};
  49. const char castvalue[2] = {4, 32};  /*  Value of castling  */
  50.  
  51. const SETOFFILE filebittab[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
  52. PAWNBITTYPE pawnbitt[MAXPLY + 2];
  53. PAWNBITTYPE *pawnbit = &pawnbitt[1];
  54. int totalmaterial, pawntotalmaterial, material;
  55.   /*  Material level of the game
  56.         (early middlegame = 43 - 32, endgame = 0)  */
  57. int materiallevel;
  58. const unsigned char squarerankvalue[8] = { 0, 0, 0, 0, 1, 2, 4, 4};
  59. COLORTYPE tempcolor;
  60. int temp, temp2;  /*  temporary junk  */
  61.  
  62.  
  63.  
  64. /*
  65.  *  count the number of set bits in b
  66.  */
  67.  
  68. static int count(SETOFFILE b)
  69. {
  70.     char cnt = 0;
  71.  
  72.     while (b)
  73.     {
  74.         if (b % 2 == 1) cnt++;
  75.         b >>= 1;
  76.     }
  77.     return cnt;
  78. }
  79.  
  80.  
  81. /*
  82.  *  Calculate value of the pawn structure in pawnbit[depth][color]
  83.  */
  84.  
  85. static int pawnstrval(DEPTHTYPE depth, COLORTYPE color)
  86. {
  87.     SETOFFILE iso;  /*  contains FILEs with isolated pawns  */
  88.  
  89.     iso = pawnbit[depth][color].one &
  90.         ~((pawnbit[depth][color].one << 1) | (pawnbit[depth][color].one
  91.             >> 1));
  92.     return (-(count(pawnbit[depth][color].dob) * DOUBLEPAWN +
  93.             count(iso) * ISOLATEDPAWN + count(iso &
  94.                 pawnbit[depth][color].dob) * ISOLATEDPAWN * 2));
  95. }
  96.  
  97.  
  98. /*
  99.  *  calculate the value of the piece on the square
  100.  */
  101.  
  102. inline int PiecePosVal(PIECETYPE piece, COLORTYPE color, SQUARETYPE square)
  103. {
  104.     return (PieceValue[piece] + PVTable[color][piece][square]);
  105. }
  106.  
  107.  
  108. short mating;  /*  mating evaluation function is used  */
  109.  
  110. /*
  111.  *  calculates piece-value table for the static evaluation function
  112.  */
  113.  
  114. void CalcPVTable(void)
  115. {
  116.     typedef SETOFFILE PAWNTABTYPE[8];
  117.  
  118.     PAWNTABTYPE pawntab[2];
  119.     /*  Bit tables for static pawn structure evaluation  */
  120.     SETOFFILE pawnfiletab, bit, oppasstab, behindoppass,
  121.         leftsidetab, rightsidetab, sidetab, leftchaintab,
  122.         rightchaintab, chaintab, leftcovertab, rightcovertab;
  123.  
  124.     /*  Importance of an attack of the square  */
  125.     char attackvalue[2][0x78];
  126.     /*  Value of squares controlled from the square  */
  127.     int pvcontrol[2][5][0x78];
  128.  
  129.     COLORTYPE losingcolor;     /*  the color which is being mated  */
  130.     int posval;                /*  The positional value of piece  */
  131.     int attval;                /*  The attack value of the square  */
  132.     FILETYPE line;             /*  The file of the piece  */
  133.     RANKTYPE rank;             /*  The rank of the piece  */
  134.     char dist, kingdist;       /*  Distance to center, to opponents king */
  135.     CASTTYPE cast;             /*  Possible castlings  */
  136.     short direct;              /*  Indicates direct attack  */
  137.     int cnt;                   /*  Counter for attack values  */
  138.     int strval;                /*  Pawnstructure value  */
  139.     COLORTYPE color, oppcolor; /*  Color and opponents color  */
  140.     PIECETYPE piececount;      /*  Piece counter  */
  141.     SQUARETYPE square;         /*  Square counter  */
  142.     DIRTYPE dir;               /*  Direction counter  */
  143.     EDGESQUARETYPE sq;         /*  Square counter  */
  144.     int temp, temp2;           /*  temporary junk  */
  145.  
  146.     /*  Calculate SAMMAT, PAWNSAMMAT and Material  */
  147.     material = pawntotalmaterial = totalmaterial = mating = 0;
  148.  
  149.     for (square = 0; square < 0x78; square++)
  150.         if (!(square & 0x88))
  151.             if (Board[square].piece != empty)
  152.                 if (Board[square].piece != king)
  153.                 {
  154.                     temp = PieceValue[Board[square].piece];
  155.                     totalmaterial += temp;
  156.                     if (Board[square].piece == pawn)
  157.                         pawntotalmaterial += PieceValue[pawn];
  158.                     if (Board[square].color == white) temp = -temp;
  159.                     material -= temp;
  160.                 }
  161.     materiallevel = max(0, totalmaterial - 0x2000) / 0x100;
  162.     /*  Set mating if weakest player has less than the equivalence
  163.     of two bishops and the advantage is at least a rook for a bishop  */
  164.     if (material < 0)
  165.         losingcolor = white;
  166.     else
  167.         losingcolor = black;
  168.     mating = ((totalmaterial - abs(material)) / 2 <= PieceValue[bishop] * 2)
  169.         && (abs(material) >= PieceValue[rook] - PieceValue[bishop]);
  170.     /*  Calculate ATTACKVAL (importance of each square)  */
  171.     for (rank = 0; rank < 8; rank++)
  172.         for (line = 0; line < 8; line++)
  173.         {
  174.             square = (rank << 4) + line;
  175.             attval = max(0, 8 - 3 * (distan[rank] + distan[line]));
  176.                     /*  center importance */
  177.                     /*  Rank importrance  */
  178.             for (color = white; color <= black; ((int)color)++)
  179.             {
  180.                 attackvalue[color][square] = ((squarerankvalue[rank] * 3 *
  181.                         (materiallevel + 8)) >> 5) + attval;
  182.                 square ^= 0x70;
  183.             }
  184.         }
  185.     for (color = white; color <= black; ((int)color)++)
  186.     {
  187.         oppcolor = (COLORTYPE)(1 - color);
  188.         CalcCastling(oppcolor, &cast);
  189.         if (cast != shrt && materiallevel > 0)
  190.             /*  Importance of the 8 squares around the opponent's King  */
  191.         for (dir = 0; dir < 8; dir++)
  192.         {
  193.             sq = PieceTab[oppcolor][0].isquare + DirTab[dir];
  194.             if (!(sq & 0x88))
  195.                 attackvalue[color][sq] += ((12 * (materiallevel + 8)) >> 5);
  196.         }
  197.     }
  198.  
  199.     /*  Calculate PVControl  */
  200.     for (square = 0x77; square >=0; square--)
  201.         if(!(square & 0x88))
  202.             for (color = white; color <= black; ((int)color)++)
  203.                 for (piececount = rook; piececount <= bishop; ((int)piececount)++)
  204.                     pvcontrol[color][piececount][square] = 0;
  205.     for (square = 0x77; square >=0; square--)
  206.         if(!(square & 0x88))
  207.             for (color = white; color <= black; ((int)color)++)
  208.             {
  209.                 for (dir = 7; dir >= 0; dir--)
  210.                 {
  211.                     if (dir < 4)
  212.                         piececount = rook;
  213.                     else
  214.                         piececount = bishop;
  215.                 /*  Count value of all attacs from the square in
  216.                     the Direction.
  217.                     The Value of attacking a Square is Found in ATTACKVAL.
  218.                     Indirect Attacks (e.g. a Rook attacking through
  219.                     another Rook) counts for a Normal attack,
  220.                     Attacks through another Piece counts half  */
  221.                     cnt = 0;
  222.                     sq = square;
  223.                     direct = 1;
  224.                     do
  225.                     {
  226.                         sq += DirTab[dir];
  227.                         if (sq & 0x88) goto TEN;
  228.                         temp = attackvalue[color][sq];
  229.                         if (direct)
  230.                             cnt += temp;
  231.                         else
  232.                             cnt += (temp >> 1);
  233.                         if (Board[sq].piece != empty)
  234.                             if ((Board[sq].piece != piececount)
  235.                               && (Board[sq].piece != queen))
  236.                                 direct = 0;
  237.                     } while (Board[sq].piece != pawn);
  238. TEN:                pvcontrol[color][piececount][square] += (cnt >> 2);
  239.                 }
  240.             }
  241.  
  242.     /*  Calculate PVTable, value by value  */
  243.     for (square = 0x77; square >= 0; square--)
  244.       if (!(square & 0x88))
  245.       {
  246.          for (color = white; color <= black; ((int)color)++)
  247.          {
  248.             oppcolor = (COLORTYPE)(1 - color);
  249.             line = square & 7;
  250.             rank = square >> 4;
  251.             if (color == black) rank = 7 - rank;
  252.             dist = distan[rank] + distan[line];
  253.             kingdist = abs((square >> 4) - (PieceTab[oppcolor][0].isquare
  254.                    >> 4)) + ((square - PieceTab[oppcolor][0].isquare) & 7);
  255.             for (piececount = king; piececount <= pawn; ((int)piececount)++)
  256.             {
  257.                 posval = 0;        /*  Calculate POSITIONAL Value for  */
  258.                                    /*  The piece on the Square  */
  259.                 if (mating && (piececount != pawn))
  260.                 {
  261.                     if (piececount == king)
  262.                         if (color == losingcolor)  /*  Mating evaluation  */
  263.                         {
  264.                             posval = 128 - 16 * distan[rank]
  265.                                 - 12 * distan[line];
  266.                             if (distan[rank] == 3)
  267.                                 posval -= 16;
  268.                         }
  269.                         else
  270.                         {
  271.                             posval = 128 - 4 * kingdist;
  272.                             if ((distan[rank] >= 2) || (distan[line] == 3))
  273.                                 posval -= 16;
  274.                         }
  275.                 }
  276.                 else
  277.                 {
  278.                     temp = pvcontrol[color][rook][square];
  279.                     temp2 = pvcontrol[color][bishop][square];
  280.                     /*  Normal evaluation function  */
  281.                     switch (piececount)
  282.                     {
  283.                         case king :
  284.                             if (materiallevel <= 0) posval = -2 * dist;
  285.                             break;
  286.                         case queen :
  287.                             posval = (temp + temp2) >> 2;
  288.                             break;
  289.                         case rook :
  290.                             posval = temp;
  291.                             break;
  292.                         case bishop :
  293.                             posval = temp2;
  294.                             break;
  295.                         case knight :
  296.                             cnt = 0;
  297.                             for (dir = 0; dir < 8; dir++)
  298.                             {
  299.                                 sq = square + KnightDir[dir];
  300.                                 if (!(sq & 0x88))
  301.                                     cnt += attackvalue[color][sq];
  302.                             }
  303.                             posval = (cnt >> 1) - dist * 3;
  304.                             break;
  305.                         case pawn :
  306.                             if ((rank != 0) && (rank != 7))
  307.                                 posval = pawnrank[rank] +
  308.                                   pawnfilefactor[line] * (rank + 2) - 12;
  309.                     }
  310.                 }
  311.                 PVTable[color][piececount][square] = posval;
  312.             }
  313.          }
  314.       }
  315.  
  316.     /*  Calculate pawntab (indicates which squares contain pawns)  */
  317.  
  318.     for (color = white; color <= black; ((int)color)++)
  319.         for (rank = 0; rank < 8; rank++)
  320.             pawntab[color][rank] = 0;
  321.     for (square = 0x77; square >= 0; square--)
  322.         if (!(square & 0x88))
  323.             if (Board[square].piece == pawn)
  324.             {
  325.                 rank = square >> 4;
  326.                 if (Board[square].color == black) rank = 7 - rank;
  327.                 pawntab[Board[square].color][rank] |=
  328.                     filebittab[square & 7];
  329.             }
  330.     for (color = white; color <= black; ((int)color)++)  /*  initialize pawnbit  */
  331.     {
  332.         pawnbit[-1][color].one = pawnbit[-1][color].dob = 0;
  333.         for (rank = 1; rank < 7; rank++)
  334.         {
  335.             temp = pawntab[color][rank];
  336.             pawnbit[-1][color].dob |= (pawnbit[-1][color].one & temp);
  337.             pawnbit[-1][color].one |= temp;
  338.         }
  339.     }
  340.     /*  Calculate pawnstructurevalue  */
  341.     RootValue = pawnstrval(-1, Player) - pawnstrval(-1, Opponent);
  342.  
  343.     /*  Calculate static value for pawn structure  */
  344.     for (color = white; color <= black; ((int)color)++)
  345.     {
  346.         oppcolor = (COLORTYPE)(1 - color);
  347.         pawnfiletab = leftsidetab = rightsidetab = behindoppass = 0;
  348.         oppasstab = 0xff;
  349.         for (rank = 1; rank < 7; rank++)
  350.         /*  Squares where opponents pawns are passed pawns  */
  351.         {
  352.             oppasstab &= (~(pawnfiletab | leftsidetab | rightsidetab));
  353.             /*  Squares behind the opponents passed pawns  */
  354.             behindoppass |= (oppasstab & pawntab[oppcolor][7 - rank]);
  355.             /*  squares which are covered by a pawn  */
  356.             leftchaintab = leftsidetab;
  357.             rightchaintab = rightsidetab;
  358.             pawnfiletab = pawntab[color][rank]; /*  squares w/ pawns  */
  359.             /*  squares w/ a pawn beside them  */
  360.             leftsidetab = (pawnfiletab << 1) & 0xff;
  361.             rightsidetab = (pawnfiletab >> 1) & 0xff;
  362.             sidetab = leftsidetab | rightsidetab;
  363.             chaintab = leftchaintab | rightchaintab;
  364.             /*  squares covering a pawn  */
  365.             temp = pawntab[color][rank+1];
  366.             leftcovertab = (temp << 1) & 0xff;
  367.             rightcovertab = (temp >> 1 ) & 0xff;
  368.             sq = rank << 4;
  369.             if (color == black) sq ^= 0x70;
  370.             bit = 1;
  371.             while (bit)
  372.             {
  373.                 strval = 0;
  374.                 if (bit & sidetab)
  375.                     strval = SIDEPAWN;
  376.                 else if (bit & chaintab)
  377.                     strval = CHAINPAWN;
  378.                 if (bit & leftcovertab)
  379.                     strval += COVERPAWN;
  380.                 if (bit & rightcovertab)
  381.                     strval += COVERPAWN;
  382.                 if (bit & pawnfiletab)
  383.                     strval += NOTMOVEPAWN;
  384.                 PVTable[color][pawn][sq] += strval;
  385.                 if ((materiallevel <= 0) || (oppcolor != ProgramColor))
  386.                 {
  387.                     if (bit & oppasstab)
  388.                         PVTable[oppcolor][pawn][sq] += passpawnrank[7 - rank];
  389.                     if (bit & behindoppass)
  390.                     {
  391.                         temp = sq ^ 0x10;
  392.                         for (tempcolor = black; tempcolor >= white
  393.                             ; ((int)tempcolor)--)
  394.                         {
  395.                             PVTable[tempcolor][rook][sq] +=
  396.                                 ROOKBEHINDPASSPAWN;
  397.                             if (rank == 6)
  398.                                 PVTable[tempcolor][rook][temp] +=
  399.                                     ROOKBEHINDPASSPAWN;
  400.                         }
  401.                     }
  402.                 }
  403.                 sq++;
  404.                 bit = (bit << 1) & 0xff;
  405.             }
  406.         }
  407.     }
  408.     /*  Calculate penalty for blocking center pawns with a bishop  */
  409.     for (sq = 3; sq < 5; sq ++)
  410.     {
  411.         if ((Board[sq + 0x10].piece == pawn) && (Board[sq + 0x10].color
  412.             == white))
  413.             PVTable[white][bishop][sq + 0x20] -= BISHOPBLOCKVALUE;
  414.         if ((Board[sq+0x60].piece == pawn) && (Board[sq+0x60].color == black))
  415.             PVTable[black][bishop][sq+0x50] -= BISHOPBLOCKVALUE;
  416.     }
  417.     for (square = 0x77; square >= 0; square--) /*  Calculate RootValue  */
  418.         if (!(square & 0x88))
  419.             if (Board[square].piece != empty)
  420.                 if (Board[square].color == Player)
  421.                     RootValue +=
  422.                         PiecePosVal(Board[square].piece, Player, square);
  423.                 else
  424.                     RootValue -=
  425.                         PiecePosVal(Board[square].piece, Opponent, square);
  426. }
  427.  
  428. /****************************************************************************/
  429.  
  430. int value;
  431. SQUARETYPE castsquare, cornersquare, epsquare;
  432.  
  433.  
  434. /*
  435.  *  Update pawnbit and calculates value when a pawn is removed from line
  436.  */
  437.  
  438. inline int decpawnstrval(COLORTYPE color, FILETYPE line)
  439. {
  440.     temp = ~filebittab[line];
  441.     pawnbit[Depth][color].one = (pawnbit[Depth][color].one & temp) |
  442.             pawnbit[Depth][color].dob;
  443.     pawnbit[Depth][color].dob &= temp;
  444.     return (pawnstrval(Depth, color) - pawnstrval(Depth - 1, color));
  445. }
  446.  
  447. /*
  448.  *  Update pawnbit and calculates value when a pawn moves
  449.  *  from old to new1 file
  450.  */
  451.  
  452. static int movepawnstrval(COLORTYPE color, FILETYPE new1, FILETYPE old)
  453. {
  454.     temp = filebittab[new1];
  455.     temp2 = ~filebittab[old];
  456.     pawnbit[Depth][color].dob |= (pawnbit[Depth][color].one & temp);
  457.     pawnbit[Depth][color].one = ((pawnbit[Depth][color].one & temp2) |
  458.         pawnbit[Depth][color].dob) | temp;
  459.     pawnbit[Depth][color].dob &= temp2;
  460.     return (pawnstrval(Depth, color) - pawnstrval(Depth - 1, color));
  461. }
  462.  
  463. /****************************************************************************/
  464.  
  465. /*
  466.  *  Calculate STATIC evaluation of the move
  467.  */
  468.  
  469. int StatEvalu(MOVETYPE *move)
  470. {
  471.     value = 0;
  472.     if (move->spe)
  473.         if (move->movpiece == king)
  474.         {
  475.             GenCastSquare(move->new1, &castsquare, &cornersquare);
  476.             value = PiecePosVal(rook, Player, castsquare) -
  477.                     PiecePosVal(rook,Player, cornersquare);
  478.             if (move->new1 > move->old)
  479.                 value += castvalue[shrt-1];
  480.             else
  481.                 value += castvalue[lng-1];
  482.         }
  483.         else if (move->movpiece == pawn)
  484.         {
  485.             epsquare = move->new1 - PawnDir[Player];  /*  E.p. capture  */
  486.             value = PiecePosVal(pawn, Opponent, epsquare);
  487.         }
  488.         else            /*  Pawnpromotion  */
  489.             value = PiecePosVal(move->movpiece, Player, move->old) -
  490.                     PiecePosVal(pawn, Player, move->old) +
  491.                     decpawnstrval(Player, move->old & 7);
  492.         if (move->content != empty)  /*  normal moves  */
  493.         {
  494.             value += PiecePosVal(move->content, Opponent, move->new1);
  495.             /*  Penalty for exchanging pieces when behind in material  */
  496.             if (abs(MainEvalu) >= 0x100)
  497.                 if (move->content != pawn)
  498.                     if ((ProgramColor == Opponent) == (MainEvalu >= 0))
  499.                         value -= EXCHANGEVALUE;
  500.         }
  501.         pawnbit[Depth][black] = pawnbit[Depth - 1][black];  /*  calculate pawnbit  */
  502.         pawnbit[Depth][white] = pawnbit[Depth - 1][white];
  503.         if ((move->movpiece == pawn) && ((move->content != empty)
  504.                 || move->spe))
  505.             value += movepawnstrval(Player, move->new1 & 7, move->old & 7);
  506.         if ((move->content == pawn) || move->spe && (move->movpiece == pawn))
  507.             value -= decpawnstrval(Opponent, move->new1 & 7);
  508.         /*  Calculate value of move  */
  509.         return (value + PiecePosVal(move->movpiece, Player, move->new1)-
  510.                 PiecePosVal(move->movpiece, Player, move->old));
  511. }
  512.  
  513.