// //[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 }
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); }