示例#1
0
        private int kingSafetyKPPart(Position pos)
        {
            ulong key = pos.pawnZobristHash() ^ pos.kingZobristHash();
            KingSafetyHashData ksh = kingSafetyHash[(int)key & (kingSafetyHash.Length - 1)];
            if (ksh.key != key) {
            int score = 0;
            ulong wPawns = pos.pieceTypeBB[Piece.WPAWN];
            ulong bPawns = pos.pieceTypeBB[Piece.BPAWN];
            {
                int safety = 0;
                int halfOpenFiles = 0;
                if (Position.getY(pos.wKingSq) < 2) {
                    ulong shelter = 1UL << Position.getX(pos.wKingSq);
                    shelter |= ((shelter & BitBoard.maskBToHFiles) >> 1) |
                               ((shelter & BitBoard.maskAToGFiles) << 1);
                    shelter <<= 8;
                    safety += 3 * BITS.bitCount(wPawns & shelter);
                    safety -= 2 * BITS.bitCount(bPawns & (shelter | (shelter << 8)));
                    shelter <<= 8;
                    safety += 2 * BITS.bitCount(wPawns & shelter);
                    shelter <<= 8;
                    safety -= BITS.bitCount(bPawns & shelter);

                    ulong wOpen = BitBoard.southFill(shelter) & (~BitBoard.southFill(wPawns)) & 0xff;
                    if (wOpen != 0) {
                        halfOpenFiles += 25 * BITS.bitCount(wOpen & 0xe7);
                        halfOpenFiles += 10 * BITS.bitCount(wOpen & 0x18);
                    }
                    ulong bOpen = BitBoard.southFill(shelter) & (~BitBoard.southFill(bPawns)) & 0xff;
                    if (bOpen != 0) {
                        halfOpenFiles += 25 * BITS.bitCount(bOpen & 0xe7);
                        halfOpenFiles += 10 * BITS.bitCount(bOpen & 0x18);
                    }
                    safety = Math.Min(safety, 8);
                }
                int kSafety = (safety - 9) * 15 - halfOpenFiles;
                score += kSafety;
            }
            {
                int safety = 0;
                int halfOpenFiles = 0;
                if (Position.getY(pos.bKingSq) >= 6) {
                    ulong shelter = 1UL << (56 + Position.getX(pos.bKingSq));
                    shelter |= ((shelter & BitBoard.maskBToHFiles) >> 1) |
                               ((shelter & BitBoard.maskAToGFiles) << 1);
                    shelter >>= 8;
                    safety += 3 * BITS.bitCount(bPawns & shelter);
                    safety -= 2 * BITS.bitCount(wPawns & (shelter | (shelter >> 8)));
                    shelter >>= 8;
                    safety += 2 * BITS.bitCount(bPawns & shelter);
                    shelter >>= 8;
                    safety -= BITS.bitCount(wPawns & shelter);

                    ulong wOpen = BitBoard.southFill(shelter) & (~BitBoard.southFill(wPawns)) & 0xff;
                    if (wOpen != 0) {
                        halfOpenFiles += 25 * BITS.bitCount(wOpen & 0xe7);
                        halfOpenFiles += 10 * BITS.bitCount(wOpen & 0x18);
                    }
                    ulong bOpen = BitBoard.southFill(shelter) & (~BitBoard.southFill(bPawns)) & 0xff;
                    if (bOpen != 0) {
                        halfOpenFiles += 25 * BITS.bitCount(bOpen & 0xe7);
                        halfOpenFiles += 10 * BITS.bitCount(bOpen & 0x18);
                    }
                    safety = Math.Min(safety, 8);
                }
                int kSafety = (safety - 9) * 15 - halfOpenFiles;
                score -= kSafety;
            }
            ksh.key = key;
            ksh.score = score;
            }
            return ksh.score;
        }
示例#2
0
        private int pawnBonus(Position pos)
        {
            ulong key = pos.pawnZobristHash();
            PawnHashData phd = pawnHash[(int)key & (pawnHash.Length - 1)];
            if (phd.key != key)
            computePawnHashData(pos, phd);
            int score = phd.score;

            int hiMtrl = qV + rV;
            score += interpolate(pos.bMtrl - pos.bMtrlPawns, 0, 2 * phd.passedBonusW, hiMtrl, phd.passedBonusW);
            score -= interpolate(pos.wMtrl - pos.wMtrlPawns, 0, 2 * phd.passedBonusB, hiMtrl, phd.passedBonusB);

            // Passed pawns are more dangerous if enemy king is far away
            int mtrlNoPawns;
            int highMtrl = qV + rV;
            ulong m = phd.passedPawnsW;
            if (m != 0) {
            mtrlNoPawns = pos.bMtrl - pos.bMtrlPawns;
            if (mtrlNoPawns < highMtrl) {
                int kingPos = pos.getKingSq(false);
                int kingX = Position.getX(kingPos);
                int kingY = Position.getY(kingPos);
                while (m != 0) {
                    int sq = BitBoard.numberOfTrailingZeros(m);
                    int x = Position.getX(sq);
                    int y = Position.getY(sq);
                    int pawnDist = Math.Min(5, 7 - y);
                    int kingDistX = Math.Abs(kingX - x);
                    int kingDistY = Math.Abs(kingY - 7);
                    int kingDist = Math.Max(kingDistX, kingDistY);
                    int kScore = kingDist * 4;
                    if (kingDist > pawnDist) kScore += (kingDist - pawnDist) * (kingDist - pawnDist);
                    score += interpolate(mtrlNoPawns, 0, kScore, highMtrl, 0);
                    if (!pos.whiteMove)
                        kingDist--;
                    if ((pawnDist < kingDist) && (mtrlNoPawns == 0))
                        score += 500; // King can't stop pawn
                    m &= m-1;
                }
            }
            }
            m = phd.passedPawnsB;
            if (m != 0) {
            mtrlNoPawns = pos.wMtrl - pos.wMtrlPawns;
            if (mtrlNoPawns < highMtrl) {
                int kingPos = pos.getKingSq(true);
                int kingX = Position.getX(kingPos);
                int kingY = Position.getY(kingPos);
                while (m != 0) {
                    int sq = BitBoard.numberOfTrailingZeros(m);
                    int x = Position.getX(sq);
                    int y = Position.getY(sq);
                    int pawnDist = Math.Min(5, y);
                    int kingDistX = Math.Abs(kingX - x);
                    int kingDistY = Math.Abs(kingY - 0);
                    int kingDist = Math.Max(kingDistX, kingDistY);
                    int kScore = kingDist * 4;
                    if (kingDist > pawnDist) kScore += (kingDist - pawnDist) * (kingDist - pawnDist);
                    score -= interpolate(mtrlNoPawns, 0, kScore, highMtrl, 0);
                    if (pos.whiteMove)
                        kingDist--;
                    if ((pawnDist < kingDist) && (mtrlNoPawns == 0))
                        score -= 500; // King can't stop pawn
                    m &= m-1;
                }
            }
            }

            return score;
        }
示例#3
0
        /** Compute pawn hash data for pos. */
        private void computePawnHashData(Position pos, PawnHashData ph)
        {
            int score = 0;

            // Evaluate double pawns and pawn islands
            ulong wPawns = pos.pieceTypeBB[Piece.WPAWN];
            ulong wPawnFiles = BitBoard.southFill(wPawns) & 0xff;
            int wDouble = BITS.bitCount(wPawns) - BITS.bitCount(wPawnFiles);
            int wIslands = BITS.bitCount(((~wPawnFiles) >> 1) & wPawnFiles);
            int wIsolated = BITS.bitCount(~(wPawnFiles<<1) & wPawnFiles & ~(wPawnFiles>>1));

            ulong bPawns = pos.pieceTypeBB[Piece.BPAWN];
            ulong bPawnFiles = BitBoard.southFill(bPawns) & 0xff;
            int bDouble = BITS.bitCount(bPawns) - BITS.bitCount(bPawnFiles);
            int bIslands = BITS.bitCount(((~bPawnFiles) >> 1) & bPawnFiles);
            int bIsolated = BITS.bitCount(~(bPawnFiles<<1) & bPawnFiles & ~(bPawnFiles>>1));

            score -= (wDouble - bDouble) * 25;
            score -= (wIslands - bIslands) * 15;
            score -= (wIsolated - bIsolated) * 15;

            // Evaluate backward pawns, defined as a pawn that guards a friendly pawn,
            // can't be guarded by friendly pawns, can advance, but can't advance without
            // being captured by an enemy pawn.
            ulong wPawnAttacks = (((wPawns & BitBoard.maskBToHFiles) << 7) |
                             ((wPawns & BitBoard.maskAToGFiles) << 9));
            ulong bPawnAttacks = (((bPawns & BitBoard.maskBToHFiles) >> 9) |
                             ((bPawns & BitBoard.maskAToGFiles) >> 7));
            ulong wBackward = wPawns & ~((wPawns | bPawns) >> 8) & (bPawnAttacks >> 8) &
                         ~BitBoard.northFill(wPawnAttacks);
            wBackward &= (((wPawns & BitBoard.maskBToHFiles) >> 9) |
                      ((wPawns & BitBoard.maskAToGFiles) >> 7));
            wBackward &= ~BitBoard.northFill(bPawnFiles);
            ulong bBackward = bPawns & ~((wPawns | bPawns) << 8) & (wPawnAttacks << 8) &
                         ~BitBoard.southFill(bPawnAttacks);
            bBackward &= (((bPawns & BitBoard.maskBToHFiles) << 7) |
                      ((bPawns & BitBoard.maskAToGFiles) << 9));
            bBackward &= ~BitBoard.northFill(wPawnFiles);
            score -= (BITS.bitCount(wBackward) - BITS.bitCount(bBackward)) * 15;

            // Evaluate passed pawn bonus, white
            ulong passedPawnsW = wPawns & ~BitBoard.southFill(bPawns | bPawnAttacks | (wPawns >> 8));
            int[] ppBonus = {-1,24,26,30,36,47,64,-1};
            int passedBonusW = 0;
            if (passedPawnsW != 0) {
            ulong guardedPassedW = passedPawnsW & (((wPawns & BitBoard.maskBToHFiles) << 7) |
                                                  ((wPawns & BitBoard.maskAToGFiles) << 9));
            passedBonusW += 15 * BITS.bitCount(guardedPassedW);
            ulong m = passedPawnsW;
            while (m != 0) {
                int sq = /*long.numberOfTrailingZeros(m) */  BitBoard.numberOfTrailingZeros(m);
                int y = Position.getY(sq);
                passedBonusW += ppBonus[y];
                m &= m-1;
            }
            }

            // Evaluate passed pawn bonus, black
            ulong passedPawnsB = bPawns & ~BitBoard.northFill(wPawns | wPawnAttacks | (bPawns << 8));
            int passedBonusB = 0;
            if (passedPawnsB != 0) {
            ulong guardedPassedB = passedPawnsB & (((bPawns & BitBoard.maskBToHFiles) >> 9) |
                                                  ((bPawns & BitBoard.maskAToGFiles) >> 7));
            passedBonusB += 15 * BITS.bitCount(guardedPassedB);
            ulong m = passedPawnsB;
            while (m != 0) {
                int sq = /*long.numberOfTrailingZeros(m) */  BitBoard.numberOfTrailingZeros(m);
                int y = Position.getY(sq);
                passedBonusB += ppBonus[7-y];
                m &= m-1;
            }
            }

            // Connected passed pawn bonus. Seems logical but doesn't help in tests
            //        if (passedPawnsW != 0)
            //            passedBonusW += 15 * BITS.bitCount(passedPawnsW & ((passedPawnsW & BitBoard.maskBToHFiles) >> 1));
            //        if (passedPawnsB != 0)
            //            passedBonusB += 15 * BITS.bitCount(passedPawnsB & ((passedPawnsB & BitBoard.maskBToHFiles) >> 1));

            ph.key = pos.pawnZobristHash();
            ph.score = score;
            ph.passedBonusW = (short)passedBonusW;
            ph.passedBonusB = (short)passedBonusB;
            ph.passedPawnsW = passedPawnsW;
            ph.passedPawnsB = passedPawnsB;
        }