Esempio n. 1
0
 private static void EvalTrappedKnights(Evaluation e, int[] eval, int side, int sq)
 {
     //look for trapped knights
     if (side == 0)
     {
         if (sq == 7) // white knight on h8
         {
             if ((e.Board.Pawns[1] & (BitMask.Mask[13] | BitMask.Mask[15])) > 0)
             {
                 eval[0] -= PieceValues[(int)Piece.Knight] / 2; //this trap costs us half a knight
             }
         }
         else if (sq == 0)
         {  //white knight on a8
             if ((e.Board.Pawns[1] & (BitMask.Mask[8] | BitMask.Mask[10])) > 0)
             {
                 eval[0] -= PieceValues[(int)Piece.Knight] / 2; //this trap costs us half a knight
             }
         }
         else if (sq == 15) //white knight on h7
         {
             if ((e.Board.Pawns[1] & BitMask.Mask[14]) > 0 &&
                 (e.Board.Pawns[1] & (BitMask.Mask[23] | BitMask.Mask[21])) > 0)
             {
                 eval[0] -= PieceValues[(int)Piece.Knight] / 2; //this trap costs us half a knight
             }
         }
         else if (sq == 08) //white knight on a7
         {
             if ((e.Board.Pawns[1] & BitMask.Mask[9]) > 0 &&
                 (e.Board.Pawns[1] & (BitMask.Mask[16] | BitMask.Mask[18])) > 0)
             {
                 eval[0] -= PieceValues[(int)Piece.Knight] / 2; //this trap costs us half a knight
             }
         }
     }
     else
     {
         if (sq == 63) // black knight on h1
         {
             if ((e.Board.Pawns[0] & (BitMask.Mask[53] | BitMask.Mask[55])) > 0)
             {
                 eval[1] -= PieceValues[(int)Piece.Knight] / 2; //this trap costs us half a knight
             }
         }
         else if (sq == 56)
         { //black knight on a1
             if ((e.Board.Pawns[0] & (BitMask.Mask[48] | BitMask.Mask[50])) > 0)
             {
                 eval[1] -= PieceValues[(int)Piece.Knight] / 2; //this trap costs us half a knight
             }
         }
         else if (sq == 55) //black knight on h2
         {
             if ((e.Board.Pawns[0] & BitMask.Mask[54]) > 0 &&
                 (e.Board.Pawns[0] & (BitMask.Mask[45] | BitMask.Mask[47])) > 0)
             {
                 eval[1] -= PieceValues[(int)Piece.Knight] / 2; //this trap costs us half a knight
             }
         }
         else if (sq == 48)//black knight on a2
         {
             if ((e.Board.Pawns[0] & BitMask.Mask[49]) > 0 &&
                 (e.Board.Pawns[0] & (BitMask.Mask[40] | BitMask.Mask[42])) > 0)
             {
                 eval[1] -= PieceValues[(int)Piece.Knight] / 2; //this trap costs us half a knight
             }
         }
     }
 }
Esempio n. 2
0
        static int EvaluatePieces(Evaluation e)
        {
            //evaluate things like material imbalance,
            //bishop pair, knights supported by pawns, etc.

            int[] eval = new int[2];
            for (int side = 0; side < 2; side++)
            {
                int xside = side ^ 1;

                //evaluate material imbalances
                // a rook+pawn for two pieces is not good

                //if side has only one rook and opponent has two
                if (e.Board.Rooks[side] > 0 &&
                    e.Board.Rooks[xside] > 0 &&
                    e.Board.Rooks[side].Count() == 1 &&
                    e.Board.Rooks[xside].Count() == 2)
                {
                    //if opposite side has two less minors then we get a bonus
                    if (e.Board.Minors(side).Count() - e.Board.Minors(xside).Count() == 2)
                    {
                        eval[side] += MinorMaterialInbalanceBonus;
                    }
                }

                //bishop pair bonus
                eval[side] += (e.Board.Bishops[side].Count() == 2) ? BishopPairBonus : 0;

                //increase the value of rooks as pawns come off the board
                int totalPawns = e.Board.Pawns[0].Count() + e.Board.Pawns[1].Count();
                eval[side] += RookBonusPawnCount[totalPawns];

                //rooks
                var rooks = e.Board.Rooks[side];
                while (rooks > 0)
                {
                    int sq = rooks.BitScanForward();
                    rooks ^= BitMask.Mask[sq];

                    //open file bonus
                    if (e.PawnScore.Files[side, sq.File()] == 0)
                    {
                        eval[side] += RookOnOpenFileBonus / 2;
                        if (e.PawnScore.Files[xside, sq.File()] == 0)
                        {
                            eval[side] = RookOnOpenFileBonus;
                        }
                    }

                    //rooks on the seventh (or eigth)
                    if (side == 0 && sq.Rank() <= 1)
                    {
                        eval[0] += RookOnSeventhBonus;
                    }
                    else if (side == 1 && sq.Rank() >= 6)
                    {
                        eval[1] += RookOnSeventhBonus;
                    }
                }

                //knights
                var knights = e.Board.Knights[side];
                while (knights > 0)
                {
                    int sq = knights.BitScanForward();
                    knights ^= BitMask.Mask[sq];

                    //only looking for forward knights
                    if (side == 0 && sq.Rank() > 3)
                    {
                        continue;
                    }
                    else if (side == 1 && sq.Rank() < 3)
                    {
                        continue;
                    }

                    //look for knights on outposts
                    if ((MoveGenerator.PawnAttacks[xside, sq] & e.Board.Pawns[side]) > 0)
                    {
                        //knight is defended by a pawn
                        //use the passed pawn lookup - minus the file to see if
                        //we have an ouput
                        if ((PassedPawnMask[side, sq] & ~Board.FileMask[sq.File()] & e.Board.Pawns[xside]) == 0)
                        {
                            eval[side] += KnightOnOutpostBonus;
                        }
                    }

                    EvalTrappedKnights(e, eval, side, sq);
                }

                var bishops = e.Board.Bishops[side];
                while (bishops > 0)
                {
                    int sq = bishops.BitScanForward();
                    bishops ^= BitMask.Mask[sq];

                    //evaluate trapped bishops
                    if (side == 0)
                    {
                        if (sq == 23 && //white bishop on h6
                            (e.Board.Pawns[1] & BitMask.Mask[30]) > 0 &&
                            (e.Board.Pawns[1] & BitMask.Mask[21]) > 0)
                        {
                            eval[side] -= PieceValues[(int)Piece.Bishop] / 3;
                        }

                        else if (sq == 16 && //white bishop on a6
                                 (e.Board.Pawns[1] & BitMask.Mask[25]) > 0 &&
                                 (e.Board.Pawns[1] & BitMask.Mask[18]) > 0)
                        {
                            eval[side] -= PieceValues[(int)Piece.Bishop] / 3;
                        }
                    }
                    else
                    {
                        if (sq == 47 && //blackbishop on h3
                            (e.Board.Pawns[0] & BitMask.Mask[38]) > 0 &&
                            (e.Board.Pawns[0] & BitMask.Mask[47]) > 0)
                        {
                            eval[side] -= PieceValues[(int)Piece.Bishop] / 3;
                        }
                        else if (sq == 40 && //black bishop on a3
                                 (e.Board.Pawns[0] & BitMask.Mask[33]) > 0 &&
                                 (e.Board.Pawns[0] & BitMask.Mask[42]) > 0)
                        {
                            eval[side] -= PieceValues[(int)Piece.Bishop] / 3;
                        }
                    }

                    //mobility score
                    var mobilitySquares = MoveGenerator.BishopAttacks(e.Board, sq);
                    eval[side] += mobilitySquares.Count();
                }
            }

            return(eval[e.Board.SideToMove] - eval[e.Board.SideToMove ^ 1]);
        }