/// Constructors of the MovePicker class. As arguments we pass information
        /// to help it to return the (presumably) good moves first, to decide which
        /// moves to return (in the quiescence search, for instance, we only want to
        /// search captures, promotions and some checks) and how important good move
        /// ordering is at the current node.
        public MovePicker(Position p, Move ttm, Depth d, HistoryStats h, Move[] cm, Move[] fm, Stack s)
        {
            pos     = p;
            history = h;
            depth   = d;

            Debug.Assert(d > DepthS.DEPTH_ZERO);

            cur            = end = 0;
            endBadCaptures = Types.MAX_MOVES - 1;
            countermoves   = cm;
            followupmoves  = fm;
            ss             = s;

            if (p.checkers() != 0)
            {
                stage = StagesS.EVASION;
            }
            else
            {
                stage = StagesS.MAIN_SEARCH;
            }

            ttMove = (ttm != 0 && pos.pseudo_legal(ttm) ? ttm : MoveS.MOVE_NONE);
            end   += ((ttMove != MoveS.MOVE_NONE) ? 1 : 0);
        }
        public MovePicker(Position p, Move ttm, Depth d, HistoryStats h, Square sq)
        {
            pos     = p;
            history = h;
            cur     = 0;
            end     = 0;

            Debug.Assert(d <= DepthS.DEPTH_ZERO);

            if (p.checkers() != 0)
            {
                stage = StagesS.EVASION;
            }

            else if (d > DepthS.DEPTH_QS_NO_CHECKS)
            {
                stage = StagesS.QSEARCH_0;
            }

            else if (d > DepthS.DEPTH_QS_RECAPTURES)
            {
                stage = StagesS.QSEARCH_1;

                // Skip TT move if is not a capture or a promotion. This avoids qsearch
                // tree explosion due to a possible perpetual check or similar rare cases
                // when TT table is full.
                if (ttm != 0 && !pos.capture_or_promotion(ttm))
                {
                    ttm = MoveS.MOVE_NONE;
                }
            }
            else
            {
                stage           = StagesS.RECAPTURE;
                recaptureSquare = sq;
                ttm             = MoveS.MOVE_NONE;
            }

            ttMove = (ttm != 0 && pos.pseudo_legal(ttm) ? ttm : MoveS.MOVE_NONE);
            end   += ((ttMove != MoveS.MOVE_NONE) ? 1 : 0);
        }
        public MovePicker(Position p, Move ttm, HistoryStats h, PieceType pt)
        {
            pos     = p;
            history = h;
            cur     = 0;
            end     = 0;

            Debug.Assert(pos.checkers() == 0);

            stage = StagesS.PROBCUT;

            // In ProbCut we generate only captures that are better than the parent's
            // captured piece.
            captureThreshold = Position.PieceValue[PhaseS.MG][pt];
            ttMove           = (ttm != 0 && pos.pseudo_legal(ttm) ? ttm : MoveS.MOVE_NONE);

            if (ttMove != 0 && (!pos.capture(ttMove) || pos.see(ttMove) <= captureThreshold))
            {
                ttMove = MoveS.MOVE_NONE;
            }

            end += ((ttMove != MoveS.MOVE_NONE) ? 1 : 0);
        }