예제 #1
0
        //
        //[Warning]Duplicate Moves can result in a number of strange, difficult to debug side-effects.
        //
        protected void clearPseudoMoveLists(List <Move> moves, Boolean bSwap) // ~32 MHz
        {
            moves.Clear();
            clearPseudoCaptures();
            clearPseudoMoves();

            PseudoCastles.Clear();
            PseudoEPCapture.Clear();
            PseudoQueenPromotion.Clear();
            PseudoUnderPromotion.Clear();
            PseudoQueenPromotionCapture.Clear();
            PseudoUnderPromotionCapture.Clear();
            PseudoCaptures.Clear();

            if (bSwap)
            {
                PseudoBadCaptures.Clear();
                PseudoGoodCaptures.Clear();
            }
#if !UseMoveSort
            SiftedMoves.Clear();        // See sortMoves()
#endif
        }
예제 #2
0
        protected Int32 sortMoves(List <Move> moves, List <GoodMove> goodMoves, Depth wDepth)
        {
            var nStart = SiftedMoves.Count;

            Trace.Assert(nStart == 0, "nStart != 0");

            var nEarlyCapacity = goodMoves.Count;
            var earlyMoves     = new List <Move>(nEarlyCapacity);

            //
            // goodMoves.Count is not subtracted from moves.Count because there
            // is no guarantee that any of the goodMoves will be found in moves:
            //
            var nMoves    = moves.Count;
            var lateMoves = new List <Move>(nMoves);

            //
            //[Note]The following operations are O(M*N) where N is the number of goodMoves
            //
            // Sift up the elements of "moves" found in goodMoves:
            //
            foreach (var move in moves)
            {
                if (goodMoves.Exists(gm => equalMoves(gm.Move, move)))
                {
                    earlyMoves.Add(move);
                    State.IncEarlyMoveCount(SearchPly); // Update EarlyMove Histogram
                }
                else
                {
                    lateMoves.Add(move);
                }
            }

            var bWTM = WTM();

            foreach (var gm in goodMoves) // Maintain goodMove priority for earlyMoves
            {
#if DebugMove
                unpackMove1(gm.Move, out sq sqFrom, out sq sqTo, out Piece piece, out Piece promotion, out Boolean bCapture);
                //unpackMove2(gm.Move, out sq sqFrom, out sq sqTo, out Piece piece, out Piece promotion, out Piece capture, out Boolean bCastles, out Boolean bCapture);
#endif
#if DebugMoveColor && BottleBothSides
                var bWhiteMove = (gm.Move & Move.WTM) != 0;
                if (bWTM != bWhiteMove)
                {
                    Debug.Assert(bWTM == bWhiteMove, "WTM != WhiteMove [sortMoves]");
                    DisplayCurrent("sortMoves()");
                }
#endif
                //SiftedMoves was cleared in generate() via clearPseudoMoveLists()
                var nIndex = earlyMoves.FindIndex(em => equalMoves(em, gm.Move));
                if (nIndex >= 0)
                {
                    var em = earlyMoves[nIndex];
                    //[Note]goodMoves may contain dupilicates
                    if (!SiftedMoves.Exists(sm => equalMoves(sm, em)))
                    {
#if TestGoodCapture
                        var good = gm.Move & Move.NormalMask;
                        if (good != em)
                        {
                            var goodCaptive = captured(good);
                            var emCaptive   = captured(em);
                            if (emCaptive != Piece.Capture)
                            {
                                var sb = new StringBuilder();
                                sb.AppendAN(good, false);
                                if (goodCaptive != Piece.None)
                                {
                                    sb.Append(goodCaptive);
                                }

                                sb.Append(" != ");
                                sb.AppendAN(em, false);
                                if (emCaptive != Piece.None)
                                {
                                    sb.Append(emCaptive);
                                }

                                sb.FlushLine();
                            }
                            else if (goodCaptive != Piece.Capture)
                            {
                                good &= ~Move.CaptiveMask;
                                good |= (Move)((Byte)Piece.Capture << nCaptiveBit);
                            }
                        }
#endif
                        //
                        //[Warning]It is necessary to Add(em) rather than gm here.
                        //
                        // An em capture will specify either Piece.Capture or Piece.EP; but a Killer gm
                        // can specify a capture from some other position and still match an em capture.
                        //
                        SiftedMoves.Add(em);
                    }
                }
            }

            var nEarly = SiftedMoves.Count;
            State.AddEarlyTotal(bWTM, nEarly);

            SiftedMoves.AddRange(lateMoves);
            var nGenerated = SiftedMoves.Count;

            if (nGenerated != nMoves)
            {
                Debug.Assert(nGenerated == nMoves, "nGenerated != nMoves");
            }

            return(nEarly);
        }