Example #1
0
        public CastleRule()
        {
            RuleParameter = new CastleRuleParameter[nSides];
            newCastleRuleSides();

            Clear();
        }
Example #2
0
 private void newCastleRuleSides()
 {
     foreach (var parameter in Parameter)
     {
         var nSide = (Int32)parameter.SideName;
         RuleParameter[nSide] = new CastleRuleParameter(parameter);
     }
 }
Example #3
0
        private Boolean canOOO(
            BoardSide friend, BoardSide foe, CastleRuleParameter friendRule)
        {
            var bLegal = ((friend.FlagsHi & HiFlags.CanOOO) != 0) &&
                         ((friendRule.OOOPath & RankPiece) == 0) &&
                         friendRule.OOOSafe.HasValue &&
                         !isAttacked(foe, friendRule.OOOSafe.Value);

            return(bLegal);
        }
Example #4
0
 //
 //[Chess 960]Certain castling configurations require that both the King and the Rook
 // be removed before either is added back in their new positions.  Orthodox Castling
 // does not require this; but one or even both of the From squares may coincide with
 // the castling partner To square in Chess 960.
 //
 private void rookCastles(BoardSide side, CastleRuleParameter rule, Int32 nTo)
 {
     if (nTo == rule.KingOOTo)
     {
         raisePiece(side, rule, vR6, rule.RookOOFrom.Value);
         lowerPiece(side, vR6, rule.RookOOTo);
     }
     else if (nTo == rule.KingOOOTo)
     {
         raisePiece(side, rule, vR6, rule.RookOOOFrom.Value);
         lowerPiece(side, vR6, rule.RookOOOTo);
     }
 }
Example #5
0
        //
        // Set EP flags only if an EP would be legal
        //
        private void tryEP(
            BoardSide friend, BoardSide foe,
            CastleRuleParameter friendRule, CastleRuleParameter foeRule,
            Int32 nMovedTo, Int32 nEnPassant)
        {
            if (!friend.KingPos.HasValue)
            {
                throw new ArgumentException(nameof(friend.KingPos), "Invalid King Position");
            }

            var vKing         = friend.KingPos.Value;
            var qpCaptureFrom = passed(friend, nEnPassant);

            while (qpCaptureFrom != 0)
            {
                var nCaptureFrom = RemoveLo(ref qpCaptureFrom);

                //
                // Test for legality, were Friend to play EP:
                //
                // 1) Remove the Friend Pawn from its nCaptureFrom square;
                // 2) And place it on the nEnPassant square.
                // 3) Remove the Foe Pawn from its nMovedTo square.
                // 4) Note whether the resulting position would be legal.
                // 5) Restore the Foe Pawn to its nMovedTo square.
                // 6) Remove the Friend Pawn placed on nEnPassant;
                // 7) And restore the Pawn to its nCaptureFrom square.
                // 8) If EP was Legal setEPFile(nEnPassant) and break.
                //
                raisePiece(friend, friendRule, vP6, nCaptureFrom);
                lowerPiece(friend, vP6, nEnPassant);
                //[Speed]Remove Not Needed, because material balance will be restored below.
                raisePiece(foe, foeRule, vP6, nMovedTo);

                //[Note]buildPawnAtx() is not needed to find Ray Checks
                var bLegal =
                    (foe.Piece & DiagPiece & diagAtx(vKing)) == 0 &&
                    (foe.Piece & RectPiece & rectAtx(vKing)) == 0;

                //[Speed]placePiece Not Needed, because a Remove was not performed.
                lowerPiece(foe, vP6, nMovedTo);
                raisePiece(friend, friendRule, vP6, nEnPassant);
                lowerPiece(friend, vP6, nCaptureFrom);

                if (bLegal)
                {
                    setEPFile(nEnPassant);
                    break;
                }
            }
        }
Example #6
0
        protected void addCastles(BoardSide friend, CastleRuleParameter friendRule, BoardSide foe)
        {
            Debug.Assert(!InCheck(), "addCastles() called while InCheck");

            if (canOO(friend, foe, friendRule))
            {
#if DebugMoveColor
                PseudoCastles.Add(Move.WTM | friendRule.OO);
#else
                PseudoCastles.Add(friendRule.OO);
#endif
            }

            if (canOOO(friend, foe, friendRule))
            {
#if DebugMoveColor
                PseudoCastles.Add(Move.WTM | friendRule.OOO);
#else
                PseudoCastles.Add(friendRule.OOO);
#endif
            }
        }
Example #7
0
        protected void removePiece(BoardSide side, CastleRuleParameter rule, Byte vPiece, Int32 nFrom)
        {
            var bLite = raisePiece(side, rule, vPiece, nFrom);

            decSideCount(side, vPiece);

            //
            // Update BishopMask, assuming DiagPiece is up to date
            //
            if (vPiece == vB6)
            {
                var qpBishop = side.Piece & Bishop;

                if (bLite)
                {
                    if ((qpBishop & LiteSquare) == 0)
                    {
                        side.FlagsHi &= ~HiFlags.Lite;
                    }
                }
                else if ((qpBishop & DarkSquare) == 0)
                {
                    side.FlagsHi &= ~HiFlags.Dark;
                }
#if HashPieces
                var u = (UInt32)(side.FlagsHi & HiFlags.Pair) >> nBishopPairBit;
                setTwoBits(ref side.PieceHash, 0, u); // Piece == vHF
#endif
            }
#if HashPieces
            if (vP6 < vPiece && vPiece < vK6)
            {
                var u = nibble(side.Counts >> vPiece * nPerNibble);
                setTwoBits(ref side.PieceHash, vPiece - vHF, u % vMod4);
            }
#endif
        }
Example #8
0
        private Boolean raisePiece(BoardSide side, CastleRuleParameter rule, Byte vPiece, Int32 nFrom)
        {
            hashPiece(side, vPiece, nFrom);
            var qp = BIT0 << nFrom;

#if VerifySquarePiece
            if ((qp & RankPiece) == 0)
            {
                var sb = new StringBuilder($"Square empty where {side.Parameter.SideName} Piece was expected at")
                         .AppendSquares(qp);
                throw new MoveException(sb.ToString());
            }
            else if ((qp & side.Piece) == 0)
            {
                var sb = new StringBuilder($"{side.Parameter.SideName} Piece was expected at")
                         .AppendSquares(qp);
                throw new MoveException(sb.ToString());
            }
#endif
            clrPiece(side, qp);
#if !Magic
            clrRotations(nFrom);
#endif
            var bLite = false;
            switch (vPiece)
            {
            case vP6:
                Pawn &= ~qp;
                break;

            case vR6:
                RectPiece &= ~qp;
                if (nFrom == rule.RookOOFrom)
                {
                    side.FlagsHi &= ~HiFlags.CanOO;
                }
                else if (nFrom == rule.RookOOOFrom)
                {
                    side.FlagsHi &= ~HiFlags.CanOOO;
                }
                break;

            case vN6:
                Knight &= ~qp;
                break;

            case vB6:
                DiagPiece &= ~qp;
                bLite      = (qp & LiteSquare) != 0;
                break;

            case vQ6:
                DiagPiece &= ~qp;
                RectPiece &= ~qp;
                break;

            case vK6:
                King         &= ~qp;
                side.FlagsHi &= ~HiFlags.CanCastleMask;
                break;

            default:
                throw new PieceException("Unexpected Piece [raiseSide]");
            }

            return(bLite);
        }
Example #9
0
        // Capture: ~6.3 MHz, Simple: ~10.5 MHz, Pawn: ~9.5 MHz
        protected void movePiece(
            BoardSide friend, BoardSide foe,
            CastleRuleParameter friendRule, CastleRuleParameter foeRule,
            ref Move move)
        {
            unpack2(move, out Int32 nFrom, out Int32 nTo,
                    out UInt32 uPiece, out UInt32 uPromotion,
                    out Boolean bCastles, out Boolean bCapture);
            var vPiece    = pieceIndex(uPiece);
            var bSupplied = uPromotion > 0;

#if VerifyPromotion                     //[PACN]
            var qpMoveTo  = BIT0 << nTo;
            var bPromote  = (friend.Parameter.RankLast & qpMoveTo) != 0;
            var bRequired = vPiece == vP6 && bPromote;
            Trace.Assert(bRequired == bSupplied, "Invalid Promotion");
#endif
            if (bSupplied)
            {
                removePiece(friend, friendRule, vPiece, nFrom);
            }
            else
            {
                raisePiece(friend, friendRule, vPiece, nFrom);
            }

            if (bCapture)
            {
                HalfMoveClock = 0;      // HalfMoveClock Reset due to Capture
                var vCapture     = captureIndex(nTo, ref move, out Boolean bEnPassant);
                var nCaptureFrom = bEnPassant ? nTo + foe.Parameter.ShiftRank : nTo;
                removePiece(foe, foeRule, vCapture, nCaptureFrom);

                if (vCapture == vP6)
                {
                    resetPawnAtx(foe);
                }
            }
            else if (bCastles)
            {
                rookCastles(friend, friendRule, nTo);
            }

            if (bSupplied)
            {
                placePiece(friend, pieceIndex(uPromotion), nTo);
            }
            else
            {
                lowerPiece(friend, vPiece, nTo);
            }

            if (vPiece == vP6)
            {
                if (nTo - nFrom == 2 * friend.Parameter.ShiftRank)
                {
                    var nEnPassant = nTo - friend.Parameter.ShiftRank;
                    tryEP(foe, friend, foeRule, friendRule, nTo, nEnPassant);
                }

                HalfMoveClock = 0;      // HalfMoveClock Reset due to Pawn Move
                resetPawnAtx(friend);
            }
        }