예제 #1
0
        protected Eval storeQXP(Eval mValue, EvalType et,
                                Move moveBest = Move.Undefined)
        {
            Trace.Assert(EvalUndefined < mValue, "storeQXP(EvalUndefined)");
            traceVal("storeQXP", mValue, et); //[Conditional]
            State.IncEvalType(et);
            var mAdjusted = creditMate(mValue, SearchPly);

            if (IsFinal())
            {
                Trace.Assert(!isDefined(moveBest), "moveBest defined in a Final position.");
                moveBest = Move.EmptyMove;
            }
#if DebugMoveColor
            if (isDefinite(moveBest))
            {
                var bWTM       = WTM();
                var bWhiteMove = (moveBest & Move.WTM) != 0;
                if (bWTM != bWhiteMove)
                {
                    Debug.Assert(bWTM == bWhiteMove, "WTM != WhiteMove [storeQXP]");
                    DisplayCurrent("storeQXP()");
                }
            }
#endif
#if QXPHash128
            var store = new QuietPosition(Hash, State.MovePly, HashPawn, mAdjusted, et, moveBest);
#else
            var store = new QuietPosition(Hash, State.MovePly, mAdjusted, et, moveBest);
#endif
            State.QXPTank.Save(store);
            return(mValue);
        }
예제 #2
0
        protected Eval storeXP(Depth wDepth, Eval mValue, EvalType et,
                               Move moveBest     = Move.Undefined,
                               Move moveExcluded = Move.Undefined) // 10 MHz
        {
            Trace.Assert(EvalUndefined < mValue, "storeXP(EvalUndefined)");
            traceVal("storeXP", mValue, et); //[Conditional]
            State.IncEvalType(et);
            var qDynamic  = DynamicHash(moveExcluded);
            var mAdjusted = creditMate(mValue, SearchPly);

            if (IsFinal())
            {
                Trace.Assert(!isDefined(moveBest), "moveBest defined in a Final position.");
                moveBest = Move.EmptyMove;
            }
#if DebugMoveColor
            if (isDefinite(moveBest))
            {
                var bWTM       = WTM();
                var bWhiteMove = (moveBest & Move.WTM) != 0;
                if (bWTM != bWhiteMove)
                {
                    Debug.Assert(bWTM == bWhiteMove, "WTM != WhiteMove [storeXP]");
                    DisplayCurrent("storeXP()");
                }
            }
#endif
#if XPHash128
#if XPMoveTypes
            var store = new Transposition(qDynamic, HashPawn, MoveTypeOrdering, State.MovePly, wDepth,
                                          mAdjusted, et, moveBest);
#else
            var store = new Transposition(qDynamic, HashPawn, State.MovePly, wDepth,
                                          mAdjusted, et, moveBest);
#endif
#else                                   // XPHash128
#if XPMoveTypes
            var store = new Transposition(qDynamic, MoveTypeOrdering, State.MovePly, wDepth,
                                          mAdjusted, et, moveBest);
#else
            var store = new Transposition(qDynamic, State.MovePly, wDepth,
                                          mAdjusted, et, moveBest);
#endif
#endif
            State.XPTank.Save(store);
            return(mValue);
        }
예제 #3
0
        protected Eval storeXPM(Depth wDepth, Eval mValue, EvalType et,
                                Move moveBest     = Move.Undefined,
                                Move moveExcluded = Move.Undefined)     // 10 MHz
        {
            Trace.Assert(EvalUndefined < mValue, "storeXPM(EvalUndefined)");
            traceVal("storeXPM", mValue, et); //[Conditional]
            State.IncEvalType(et);
#if XPMCompositionHash || DebugMoveColor
            var bWTM = WTM();
#endif
#if XPMCompositionHash
            UInt32 wPly      = State.MovePly;
            var    nSide     = bWTM ? 0 : 1;
            var    uMemoHash = compositionHash(bWTM);
            var    qDynamic  = (Hashcode)(uMemoHash * wPly + nSide);
#else
            var qDynamic = DynamicHash(moveExcluded);
#endif
            var mAdjusted = creditMate(mValue, SearchPly);

            if (IsFinal())
            {
                Trace.Assert(!isDefined(moveBest), "moveBest defined in a Final position.");
                moveBest = Move.EmptyMove;
            }
#if DebugMoveColor
            if (isDefinite(moveBest))
            {
                var bWhiteMove = (moveBest & Move.WTM) != 0;
                if (bWTM != bWhiteMove)
                {
                    Debug.Assert(bWTM == bWhiteMove, "WTM != WhiteMove [storeXPM]");
                    DisplayCurrent("storeXPM()");
                }
            }
#endif
#if XPHash128
            var store = new PositionMove(qDynamic, HashPawn, State.MovePly, wDepth,
                                         mAdjusted, et, moveBest);
#else
            var store = new PositionMove(qDynamic, State.MovePly, wDepth,
                                         mAdjusted, et, moveBest);
#endif
            State.XPMTank.Save(store);
            return(mValue);
        }
예제 #4
0
    public Eval Search(Draft wDraft, Eval mAlpha, Eval mBeta,
                       Move moveExcluded = Move.Undefined) {
      var moves = PseudoMoves;
      BestMoves.Clear();                //[Required]

      #region Test for Draw
      if (IsDraw()) {                   //[Note]setDraw50() must be called after tryMove(), below.
        State.IncEvalType(EvalType.Exact);
        return eval();
      }
      #endregion

      #region Test for entry into Quiet Search
      var bInCheck = InCheck();
      if (bInCheck) {                   // Check Extension
        if (extended(ref wDraft, SearchExtensions.Check))
          AtomicIncrement(ref State.CheckExtCount);
      }

      //
      // Depth is tested here, rather than in the PVS recursion case,
      // because search also recurses from the heuristic cases below.
      //
      var wDepth = depth(wDraft);       // InCheck Adjusted Depth
      if (wDepth < 1) {
#if Quiescence
        return quiet(mAlpha, mBeta);
#else
        return boundValue(eval(), mAlpha, mBeta);
#endif
      }
      #endregion

      #region Transposition Table Lookup
#if TraceVal
      var bTrace = IsTrace();
      if (IsTrace()) {                  //[Note]CurrentMove Undefined
        Display($"Search(Depth = {wDepth})");
      }
#endif
      Debug.Assert(mAlpha < mBeta, "Alpha must be less than Beta");

      var goodMoves = new List<GoodMove>(nFirstCapacity);
      var bFoundValue = probeXP(wDepth, mAlpha, mBeta, moveExcluded, goodMoves,
                                out Move moveFound, out Eval mValueFound, out EvalType etFound);
      // Variations updated iff bFoundValue
      if (bFoundValue) {
        // moveFound not always defined for EvalType.Upper [Fail Low]
        if (isDefinite(moveFound)) {    //[Safe]Also prevent unexpected EmptyMove
#if DebugMove
          unpackMove1(moveFound, out sq sqFrom, out sq sqTo, out Piece piece, out Piece promotion, out Boolean bCapture);
          //unpackMove2(moveFound, out sq sqFrom, out sq sqTo, out Piece piece, out Piece promotion, out Piece capture, out Boolean bCastles, out Boolean bCapture);
#endif
          if (IsMovePosition)           // Pass empty BestMoves, at top level
            AddPV(mAlpha, mValueFound, moveFound, BestMoves);
#if AddBestMoves
          BestMoves.Add(moveFound);     // Safe to update BestMoves now
#endif
        }

        return mValueFound;
      }
      #endregion

      #region Heuristic Tests
      var bReduced = (FlagsMode & ModeFlags.Reduced) != 0;
      if (bReduced)
        AtomicIncrement(ref State.ReducedTotal);

      var bTestSingular = false;
      var bPruneQuiet = false;
      var bPVS = (FlagsMode & ModeFlags.ZWS) == 0;
      var bMoveExcluded = isDefined(moveExcluded);
      var wReducedDraft = reduceShallow(wDraft);// Draft for Heuristic Searches

      if (!bInCheck) {
        var mStand = standpatval(mValueFound, etFound);

        if (!bPVS) {
          if (prune(wDraft, wDepth, mAlpha, mBeta, mValueFound, etFound, bMoveExcluded, out Eval mPrunedValue))
            return mPrunedValue;
        }

        if (!bReduced) {
          //[Conditional]
          threat(ref wDraft, ref wReducedDraft, ref wDepth);
        }

        // Determine whether Futility Pruning should be performed at Frontier Nodes:
        if (State.IsFutility && 0 < wDepth) {
          var bNonMateWindow = -MateMin < mAlpha && mBeta < MateMin;
          var bNonEndGame = (FlagsEG & EGFlags.EndGame) == 0;
          if (bNonMateWindow && bNonEndGame) {
            var nMargin = wDepth - 1;
            if (nMargin < FutilityMargin.Length)
              bPruneQuiet = mStand + FutilityMargin[nMargin] <= mAlpha;
          }
        }                               // Futility Pruning

#if SingularExtension
        bTestSingular = wSingularDepthMin <= wDepth &&
                        EvalUndefined < mValueFound &&
                        //[Test]More inclusion performs better than less!
                        Abs(mValueFound) < mQueenWeight &&
                        isDefined(moveFound) && !(bReduced || bMoveExcluded) &&
                        canExtend(vSingular);   //[Ergo]child.canExtend(vSingular) below
#endif
      }                                 // !bInCheck
      #endregion

      #region Generate Moves
      //
      // The "go searchmoves" UCI command sets SearchMoves
      // to restrict the set of candidate moves at the Root:
      //
      if (SearchMoves is not null && SearchMoves.Count > 0) {
        moves.Clear();
        moves.AddRange(SearchMoves);
#if DebugSearchMoves
        var sb = new StringBuilder("SearchMoves:");
        sb.MapMoves(Extension.AppendPACN, moves, State.Rule);
        LogLine(sb.ToString());
#endif
      }
예제 #5
0
        protected Eval quiet(Eval mAlpha, Eval mBeta)
        {
            var moves = PseudoMoves;

            BestMoves.Clear();          //[Required]

            #region Test for Draw
            if (IsDraw())               //[Note]setDraw50() will not be called below
            {
                State.IncEvalType(EvalType.Exact);
#if TransposeQuiet
                return(eval());
#else
                return(boundValue(eval(), mAlpha, mBeta));
#endif
            }
            #endregion

            #region Transposition Table Lookup
#if TraceVal
            var bTrace = IsTrace();
            if (bTrace)
            {
                const String sLabel = "quiet()";
                Display(sLabel);        //[Note]Undefined CurrentMove
            }
#endif
            // BestMoves updated iff bFoundValue
            if (probeQxnt(mAlpha, mBeta, out Move moveFound, out Eval mValueFound, out EvalType etFound))
            {
                // moveFound not always defined for EvalType.Upper [Fail Low]
                if (isDefinite(moveFound)) //[Safe]Also prevent unexpected EmptyMove
                {
#if DebugMove
                    unpackMove1(moveFound, out sq sqFrom, out sq sqTo, out Piece piece, out Piece promotion, out Boolean bCapture);
                    //unpackMove2(moveFound, out sq sqFrom, out sq sqTo, out Piece piece, out Piece promotion, out Piece capture, out Boolean bCastles, out Boolean bCapture);
#endif
#if AddBestMoves
                    BestMoves.Add(moveFound);
#endif
                }

                return(mValueFound);
            }
            #endregion

            #region Move Loop Initializaton
#if QuietCheck || QuietMate
            var bInCheck = InCheck();
#endif
            var et = EvalType.Upper;    //[Init]Fail Low is the default assumption
                                        // Stand Pat (tests Draw Flags)
            var mStand = standpatval(mValueFound, etFound);

            var moveBest = Move.Undefined; //[Init]
            var mValue   = EvalUndefined;
            var mBest    = EvalUndefined;

            var bStandPat = mAlpha /*+ mStandPatWeight*/ < mStand;
            if (bStandPat)
            {
                mBest = mStand;

                if (mAlpha < mBest)
                {
                    mAlpha = mBest;
                }
            }
            #endregion

            if (mBeta <= mAlpha)
            {
                //[Test]return boundValue(mBest, mAlpha, mBeta);
            }
            else
            {
                #region Generate Moves
                if (SearchMoves is not null && SearchMoves.Count > 0)
                {
                    moves.Clear();
                    moves.AddRange(SearchMoves);
#if DebugSearchMoves
                    var sb = new StringBuilder("SearchMoves:");
                    sb.MapMoves(Extension.AppendPACN, moves, State.Rule);
                    sb.FlushLine();
#endif
                }