Exemplo n.º 1
0
 //        logger.debug("***PAWN");
 //        printPcsq(pawnIndexValue);
 //        logger.debug("***KNIGHT");
 //        printPcsq(knightIndexValue);
 //        logger.debug("***BISHOP");
 //        printPcsq(bishopIndexValue);
 //        logger.debug("***ROOK");
 //        printPcsq(rookIndexValue);
 //        logger.debug("***QUEEN");
 //        printPcsq(queenIndexValue);
 //        logger.debug("***KING");
 //        printPcsq(kingIndexValue);
 //        logger.debug("PCSQ tables generated");
 //    private static void printPcsq(int pcsq[]) {
 //        StringBuffer sb = new StringBuffer();
 //        for (int k=0; k<2; k++) {
 //            if (k==0) sb.append("Opening:\n");
 //            else sb.append("Endgame:\n");
 //            for (int i = 0; i<64; i++) {
 //                String aux = "     " + (k==0 ? o(pcsq[i]) : e(pcsq[i]));
 //                aux = aux.substring(aux.length()-5);
 //                sb.append(aux);
 //                if (i%8 != 7) {
 //                    sb.append(",");
 //                } else {
 //                    sb.append("\n");
 //                }
 //            }
 //        }
 //        logger.debug(sb.toString());
 //    }
 public override int EvaluateBoard(Board board, int alpha, int beta)
 {
     long square = 1;
     byte index = 0;
     all = board.GetAll();
     superiorPieceAttacked[0] = superiorPieceAttacked[1] = 0;
     attacksColor[0] = attacksColor[1] = 0;
     material[0] = material[1] = 0;
     pawnMaterial[0] = pawnMaterial[1] = 0;
     center[0] = center[1] = 0;
     positional[0] = positional[1] = 0;
     mobility[0] = mobility[1] = 0;
     attacks[0] = attacks[1] = 0;
     kingAttackersCount[0] = kingAttackersCount[1] = 0;
     kingSafety[0] = kingSafety[1] = 0;
     kingDefense[0] = kingDefense[1] = 0;
     pawnStructure[0] = pawnStructure[1] = 0;
     passedPawns[0] = passedPawns[1] = 0;
     bishopCount[0] = bishopCount[1] = 0;
     // Squares attackeds by pawns
     pawnAttacks[0] = ((board.pawns & board.whites & ~BitboardUtils.b_l) << 9) | ((board
         .pawns & board.whites & ~BitboardUtils.b_r) << 7);
     pawnAttacks[1] = ((long)(((ulong)(board.pawns & board.blacks & ~BitboardUtils.b_r
         )) >> 9)) | ((long)(((ulong)(board.pawns & board.blacks & ~BitboardUtils.b_l)) >>
          7));
     // Square that pawn attacks or can attack by advancing
     pawnCanAttack[0] = pawnAttacks[0] | pawnAttacks[0] << 8 | pawnAttacks[0] << 16 |
         pawnAttacks[0] << 24 | pawnAttacks[0] << 32 | pawnAttacks[0] << 40;
     pawnCanAttack[1] = pawnAttacks[1] | (long)(((ulong)pawnAttacks[1]) >> 8) | (long)
         (((ulong)pawnAttacks[1]) >> 16) | (long)(((ulong)pawnAttacks[1]) >> 24) | (long)
         (((ulong)pawnAttacks[1]) >> 32) | (long)(((ulong)pawnAttacks[1]) >> 40);
     // Squares surrounding King
     squaresNearKing[0] = bbAttacks.king[BitboardUtils.Square2Index(board.whites & board
         .kings)] | board.whites & board.kings;
     squaresNearKing[1] = bbAttacks.king[BitboardUtils.Square2Index(board.blacks & board
         .kings)] | board.blacks & board.kings;
     minorPiecesDefendedByPawns[0] = board.whites & (board.bishops | board.knights) &
         pawnAttacks[0];
     minorPiecesDefendedByPawns[1] = board.blacks & (board.bishops | board.knights) &
         pawnAttacks[1];
     // first build attacks info
     square = 1;
     for (index = 0; ((sbyte)index) < 64; index++)
     {
         if ((square & all) != 0)
         {
             bool isWhite = ((board.whites & square) != 0);
             int color = (isWhite ? 0 : 1);
             if ((square & board.pawns) != 0)
             {
                 pieceAttacks = (isWhite ? bbAttacks.pawnUpwards[index] : bbAttacks.pawnDownwards[
                     index]);
             }
             else
             {
                 if ((square & board.knights) != 0)
                 {
                     pieceAttacks = bbAttacks.knight[index];
                 }
                 else
                 {
                     if ((square & board.bishops) != 0)
                     {
                         pieceAttacks = bbAttacks.GetBishopAttacks(index, all);
                     }
                     else
                     {
                         if ((square & board.rooks) != 0)
                         {
                             pieceAttacks = bbAttacks.GetRookAttacks(index, all);
                         }
                         else
                         {
                             if ((square & board.queens) != 0)
                             {
                                 pieceAttacks = bbAttacks.GetRookAttacks(index, all) | bbAttacks.GetBishopAttacks(
                                     index, all);
                             }
                             else
                             {
                                 if ((square & board.kings) != 0)
                                 {
                                     pieceAttacks = bbAttacks.king[index];
                                 }
                                 else
                                 {
                                     pieceAttacks = 0;
                                 }
                             }
                         }
                     }
                 }
             }
             attacksColor[color] |= pieceAttacks;
             attacksSquare[index] = pieceAttacks;
         }
         square <<= 1;
     }
     // Ok, ended initialization
     square = 1;
     index = 0;
     while (square != 0)
     {
         if ((square & all) != 0)
         {
             bool isWhite = ((board.whites & square) != 0);
             int color = (isWhite ? 0 : 1);
             long mines = (isWhite ? board.whites : board.blacks);
             long others = (isWhite ? board.blacks : board.whites);
             long otherPawnAttacks = (isWhite ? pawnAttacks[1] : pawnAttacks[0]);
             int pcsqIndex = (isWhite ? index : 63 - index);
             int rank = index >> 3;
             int column = 7 - index & 7;
             pieceAttacks = attacksSquare[index];
             if ((square & board.pawns) != 0)
             {
                 pawnMaterial[color] += PAWN;
                 center[color] += pawnIndexValue[pcsqIndex];
                 if ((pieceAttacks & squaresNearKing[1 - color] & ~otherPawnAttacks) != 0)
                 {
                     kingSafety[color] += PAWN_ATTACKS_KING;
                 }
                 // TODO: if two pawns attacks the same square, add only once
                 if ((pieceAttacks & board.knights & others) != 0)
                 {
                     attacks[color] += PAWN_ATTACKS_KNIGHT;
                 }
                 if ((pieceAttacks & board.bishops & others) != 0)
                 {
                     attacks[color] += PAWN_ATTACKS_BISHOP;
                 }
                 if ((pieceAttacks & board.rooks & others) != 0)
                 {
                     attacks[color] += PAWN_ATTACKS_ROOK;
                 }
                 if ((pieceAttacks & board.queens & others) != 0)
                 {
                     attacks[color] += PAWN_ATTACKS_QUEEN;
                 }
                 superiorPieceAttacked[color] |= pieceAttacks & others & (board.knights | board.bishops
                      | board.rooks | board.queens);
                 bool isolated = (BitboardUtils.COLUMNS_ADJACENTS[column] & board.pawns & mines) ==
                      0;
                 bool doubled = (BitboardUtils.COLUMN[column] & BitboardUtils.RANKS_FORWARD[color]
                     [rank] & board.pawns & mines) != 0;
                 //					boolean backwards = ((BitboardUtils.COLUMN[column] | BitboardUtils.COLUMNS_ADJACENTS[column]) & ~BitboardUtils.RANKS_FORWARD[color][rank] & board.pawns & mines) == 0;
                 //					boolean weak = !isolated && (pawnAttacks[color] & square) == 0
                 //					&& pcsqIndex >= 24;
                 //					 // not defended is weak
                 //					if (weak) {
                 //						// Can be defended advancing one pawn
                 //						auxLong = (isWhite ? BitboardAttacks.pawnDownwards[color] : BitboardAttacks.pawnUpwards[color]) & ~otherPawnAttacks & ~all;
                 //						while (auxLong != 0) { // Not attacked by other pawn and empty
                 //							auxLong2 = BitboardUtils.lsb(auxLong);
                 //							auxLong &= ~auxLong2;
                 //							auxLong2 = isWhite ?  auxLong2 >>> 8 : auxLong2 << 8;
                 //							if ((auxLong2 & mines & board.pawns) !=0) {
                 //								weak = false;
                 //							} else { // Defended advancing one pawn two squares
                 //								if ((auxLong2 & all) == 0) { // empty square
                 //									auxLong2 = (isWhite ? auxLong2 >>> 8 : auxLong2 << 8);
                 //									if (((isWhite ? BitboardUtils.RANK[1] : BitboardUtils.RANK[6]) & auxLong2 & board.pawns & mines) != 0) {
                 //										weak = false;
                 //									}
                 //								}
                 //							}
                 //						}
                 //
                 //						if (weak) {
                 //							// Can advance to be supported
                 //							auxLong = (isWhite ? square << 8 : square >>> 8) & ~otherPawnAttacks & ~all;
                 //							if (auxLong != 0) {
                 //								if ((auxLong & pawnAttacks[color]) != 0) {
                 //									weak = false;
                 //								} else {
                 //									// Checks advancing two squares if in initial position
                 //									if (((isWhite ? BitboardUtils.RANK[1] : BitboardUtils.RANK[6]) & square) != 0) {
                 //										auxLong = (isWhite ? square << 16 : square >>> 16) & ~otherPawnAttacks & ~all;
                 //										if ((auxLong & pawnAttacks[color]) != 0) weak = false;
                 //									}
                 //								}
                 //							}
                 //						}
                 //					}
                 //					if (weak) pawnStructure[color] += PAWN_WEAK;
                 ////					if (weak) {
                 ////						System.out.println("weak pawn: \n" + board.toString());
                 ////						System.out.println("square: \n" + BitboardUtils.toString(square));
                 ////					}
                 //
                 // No pawns in front
                 if ((BitboardUtils.COLUMN[column] & BitboardUtils.RANKS_FORWARD[color][rank] & board
                     .pawns) == 0)
                 {
                     if (doubled)
                     {
                         pawnStructure[color] += PAWN_NO_FRONT_DOUBLED;
                         if (isolated)
                         {
                             pawnStructure[color] += PAWN_NO_FRONT_DOUB_ISO;
                         }
                     }
                     else
                     {
                         if (isolated)
                         {
                             pawnStructure[color] += PAWN_NO_FRONT_ISOLATED;
                         }
                     }
                 }
                 else
                 {
                     // pawns in front
                     if (doubled)
                     {
                         pawnStructure[color] += PAWN_FRONT_DOUBLED;
                         if (isolated)
                         {
                             pawnStructure[color] += PAWN_FRONT_DOUB_ISO;
                         }
                     }
                     else
                     {
                         if (isolated)
                         {
                             pawnStructure[color] += PAWN_FRONT_ISOLATED;
                         }
                     }
                 }
                 // Backwards pawns and advance squares attacked by opposite pawns (TODO only three)
                 //					if (backwards && (BitboardUtils.COLUMN[column] & BitboardUtils.RANKS_FORWARD[color][rank] & otherPawnAttacks) !=0)
                 //						pawnStructure[color] += PAWN_BACKWARDS;
                 // Passed Pawns
                 if (((BitboardUtils.COLUMN[column] | BitboardUtils.COLUMNS_ADJACENTS[column]) & BitboardUtils
                     .RANKS_FORWARD[color][rank] & board.pawns & others) == 0)
                 {
                     // Static part
                     passedPawns[color] += PAWN_PASSER[(isWhite ? rank : 7 - rank)];
                     if ((square & pawnAttacks[color]) != 0)
                     {
                         passedPawns[color] += PAWN_PASSER_PROTECTED[(isWhite ? rank : 7 - rank)];
                     }
                     if ((BitboardUtils.ROWS_LEFT[column] & board.pawns & others) == 0 && (BitboardUtils
                         .ROWS_RIGHT[column] & board.pawns & others) == 0)
                     {
                         passedPawns[color] += PAWN_PASSER_OUTSIDE[(isWhite ? rank : 7 - rank)];
                     }
                     // Dynamic part
                     auxLong = BitboardUtils.COLUMN[column] & BitboardUtils.RANKS_FORWARD[color][rank];
                     if ((auxLong & mines) == 0)
                     {
                         passedPawns[color] += PAWN_PASSER_NO_MINES[(isWhite ? rank : 7 - rank)];
                     }
                     if ((auxLong & others) == 0)
                     {
                         passedPawns[color] += PAWN_PASSER_NO_OTHERS[(isWhite ? rank : 7 - rank)];
                     }
                     if (((isWhite ? square << 8 : (long)(((ulong)square) >> 8)) & others) == 0)
                     {
                         passedPawns[color] += PAWN_PASSER_MOBILE[(isWhite ? rank : 7 - rank)];
                     }
                     if ((auxLong & ~attacksColor[color] & attacksColor[1 - color]) == 0)
                     {
                         passedPawns[color] += PAWN_PASSER_RUNNER[(isWhite ? rank : 7 - rank)];
                     }
                     if ((BitboardUtils.COLUMN[column] & BitboardUtils.RANKS_BACKWARD[color][rank] & board
                         .rooks & mines) != 0)
                     {
                         passedPawns[color] += PAWN_PASSER_ROOK_BEHIND[(isWhite ? rank : 7 - rank)];
                     }
                 }
                 else
                 {
                     // Candidates is the same check but removing opposite pawns attacking our square
                     if (((BitboardUtils.COLUMN[column] | BitboardUtils.COLUMNS_ADJACENTS[column]) & BitboardUtils
                         .RANKS_FORWARD[color][rank] & (isWhite ? bbAttacks.pawnUpwards[index] : bbAttacks
                         .pawnDownwards[index]) & board.pawns & others) == 0)
                     {
                         passedPawns[color] += PAWN_CANDIDATE[(isWhite ? rank : 7 - rank)];
                     }
                 }
             }
             else
             {
                 if ((square & board.knights) != 0)
                 {
                     material[color] += KNIGHT;
                     center[color] += knightIndexValue[pcsqIndex];
                     // Only mobility forward
                     mobility[color] += KNIGHT_M * BitboardUtils.PopCount(pieceAttacks & ~mines & ~otherPawnAttacks
                          & BitboardUtils.RANKS_FORWARD[color][rank]);
                     if ((pieceAttacks & squaresNearKing[1 - color] & ~otherPawnAttacks) != 0)
                     {
                         kingSafety[color] += KNIGHT_ATTACKS_KING;
                         kingAttackersCount[color]++;
                     }
                     if ((pieceAttacks & squaresNearKing[color]) != 0)
                     {
                         kingDefense[color] += KNIGHT_DEFENDS_KING;
                     }
                     if ((pieceAttacks & board.pawns & others & ~otherPawnAttacks) != 0)
                     {
                         attacks[color] += KNIGHT_ATTACKS_PU_P;
                     }
                     if ((pieceAttacks & board.bishops & others & ~otherPawnAttacks) != 0)
                     {
                         attacks[color] += KNIGHT_ATTACKS_PU_B;
                     }
                     if ((pieceAttacks & (board.rooks | board.queens) & others) != 0)
                     {
                         attacks[color] += KNIGHT_ATTACKS_RQ;
                     }
                     superiorPieceAttacked[color] |= pieceAttacks & others & (board.rooks | board.queens
                         );
                     // Knight Outpost: no opposite pawns can attack the square
                     if ((square & OUTPOST_MASK[color] & ~pawnCanAttack[1 - color]) != 0)
                     {
                         positional[color] += KNIGHT_OUTPOST;
                         // Defended by one of our pawns
                         if ((square & pawnAttacks[color]) != 0)
                         {
                             positional[color] += KNIGHT_OUTPOST;
                             // Attacks squares near king or other pieces pawn undefended
                             if ((pieceAttacks & (squaresNearKing[1 - color] | others) & ~otherPawnAttacks) !=
                                  0)
                             {
                                 positional[color] += KNIGHT_OUTPOST_ATTACKS_NK_PU[pcsqIndex];
                             }
                         }
                     }
                 }
                 else
                 {
                     if ((square & board.bishops) != 0)
                     {
                         material[color] += BISHOP;
                         if (bishopCount[color]++ == 2)
                         {
                             material[color] += BISHOP_PAIR;
                         }
                         center[color] += bishopIndexValue[pcsqIndex];
                         mobility[color] += BISHOP_M * BitboardUtils.PopCount(pieceAttacks & ~mines & ~otherPawnAttacks
                              & BitboardUtils.RANKS_FORWARD[color][rank]);
                         if ((pieceAttacks & squaresNearKing[1 - color] & ~otherPawnAttacks) != 0)
                         {
                             kingSafety[color] += BISHOP_ATTACKS_KING;
                             kingAttackersCount[color]++;
                         }
                         if ((pieceAttacks & squaresNearKing[color]) != 0)
                         {
                             kingDefense[color] += BISHOP_DEFENDS_KING;
                         }
                         if ((pieceAttacks & board.pawns & others & ~otherPawnAttacks) != 0)
                         {
                             attacks[color] += BISHOP_ATTACKS_PU_P;
                         }
                         if ((pieceAttacks & board.knights & others & ~otherPawnAttacks) != 0)
                         {
                             attacks[color] += BISHOP_ATTACKS_PU_K;
                         }
                         if ((pieceAttacks & (board.rooks | board.queens) & others) != 0)
                         {
                             attacks[color] += BISHOP_ATTACKS_RQ;
                         }
                         superiorPieceAttacked[color] |= pieceAttacks & others & (board.rooks | board.queens
                             );
                         pieceAttacksXray = bbAttacks.GetBishopAttacks(index, all & ~(pieceAttacks & others
                             )) & ~pieceAttacks;
                         if ((pieceAttacksXray & (board.rooks | board.queens | board.kings) & others) != 0)
                         {
                             attacks[color] += PINNED_PIECE;
                         }
                         // Bishop Outpost: no opposite pawns can attack the square and defended by one of our pawns
                         if ((square & OUTPOST_MASK[color] & ~pawnCanAttack[1 - color] & pawnAttacks[color
                             ]) != 0)
                         {
                             positional[color] += BISHOP_OUTPOST;
                             // Attacks squares near king or other pieces pawn undefended
                             if ((pieceAttacks & (squaresNearKing[1 - color] | others) & ~otherPawnAttacks) !=
                                  0)
                             {
                                 positional[color] += BISHOP_OUTPOST_ATT_NK_PU;
                             }
                         }
                         // Pawns in our color
                         if ((square & BitboardUtils.WHITE_SQUARES) != 0)
                         {
                             auxLong = BitboardUtils.WHITE_SQUARES;
                         }
                         else
                         {
                             auxLong = BitboardUtils.BLACK_SQUARES;
                         }
                         positional[color] += ((int)(((uint)BitboardUtils.PopCount(auxLong & board.pawns &
                              mines) + BitboardUtils.PopCount(auxLong & board.pawns & mines)) >> 1)) * BISHOP_PAWN_IN_COLOR;
                         positional[color] += ((int)(((uint)BitboardUtils.PopCount(auxLong & board.pawns &
                              others & BitboardUtils.RANKS_FORWARD[color][rank])) >> 1)) * BISHOP_FORWARD_P_PU;
                         if ((BISHOP_TRAPPING[index] & board.pawns & others) != 0)
                         {
                             mobility[color] += BISHOP_TRAPPED;
                         }
                     }
                     else
                     {
                         // TODO protection
                         if ((square & board.rooks) != 0)
                         {
                             material[color] += ROOK;
                             center[color] += rookIndexValue[pcsqIndex];
                             mobility[color] += ROOK_M * BitboardUtils.PopCount(pieceAttacks & ~mines & ~otherPawnAttacks
                                 );
                             if ((pieceAttacks & squaresNearKing[1 - color] & ~otherPawnAttacks) != 0)
                             {
                                 kingSafety[color] += ROOK_ATTACKS_KING;
                                 kingAttackersCount[color]++;
                             }
                             if ((pieceAttacks & squaresNearKing[color]) != 0)
                             {
                                 kingDefense[color] += ROOK_DEFENDS_KING;
                             }
                             if ((pieceAttacks & board.pawns & others & ~otherPawnAttacks) != 0)
                             {
                                 attacks[color] += ROOK_ATTACKS_PU_P;
                             }
                             if ((pieceAttacks & (board.bishops | board.knights) & others & ~otherPawnAttacks)
                                  != 0)
                             {
                                 attacks[color] += ROOK_ATTACKS_PU_BK;
                             }
                             if ((pieceAttacks & board.queens & others) != 0)
                             {
                                 attacks[color] += ROOK_ATTACKS_Q;
                             }
                             superiorPieceAttacked[color] |= pieceAttacks & others & board.queens;
                             pieceAttacksXray = bbAttacks.GetRookAttacks(index, all & ~(pieceAttacks & others)
                                 ) & ~pieceAttacks;
                             if ((pieceAttacksXray & (board.queens | board.kings) & others) != 0)
                             {
                                 attacks[color] += PINNED_PIECE;
                             }
                             auxLong = (isWhite ? BitboardUtils.b_u : BitboardUtils.b_d);
                             if ((square & auxLong) != 0 && (others & board.kings & auxLong) != 0)
                             {
                                 positional[color] += ROOK_8_KING_8;
                             }
                             if ((square & (isWhite ? BitboardUtils.r2_u : BitboardUtils.r2_d)) != 0 & (others
                                  & (board.kings | board.pawns) & (isWhite ? BitboardUtils.b2_u : BitboardUtils.b2_d
                                 )) != 0)
                             {
                                 positional[color] += ROOK_7_KP_78;
                                 if ((others & board.kings & auxLong) != 0 && (pieceAttacks & others & (board.queens
                                      | board.rooks) & (isWhite ? BitboardUtils.r2_u : BitboardUtils.r2_d)) != 0)
                                 {
                                     positional[color] += ROOK_7_P_78_K_8_RQ_7;
                                 }
                             }
                             if ((square & (isWhite ? BitboardUtils.r3_u : BitboardUtils.r3_d)) != 0 & (others
                                  & (board.kings | board.pawns) & (isWhite ? BitboardUtils.b3_u : BitboardUtils.b3_d
                                 )) != 0)
                             {
                                 positional[color] += ROOK_6_KP_678;
                             }
                             auxLong = BitboardUtils.COLUMN[column] & BitboardUtils.RANKS_FORWARD[color][rank];
                             if ((auxLong & board.pawns & mines) == 0)
                             {
                                 positional[color] += ROOK_COLUMN_SEMIOPEN;
                                 if ((auxLong & board.pawns) == 0)
                                 {
                                     if ((auxLong & minorPiecesDefendedByPawns[1 - color]) == 0)
                                     {
                                         positional[color] += ROOK_COLUMN_OPEN_NO_MG;
                                     }
                                     else
                                     {
                                         if ((auxLong & minorPiecesDefendedByPawns[1 - color] & pawnCanAttack[color]) == 0)
                                         {
                                             positional[color] += ROOK_COLUMN_OPEN_MG_NP;
                                         }
                                         else
                                         {
                                             positional[color] += ROOK_COLUMN_OPEN_MG_P;
                                         }
                                     }
                                 }
                                 else
                                 {
                                     // There is an opposite backward pawn
                                     if ((auxLong & board.pawns & others & pawnCanAttack[1 - color]) == 0)
                                     {
                                         positional[color] += ROOK_COLUMN_SEMIOPEN_BP;
                                     }
                                 }
                                 if ((auxLong & board.kings & others) != 0)
                                 {
                                     positional[color] += ROOK_COLUMN_SEMIOPEN_K;
                                 }
                             }
                             // Rook Outpost: no opposite pawns can attack the square and defended by one of our pawns
                             if ((square & OUTPOST_MASK[color] & ~pawnCanAttack[1 - color] & pawnAttacks[color
                                 ]) != 0)
                             {
                                 positional[color] += ROOK_OUTPOST;
                                 // Attacks squares near king or other pieces pawn undefended
                                 if ((pieceAttacks & (squaresNearKing[1 - color] | others) & ~otherPawnAttacks) !=
                                      0)
                                 {
                                     positional[color] += ROOK_OUTPOST_ATT_NK_PU;
                                 }
                             }
                         }
                         else
                         {
                             if ((square & board.queens) != 0)
                             {
                                 material[color] += QUEEN;
                                 center[color] += queenIndexValue[pcsqIndex];
                                 mobility[color] += QUEEN_M * BitboardUtils.PopCount(pieceAttacks & ~mines & ~otherPawnAttacks
                                     );
                                 if ((pieceAttacks & squaresNearKing[1 - color] & ~otherPawnAttacks) != 0)
                                 {
                                     kingSafety[color] += QUEEN_ATTACKS_KING;
                                     kingAttackersCount[color]++;
                                 }
                                 if ((pieceAttacks & squaresNearKing[color]) != 0)
                                 {
                                     kingDefense[color] += QUEEN_DEFENDS_KING;
                                 }
                                 if ((pieceAttacks & others & ~otherPawnAttacks) != 0)
                                 {
                                     attacks[color] += QUEEN_ATTACKS_PU;
                                 }
                                 pieceAttacksXray = (bbAttacks.GetRookAttacks(index, all & ~(pieceAttacks & others
                                     )) | bbAttacks.GetBishopAttacks(index, all & ~(pieceAttacks & others))) & ~pieceAttacks;
                                 if ((pieceAttacksXray & board.kings & others) != 0)
                                 {
                                     attacks[color] += PINNED_PIECE;
                                 }
                                 auxLong = (isWhite ? BitboardUtils.b_u : BitboardUtils.b_d);
                                 auxLong2 = (isWhite ? BitboardUtils.r2_u : BitboardUtils.r2_d);
                                 if ((square & auxLong2) != 0 && (others & (board.kings | board.pawns) & (auxLong
                                     | auxLong2)) != 0)
                                 {
                                     attacks[color] += QUEEN_7_KP_78;
                                     if ((board.rooks & mines & auxLong2 & pieceAttacks) != 0 && (board.kings & others
                                          & auxLong) != 0)
                                     {
                                         positional[color] += QUEEN_7_P_78_K_8_R_7;
                                     }
                                 }
                             }
                             else
                             {
                                 if ((square & board.kings) != 0)
                                 {
                                     center[color] += kingIndexValue[pcsqIndex];
                                     // If king is in the first rank, we add the pawn shield
                                     if ((square & (isWhite ? BitboardUtils.RANK[0] : BitboardUtils.RANK[7])) != 0)
                                     {
                                         kingDefense[color] += KING_PAWN_SHIELD * BitboardUtils.PopCount(pieceAttacks & mines
                                              & board.pawns);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
         square <<= 1;
         index++;
     }
     // Ponder opening and Endgame value depending of the non-pawn pieces:
     // opening=> gamephase = 255 / ending => gamephase ~= 0
     int gamePhase = ((material[0] + material[1]) << 8) / 5000;
     if (gamePhase > 256)
     {
         gamePhase = 256;
     }
     // Security
     int value = 0;
     // First Material
     value += pawnMaterial[0] - pawnMaterial[1] + material[0] - material[1];
     // Tempo
     value += (board.GetTurn() ? TEMPO : -TEMPO);
     int oe = config.GetEvalCenter() * (center[0] - center[1]) + config.GetEvalPositional
         () * (positional[0] - positional[1]) + config.GetEvalAttacks() * (attacks[0] - attacks
         [1]) + config.GetEvalMobility() * (mobility[0] - mobility[1]) + config.GetEvalPawnStructure
         () * (pawnStructure[0] - pawnStructure[1]) + config.GetEvalPassedPawns() * (passedPawns
         [0] - passedPawns[1]) + config.GetEvalKingSafety() * (kingDefense[0] - kingDefense
         [1]) + config.GetEvalKingSafety() * (KING_SAFETY_PONDER[kingAttackersCount[0]] *
          kingSafety[0] - KING_SAFETY_PONDER[kingAttackersCount[1]] * kingSafety[1]) + config
         .GetEvalAttacks() * ((BitboardUtils.PopCount(superiorPieceAttacked[0]) >= 2 ? HUNG_PIECES
          : 0) - (BitboardUtils.PopCount(superiorPieceAttacked[1]) >= 2 ? HUNG_PIECES : 0
         ));
     value += (gamePhase * O(oe)) / (256 * 100);
     // divide by 256
     value += ((256 - gamePhase) * E(oe)) / (256 * 100);
     if (debug)
     {
         logger.Debug("\n" + board.ToString());
         logger.Debug(board.GetFen());
         logger.Debug("materialValue          = " + (material[0] - material[1]));
         logger.Debug("pawnMaterialValue      = " + (pawnMaterial[0] - pawnMaterial[1]));
         logger.Debug("centerOpening          = " + O(center[0] - center[1]));
         logger.Debug("centerEndgame          = " + E(center[0] - center[1]));
         logger.Debug("positionalOpening      = " + O(positional[0] - positional[1]));
         logger.Debug("positionalEndgame      = " + E(positional[0] - positional[1]));
         logger.Debug("attacksO 				 = " + O(attacks[0] - attacks[1]));
         logger.Debug("attacksE 				 = " + E(attacks[0] - attacks[1]));
         logger.Debug("mobilityO              = " + O(mobility[0] - mobility[1]));
         logger.Debug("mobilityE              = " + E(mobility[0] - mobility[1]));
         logger.Debug("pawnsO                 = " + O(pawnStructure[0] - pawnStructure[1])
             );
         logger.Debug("pawnsE                 = " + E(pawnStructure[0] - pawnStructure[1])
             );
         logger.Debug("passedPawnsO           = " + O(passedPawns[0] - passedPawns[1]));
         logger.Debug("passedPawnsE           = " + E(passedPawns[0] - passedPawns[1]));
         logger.Debug("kingSafetyValueO       = " + O(KING_SAFETY_PONDER[kingAttackersCount
             [0]] * kingSafety[0] - KING_SAFETY_PONDER[kingAttackersCount[1]] * kingSafety[1]
             ));
         logger.Debug("kingSafetyValueE       = " + E(KING_SAFETY_PONDER[kingAttackersCount
             [0]] * kingSafety[0] - KING_SAFETY_PONDER[kingAttackersCount[1]] * kingSafety[1]
             ));
         logger.Debug("kingDefenseO           = " + O(kingDefense[0] - kingDefense[1]));
         logger.Debug("kingDefenseE           = " + E(kingDefense[0] - kingDefense[1]));
         logger.Debug("HungPiecesO 		     = " + O((BitboardUtils.PopCount(superiorPieceAttacked
             [0]) >= 2 ? HUNG_PIECES : 0) - (BitboardUtils.PopCount(superiorPieceAttacked[1])
              >= 2 ? HUNG_PIECES : 0)));
         logger.Debug("HungPiecesE 		     = " + O((BitboardUtils.PopCount(superiorPieceAttacked
             [0]) >= 2 ? HUNG_PIECES : 0) - (BitboardUtils.PopCount(superiorPieceAttacked[1])
              >= 2 ? HUNG_PIECES : 0)));
         logger.Debug("gamePhase              = " + gamePhase);
         logger.Debug("tempo                  = " + (board.GetTurn() ? TEMPO : -TEMPO));
         logger.Debug("value                  = " + value);
     }
     return value;
 }
Exemplo n.º 2
0
 // D5
 //        logger.debug("***PAWN");
 //        printPcsq(pawnIndexValue);
 //        logger.debug("***KNIGHT");
 //        printPcsq(knightIndexValue);
 //        logger.debug("***BISHOP");
 //        printPcsq(bishopIndexValue);
 //        logger.debug("***ROOK");
 //        printPcsq(rookIndexValue);
 //        logger.debug("***QUEEN");
 //        printPcsq(queenIndexValue);
 //        logger.debug("***KING");
 //        printPcsq(kingIndexValue);
 //        logger.debug("PCSQ tables generated");
 //    private static void printPcsq(int pcsq[][]) {
 //        StringBuffer sb = new StringBuffer();
 //        for (int k=0; k<2; k++) {
 //            if (k==0) sb.append("Opening:\n");
 //            else sb.append("Endgame:\n");
 //            for (int i = 0; i<64; i++) {
 //                String aux = "     " + pcsq[i][k];
 //                aux = aux.substring(aux.length()-5);
 //                sb.append(aux);
 //                if (i%8 != 7) {
 //                    sb.append(",");
 //                } else {
 //                    sb.append("\n");
 //                }
 //            }
 //        }
 //        logger.debug(sb.toString());
 //    }
 //    int kingDefense[] = {0,0};
 // Squares attackeds by pawns
 // Squares surrounding King
 public override int EvaluateBoard(Board board, int alpha, int beta)
 {
     all = board.GetAll();
     Arrays.Fill(bishopCount, 0);
     Arrays.Fill(superiorPieceAttacked, 0);
     Arrays.Fill(material, 0);
     Arrays.Fill(pawnMaterial, 0);
     Arrays.Fill(mobility, 0);
     Arrays.Fill(attacks, 0);
     Arrays.Fill(center, 0);
     Arrays.Fill(positional, 0);
     Arrays.Fill(kingAttackersCount, 0);
     Arrays.Fill(kingSafety, 0);
     Arrays.Fill(pawnStructure, 0);
     Arrays.Fill(passedPawns, 0);
     // Squares attackeds by pawns
     pawnAttacks[0] = ((board.pawns & board.whites & ~BitboardUtils.b_l) << 9) | ((board
         .pawns & board.whites & ~BitboardUtils.b_r) << 7);
     pawnAttacks[1] = ((long)(((ulong)(board.pawns & board.blacks & ~BitboardUtils.b_r
         )) >> 9)) | ((long)(((ulong)(board.pawns & board.blacks & ~BitboardUtils.b_l)) >>
          7));
     // Squares surrounding King
     squaresNearKing[0] = bbAttacks.king[BitboardUtils.Square2Index(board.whites & board
         .kings)];
     squaresNearKing[1] = bbAttacks.king[BitboardUtils.Square2Index(board.blacks & board
         .kings)];
     // From material imbalances (Larry Kaufmann):
     // A further refinement would be to raise the knight's value by 1/16 and lower the rook's value by 1/8
     // for each pawn above five of the side being valued, with the opposite adjustment for each pawn short of five
     int whitePawnsCount = BitboardUtils.PopCount(board.pawns & board.whites);
     int blackPawnsCount = BitboardUtils.PopCount(board.pawns & board.blacks);
     knightKaufBonus[0] = KNIGHT_KAUF_BONUS * (whitePawnsCount - 5);
     knightKaufBonus[1] = KNIGHT_KAUF_BONUS * (blackPawnsCount - 5);
     rookKaufBonus[0] = ROOK_KAUF_BONUS * (whitePawnsCount - 5);
     rookKaufBonus[1] = ROOK_KAUF_BONUS * (blackPawnsCount - 5);
     square = 1;
     index = 0;
     while (square != 0)
     {
         isWhite = ((board.whites & square) != 0);
         color = (isWhite ? 0 : 1);
         mines = (isWhite ? board.whites : board.blacks);
         others = (isWhite ? board.blacks : board.whites);
         pcsqIndex = (isWhite ? index : 63 - index);
         if ((square & all) != 0)
         {
             int rank = index >> 3;
             int column = 7 - index & 7;
             if ((square & board.pawns) != 0)
             {
                 pawnMaterial[color] += PAWN;
                 center[color] += pawnIndexValue[pcsqIndex];
                 pieceAttacks = (isWhite ? bbAttacks.pawnUpwards[index] : bbAttacks.pawnDownwards[
                     index]);
                 superiorPieceAttacked[color] |= pieceAttacks & others & (board.knights | board.bishops
                      | board.rooks | board.queens);
                 if ((pieceAttacks & squaresNearKing[1 - color]) != 0)
                 {
                     kingSafety[color] += PAWN_ATTACKS_KING;
                 }
                 // Doubled pawn detection
                 if ((BitboardUtils.COLUMN[column] & BitboardUtils.RANKS_FORWARD[color][rank] & board
                     .pawns & mines) != square)
                 {
                     pawnStructure[color] += PAWN_DOUBLED;
                 }
                 // Blocked Pawn
                 //					boolean blocked = ((isWhite ? (square<< 8)  : (square >>> 8)) & others) != 0;
                 //					if (blocked) pawnStructure[color] += PAWN_BLOCKED;
                 // Backwards Pawn
                 //					if (((BitboardUtils.COLUMN[column] | BitboardUtils.COLUMNS_ADJACENTS[column]) & ~BitboardUtils.RANKS_FORWARD[color][rank] & board.pawns & mines) == 0)
                 //						pawnStructure[color] += PAWN_BACKWARD;
                 // Passed Pawn
                 if (((BitboardUtils.COLUMN[column] | BitboardUtils.COLUMNS_ADJACENTS[column]) & (
                     isWhite ? BitboardUtils.RANKS_UPWARDS[rank] : BitboardUtils.RANKS_DOWNWARDS[rank
                     ]) & board.pawns & others) == 0)
                 {
                     passedPawns[color] += PAWN_PASSER[(isWhite ? rank : 7 - rank)];
                     if ((square & pawnAttacks[color]) != 0)
                     {
                         passedPawns[color] += PAWN_PASSER_SUPPORT[(isWhite ? rank : 7 - rank)];
                     }
                     passedPawns[color] += PAWN_PASSER_KING_D[(isWhite ? rank : 7 - rank)] * BitboardUtils
                         .Distance(index, BitboardUtils.Square2Index(board.kings & others));
                 }
                 // Isolated pawn
                 bool isolated = (BitboardUtils.COLUMNS_ADJACENTS[column] & board.pawns & mines) ==
                      0;
                 if (isolated)
                 {
                     pawnStructure[color] += PAWN_ISOLATED;
                 }
                 long auxLong;
                 long auxLong2;
                 bool weak = !isolated && (pawnAttacks[color] & square) == 0;
                 //						&& pcsqIndex >= 24
                 // not defended is weak and only if over rank 2
                 if (weak)
                 {
                     // Can be defended advancing one square
                     auxLong = (isWhite ? bbAttacks.pawnDownwards[color] : bbAttacks.pawnUpwards[color
                         ]) & ~pawnAttacks[1 - color] & ~all;
                     while (auxLong != 0)
                     {
                         // Not attacked by other pawn and empty
                         auxLong2 = BitboardUtils.Lsb(auxLong);
                         auxLong &= ~auxLong2;
                         auxLong2 = isWhite ? (long)(((ulong)auxLong2) >> 8) : auxLong2 << 8;
                         if ((auxLong2 & mines & board.pawns) != 0)
                         {
                             weak = false;
                         }
                         else
                         {
                             // Defended advancing one pawn two squares
                             if ((auxLong2 & all) == 0)
                             {
                                 // empty square
                                 auxLong2 = (isWhite ? (long)(((ulong)auxLong2) >> 8) : auxLong2 << 8);
                                 if (((isWhite ? BitboardUtils.RANK[1] : BitboardUtils.RANK[6]) & auxLong2 & board
                                     .pawns & mines) != 0)
                                 {
                                     weak = false;
                                 }
                             }
                         }
                     }
                     if (weak)
                     {
                         // Can advance to be supported
                         auxLong = (isWhite ? square << 8 : (long)(((ulong)square) >> 8)) & ~pawnAttacks[1
                              - color] & ~all;
                         if (auxLong != 0)
                         {
                             if ((auxLong & pawnAttacks[color]) != 0)
                             {
                                 weak = false;
                             }
                             else
                             {
                                 // Checks advancing two squares if in initial position
                                 if (((isWhite ? BitboardUtils.RANK[1] : BitboardUtils.RANK[6]) & square) != 0)
                                 {
                                     auxLong = (isWhite ? square << 16 : (long)(((ulong)square) >> 16)) & ~pawnAttacks
                                         [1 - color] & ~all;
                                     if ((auxLong & pawnAttacks[color]) != 0)
                                     {
                                         weak = false;
                                     }
                                 }
                             }
                         }
                     }
                 }
                 if (weak)
                 {
                     pawnStructure[color] += PAWN_WEAK;
                 }
             }
             else
             {
                 //					if (weak) {
                 //						System.out.println("weak pawn: \n" + board.toString());
                 //						System.out.println("square: \n" + BitboardUtils.toString(square));
                 //					}
                 if ((square & board.knights) != 0)
                 {
                     material[color] += KNIGHT + knightKaufBonus[color];
                     center[color] += knightIndexValue[pcsqIndex];
                     pieceAttacks = bbAttacks.knight[index];
                     auxInt = BitboardUtils.PopCount(pieceAttacks & ~mines & ~pawnAttacks[1 - color])
                         - KNIGHT_M_UNITS;
                     mobility[color] += KNIGHT_M * auxInt;
                     if ((pieceAttacks & squaresNearKing[color]) != 0)
                     {
                         kingSafety[color] += KNIGHT_ATTACKS_KING;
                         kingAttackersCount[color]++;
                     }
                     superiorPieceAttacked[color] |= pieceAttacks & others & (board.rooks | board.queens
                         );
                     // Knight outpost: no opposite pawns can attack the square and is defended by one of our pawns
                     if (((BitboardUtils.COLUMNS_ADJACENTS[column] & (isWhite ? BitboardUtils.RANKS_UPWARDS
                         [rank] : BitboardUtils.RANKS_DOWNWARDS[rank]) & board.pawns & others) == 0) && (
                         ((isWhite ? bbAttacks.pawnDownwards[index] : bbAttacks.pawnUpwards[index]) & board
                         .pawns & mines) != 0))
                     {
                         positional[color] += KNIGTH_OUTPOST[pcsqIndex];
                     }
                 }
                 else
                 {
                     if ((square & board.bishops) != 0)
                     {
                         material[color] += BISHOP;
                         if (bishopCount[color]++ == 2)
                         {
                             material[color] += BISHOP_PAIR;
                         }
                         center[color] += bishopIndexValue[pcsqIndex];
                         pieceAttacks = bbAttacks.GetBishopAttacks(index, all);
                         auxInt = BitboardUtils.PopCount(pieceAttacks & ~mines & ~pawnAttacks[1 - color])
                             - BISHOP_M_UNITS;
                         mobility[color] += BISHOP_M * auxInt;
                         if ((pieceAttacks & squaresNearKing[1 - color]) != 0)
                         {
                             kingSafety[color] += BISHOP_ATTACKS_KING;
                             kingAttackersCount[color]++;
                         }
                         pieceAttacksXray = bbAttacks.GetBishopAttacks(index, all & ~(pieceAttacks & others
                             )) & ~pieceAttacks;
                         if ((pieceAttacksXray & (board.rooks | board.queens | board.kings) & others) != 0)
                         {
                             attacks[color] += PINNED_PIECE;
                         }
                         superiorPieceAttacked[color] |= pieceAttacks & others & (board.rooks | board.queens
                             );
                         if ((BISHOP_TRAPPING[index] & board.pawns & others) != 0)
                         {
                             mobility[color] += BISHOP_TRAPPED;
                         }
                     }
                     else
                     {
                         if ((square & board.rooks) != 0)
                         {
                             material[color] += ROOK + rookKaufBonus[color];
                             center[color] += rookIndexValue[pcsqIndex];
                             pieceAttacks = bbAttacks.GetRookAttacks(index, all);
                             auxInt = BitboardUtils.PopCount(pieceAttacks & ~mines & ~pawnAttacks[1 - color])
                                 - ROOK_M_UNITS;
                             mobility[color] += ROOK_M * auxInt;
                             pieceAttacksXray = bbAttacks.GetRookAttacks(index, all & ~(pieceAttacks & others)
                                 ) & ~pieceAttacks;
                             if ((pieceAttacksXray & (board.queens | board.kings) & others) != 0)
                             {
                                 attacks[color] += PINNED_PIECE;
                             }
                             if ((pieceAttacks & squaresNearKing[1 - color]) != 0)
                             {
                                 kingSafety[color] += ROOK_ATTACKS_KING;
                                 kingAttackersCount[color]++;
                             }
                             superiorPieceAttacked[color] |= pieceAttacks & others & board.queens;
                             if ((pieceAttacks & mines & (board.rooks)) != 0)
                             {
                                 positional[color] += ROOK_CONNECT;
                             }
                             pieceAttacks = BitboardUtils.COLUMN[column];
                             if ((pieceAttacks & board.pawns) == 0)
                             {
                                 positional[color] += ROOK_COLUMN_OPEN;
                             }
                             else
                             {
                                 if ((pieceAttacks & board.pawns & mines) == 0)
                                 {
                                     positional[color] += ROOK_COLUMN_SEMIOPEN;
                                 }
                             }
                         }
                         else
                         {
                             if ((square & board.queens) != 0)
                             {
                                 center[color] += queenIndexValue[pcsqIndex];
                                 material[color] += QUEEN;
                                 pieceAttacks = bbAttacks.GetRookAttacks(index, all) | bbAttacks.GetBishopAttacks(
                                     index, all);
                                 auxInt = BitboardUtils.PopCount(pieceAttacks & ~mines & ~pawnAttacks[1 - color])
                                     - QUEEN_M_UNITS;
                                 mobility[color] += QUEEN_M * auxInt;
                                 if ((pieceAttacks & squaresNearKing[1 - color]) != 0)
                                 {
                                     kingSafety[color] += QUEEN_ATTACKS_KING;
                                     kingAttackersCount[color]++;
                                 }
                                 pieceAttacksXray = (bbAttacks.GetRookAttacks(index, all & ~(pieceAttacks & others
                                     )) | bbAttacks.GetBishopAttacks(index, all & ~(pieceAttacks & others))) & ~pieceAttacks;
                                 if ((pieceAttacksXray & board.kings & others) != 0)
                                 {
                                     attacks[color] += PINNED_PIECE;
                                 }
                             }
                             else
                             {
                                 if ((square & board.kings) != 0)
                                 {
                                     pieceAttacks = bbAttacks.king[index];
                                     center[color] += kingIndexValue[pcsqIndex];
                                     // TODO
                                     if ((square & (isWhite ? BitboardUtils.RANK[1] : BitboardUtils.RANK[7])) != 0)
                                     {
                                         positional[color] += KING_PAWN_NEAR * BitboardUtils.PopCount(pieceAttacks & mines
                                              & board.pawns);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
         square <<= 1;
         index++;
     }
     // Ponder opening and Endgame value depending of the non-pawn pieces:
     // opening=> gamephase = 255 / ending => gamephase ~= 0
     int gamePhase = ((material[0] + material[1]) << 8) / 5000;
     if (gamePhase > 256)
     {
         gamePhase = 256;
     }
     // Security
     int value = 0;
     // First Material
     value += pawnMaterial[0] - pawnMaterial[1] + material[0] - material[1];
     // Tempo
     value += (board.GetTurn() ? TEMPO : -TEMPO);
     int oe = config.GetEvalCenter() * (center[0] - center[1]) + config.GetEvalPositional
         () * (positional[0] - positional[1]) + config.GetEvalAttacks() * (attacks[0] - attacks
         [1]) + config.GetEvalMobility() * (mobility[0] - mobility[1]) + config.GetEvalPawnStructure
         () * (pawnStructure[0] - pawnStructure[1]) + config.GetEvalPassedPawns() * (passedPawns
         [0] - passedPawns[1]) + (config.GetEvalKingSafety() / 8) * ((KING_SAFETY_PONDER[
         kingAttackersCount[0]] * kingSafety[0] - KING_SAFETY_PONDER[kingAttackersCount[1
         ]] * kingSafety[1])) + config.GetEvalAttacks() * ((BitboardUtils.PopCount(superiorPieceAttacked
         [0]) >= 2 ? HUNG_PIECES : 0) - (BitboardUtils.PopCount(superiorPieceAttacked[1])
          >= 2 ? HUNG_PIECES : 0));
     // Divide by eight
     value += (gamePhase * O(oe)) / (256 * 100);
     // divide by 256
     value += ((256 - gamePhase) * E(oe)) / (256 * 100);
     if (debug)
     {
         logger.Debug("\n" + board.ToString());
         logger.Debug(board.GetFen());
         logger.Debug("materialValue          = " + (material[0] - material[1]));
         logger.Debug("pawnMaterialValue      = " + (pawnMaterial[0] - pawnMaterial[1]));
         logger.Debug("centerOpening          = " + O(center[0] - center[1]));
         logger.Debug("centerEndgame          = " + E(center[0] - center[1]));
         logger.Debug("positionalOpening      = " + O(positional[0] - positional[1]));
         logger.Debug("positionalEndgame      = " + E(positional[0] - positional[1]));
         logger.Debug("attacksO 				 = " + O(attacks[0] - attacks[1]));
         logger.Debug("attacksE 				 = " + E(attacks[0] - attacks[1]));
         logger.Debug("mobilityO              = " + O(mobility[0] - mobility[1]));
         logger.Debug("mobilityE              = " + E(mobility[0] - mobility[1]));
         logger.Debug("pawnsO                 = " + O(pawnStructure[0] - pawnStructure[1])
             );
         logger.Debug("pawnsE                 = " + E(pawnStructure[0] - pawnStructure[1])
             );
         logger.Debug("passedPawnsO           = " + O(passedPawns[0] - passedPawns[1]));
         logger.Debug("passedPawnsE           = " + E(passedPawns[0] - passedPawns[1]));
         logger.Debug("kingSafetyValueO       = " + O(KING_SAFETY_PONDER[kingAttackersCount
             [0]] * kingSafety[0] - KING_SAFETY_PONDER[kingAttackersCount[1]] * kingSafety[1]
             ));
         logger.Debug("kingSafetyValueE       = " + E(KING_SAFETY_PONDER[kingAttackersCount
             [0]] * kingSafety[0] - KING_SAFETY_PONDER[kingAttackersCount[1]] * kingSafety[1]
             ));
         logger.Debug("HungPiecesO 		     = " + O((BitboardUtils.PopCount(superiorPieceAttacked
             [0]) >= 2 ? HUNG_PIECES : 0) - (BitboardUtils.PopCount(superiorPieceAttacked[1])
              >= 2 ? HUNG_PIECES : 0)));
         logger.Debug("HungPiecesE 		     = " + O((BitboardUtils.PopCount(superiorPieceAttacked
             [0]) >= 2 ? HUNG_PIECES : 0) - (BitboardUtils.PopCount(superiorPieceAttacked[1])
              >= 2 ? HUNG_PIECES : 0)));
         logger.Debug("gamePhase              = " + gamePhase);
         logger.Debug("tempo                  = " + (board.GetTurn() ? TEMPO : -TEMPO));
         logger.Debug("value                  = " + value);
     }
     return value;
 }