Ejemplo n.º 1
0
        private UInt32 countFile(
            Int32 nSide, Int32 nFile, Plane qpFile, Plane qpFilePawn, Plane qpFoePawn, Plane qpFoePawnAtx, Plane qpFriendPawnAtx,
            ref PRPFlags fprp, ref Plane qpPassers, ref Plane qpIsolani, ref Plane qpDoubled, ref Plane qpAwkward,
            ref UInt32 uPassers, ref UInt32 uIsolani, ref UInt32 uDoubled, ref UInt32 uAwkward)
        {
            var uFilePawns = 0U;

            for (var qpPawn = qpFilePawn; qpPawn != 0; uFilePawns++)
            {
                var nPawn = RemoveLo(ref qpPawn, out Plane qpFound);
                countPawn(
                    nSide, nFile, nPawn, qpFound, qpFoePawn, qpFoePawnAtx, qpFriendPawnAtx,
                    ref fprp, ref qpPassers, ref qpAwkward, ref uPassers, ref uAwkward);
            }

            if ((qpFile & qpFriendPawnAtx) == 0)
            {
                uIsolani  += uFilePawns;
                qpIsolani |= qpFilePawn;
            }

            if (uFilePawns > 1)
            {
                uDoubled  += uFilePawns - 1; // Avoid double counting the first Doubled Pawn
                qpDoubled |= qpFilePawn;
            }

            return(uFilePawns);
        }
Ejemplo n.º 2
0
        //
        // To be considered "Wrong" a given side must have a Bishop to begin with.
        // Wrong Bishops DO NOT protect the queening square of a Passed Rook Pawn:
        //
        private static Boolean punishWrongBishop(PRPFlags fprp, HiFlags fhi)
        {
            var bWrong =
                ((fhi & HiFlags.Pair) != 0) &&
                ((fprp & PRPFlags.Both) != 0) &&
                ((((fprp & PRPFlags.Lite) != 0) && (fhi & HiFlags.Lite) == 0) ||
                 (((fprp & PRPFlags.Dark) != 0) && (fhi & HiFlags.Dark) == 0));

            return(bWrong);
        }
Ejemplo n.º 3
0
 // Recycle PawnPositions to reduce garbage:
 public void Recycle(Hashcode qHashPawn, PRPFlags fBlackPRP, PRPFlags fWhitePRP,
                     FeatureCounter uBlackCounts, FeatureCounter uWhiteCounts,
                     Plane qpBlackPassers, Plane qpWhitePassers)
 {
     HashPawn     = qHashPawn;
     BlackPRP     = fBlackPRP | PRPFlags.IsValid;
     WhitePRP     = fWhitePRP;
     BlackPassers = qpBlackPassers;
     WhitePassers = qpWhitePassers;
     weighPawnFeatures(out Delta, out Total,
                       uBlackCounts, uWhiteCounts,
                       qpBlackPassers, qpWhitePassers);
 }
Ejemplo n.º 4
0
 public PawnPosition(Hashcode qHashPawn, PRPFlags fBlackPRP, PRPFlags fWhitePRP,
                     FeatureCounter uBlackCounts, FeatureCounter uWhiteCounts,
                     Plane qpBlackPassers, Plane qpWhitePassers)
 {
     HashPawn     = qHashPawn;   // To verify Position Equality
     BlackPRP     = fBlackPRP | PRPFlags.IsValid;
     WhitePRP     = fWhitePRP;
     BlackPassers = qpBlackPassers;
     WhitePassers = qpWhitePassers;
     weighPawnFeatures(out Delta, out Total,
                       uBlackCounts, uWhiteCounts,
                       qpBlackPassers, qpWhitePassers);
 }
Ejemplo n.º 5
0
        private void countPawn(
            Int32 nSide, Int32 nFile, Int32 nPawn, Plane qpFound, Plane qpFoePawn, Plane qpFoePawnAtx, Plane qpFriendPawnAtx,
            ref PRPFlags fprp, ref Plane qpPassers, ref Plane qpAwkward, ref UInt32 uPassers, ref UInt32 uAwkward)
        {
            var(qpFree, qpHelp) = GetFreeHelp(nSide, nPawn);

            if ((qpFree & qpFoePawn) == 0 &&
                (qpFree & qpFoePawnAtx) == 0)
            {
                uPassers++;
                qpPassers |= qpFound;

                //
                // Identify which Bishops would protect the queening square of a Passed Rook Pawn:
                //
                if (nFile == 0)
                {
                    fprp |= nSide == White ? PRPFlags.Lite : PRPFlags.Dark;
                }
                else if (nFile == nFiles - 1)
                {
                    fprp |= nSide == White ? PRPFlags.Dark : PRPFlags.Lite;
                }
            }

            //
            // Awkward Pawn has no Helper, nor possibility of a Helper,
            // and its next square is stopped or guarded by a Foe Pawn.
            //
            if ((qpHelp & qpFriendPawnAtx) == 0)
            {
                var nStop  = nPawn + Parameter[nSide].ShiftRank;
                var qpStop = BIT0 << nStop;

                if ((qpStop & qpFoePawn) != 0 ||
                    (qpStop & qpFoePawnAtx) != 0)
                {
                    uAwkward++;
                    qpAwkward |= qpFound;
                }
            }
        }
Ejemplo n.º 6
0
        //
        // Isolated Files have no intersection with FriendPawnAtx.
        // Pawns are not Free iff Free[sq] & (FoePawnAtx | FoePawn).
        // Pawns are Backward when their Stop Squares are blocked, i.e.,
        // when their Stop Square is either attacked or occupied by a Foe,
        // unless Help[sq] & FriendPawnAtx indicates that they can be helped.
        //
        public FeatureCounter CountPawnFeatures(Int32 nSide, out Plane qpPassers, out PRPFlags fprp)
        {
            fprp = default;             //[Init]
            (BoardSide friend, BoardSide foe) = getSides(nSide == White);
            var qpFriendPawnAtx = friend.PawnA1H8Atx | friend.PawnA8H1Atx;
            var qpFoePawnAtx    = foe.PawnA1H8Atx | foe.PawnA8H1Atx;
            var qpFriend        = friend.Piece;
            var qpFoe           = foe.Piece;
            var qpFriendPawn    = Pawn & qpFriend;
            var qpFoePawn       = Pawn & qpFoe;

#if TestPawnFeatures
            Display();
#endif
            //
            // Outputs:
            //
            var uFriendPawns = 0U;
            var uPassers     = 0U;
            var uIslands     = 0U;
            var uIsolani     = 0U;
            var uDoubled     = 0U;
            var uAwkward     = 0U;

            var qpPawns = qpFriendPawn;
            qpPassers = 0UL;
            Byte vOccupied = 0;
            var  qpIsolani = 0UL;
            var  qpDoubled = 0UL;
            var  qpAwkward = 0UL;

            while (qpFriendPawn != 0)
            {
                var nFound = TZC64(qpFriendPawn);
                var nFile  = x(nFound);
                Debug.Assert((vOccupied & (Byte)(BIT0 << nFile)) == 0, "File Previously Visited", $"File = {nFile}");
                vOccupied |= (Byte)(BIT0 << nFile);
                var qpFile     = File[nFile];
                var qpFilePawn = qpFile & qpFriendPawn;
                qpFriendPawn &= ~qpFilePawn; // Visit each occupied file only once

                UInt32 uFilePawns = countFile(
                    nSide, nFile, qpFile, qpFilePawn, qpFoePawn, qpFoePawnAtx, qpFriendPawnAtx,
                    ref fprp, ref qpPassers, ref qpIsolani, ref qpDoubled, ref qpAwkward,
                    ref uPassers, ref uIsolani, ref uDoubled, ref uAwkward);
                uFriendPawns += uFilePawns;
            }

            Int32?nPrevFile = default;
            var   vFile     = vOccupied;
            while (vFile != 0)
            {
                var nFile = RemoveLo(ref vFile);
                if (!nPrevFile.HasValue || nFile > nPrevFile + 1)
                {
                    uIslands++;
                }
                nPrevFile = nFile;
            }

            var uDivides = uIslands > 0 ? uIslands - 1 : uIslands;

            return(featureCount(
                       nSide, uFriendPawns, uPassers, uDivides, uIsolani, uDoubled, uAwkward,
                       qpPawns, qpPassers, vOccupied, qpIsolani, qpDoubled, qpAwkward));
        }