X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=95e7019b18ccbe2811d9859a2951e9304cbb7172;hp=daf40dec7cc05a9c1b6f336bf9b3bb062d4311e2;hb=ff41b8df764b352b450af572fa98097343b3f808;hpb=c9b24c3358a26afdec5e33e369b6192039562971 diff --git a/src/search.cpp b/src/search.cpp index daf40dec..95e7019b 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -363,27 +363,24 @@ void init_search() { int64_t perft(Position& pos, Depth depth) { - MoveStack mlist[MAX_MOVES]; StateInfo st; - Move m; int64_t sum = 0; // Generate all legal moves - MoveStack* last = generate(pos, mlist); + MoveList ml(pos); // If we are at the last ply we don't need to do and undo // the moves, just to count them. if (depth <= ONE_PLY) - return int(last - mlist); + return ml.size(); // Loop through all legal moves CheckInfo ci(pos); - for (MoveStack* cur = mlist; cur != last; cur++) + for ( ; !ml.end(); ++ml) { - m = cur->move; - pos.do_move(m, st, ci, pos.move_gives_check(m, ci)); + pos.do_move(ml.move(), st, ci, pos.move_gives_check(ml.move(), ci)); sum += perft(pos, depth - ONE_PLY); - pos.undo_move(m); + pos.undo_move(ml.move()); } return sum; } @@ -403,7 +400,7 @@ bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) { NodesSincePoll = 0; current_search_time(get_system_time()); Limits = limits; - TimeMgr.init(Limits, pos.full_moves()); + TimeMgr.init(Limits, pos.startpos_ply_counter()); // Set output steram in normal or chess960 mode cout << set960(pos.is_chess960()); @@ -776,7 +773,6 @@ namespace { // TT value, so we use a different position key in case of an excluded move. excludedMove = ss->excludedMove; posKey = excludedMove ? pos.get_exclusion_key() : pos.get_key(); - tte = TT.probe(posKey); ttMove = tte ? tte->move() : MOVE_NONE; @@ -976,7 +972,7 @@ split_point_start: // At split points actual search starts from here if (move == excludedMove) continue; - // At PV and SpNode nodes we want the moves to be legal + // At PV and SpNode nodes we want all moves to be legal since the beginning if ((PvNode || SpNode) && !pos.pl_move_is_legal(move, ci.pinned)) continue; @@ -1004,14 +1000,14 @@ split_point_start: // At split points actual search starts from here cout << "info" << speed_to_uci(pos.nodes_searched()) << endl; } - // For long searches send to GUI current move + // For long searches send current move info to GUI if (current_search_time() > 2000) cout << "info" << depth_to_uci(depth) << " currmove " << move << " currmovenumber " << moveCount << endl; } // At Root and at first iteration do a PV search on all the moves to score root moves - isPvMove = (PvNode && moveCount <= (RootNode ? depth <= ONE_PLY ? MAX_MOVES : MultiPV : 1)); + isPvMove = (PvNode && moveCount <= (!RootNode ? 1 : depth <= ONE_PLY ? MAX_MOVES : MultiPV)); givesCheck = pos.move_gives_check(move, ci); captureOrPromotion = pos.move_is_capture_or_promotion(move); @@ -1107,13 +1103,12 @@ split_point_start: // At split points actual search starts from here } ss->currentMove = move; + if (!SpNode && !captureOrPromotion) + movesSearched[playedMoveCount++] = move; // Step 14. Make the move pos.do_move(move, st, ci, givesCheck); - if (!SpNode && !captureOrPromotion) - movesSearched[playedMoveCount++] = move; - // Step extra. pv search (only in PV nodes) // The first move in list is the expected PV if (isPvMove) @@ -1124,24 +1119,23 @@ split_point_start: // At split points actual search starts from here // Step 15. Reduced depth search // If the move fails high will be re-searched at full depth. bool doFullDepthSearch = true; - alpha = SpNode ? sp->alpha : alpha; if ( depth > 3 * ONE_PLY && !captureOrPromotion && !dangerous && !move_is_castle(move) && ss->killers[0] != move - && ss->killers[1] != move) + && ss->killers[1] != move + && (ss->reduction = reduction(depth, moveCount)) != DEPTH_ZERO) { - ss->reduction = reduction(depth, moveCount); - if (ss->reduction) - { - Depth d = newDepth - ss->reduction; - value = d < ONE_PLY ? -qsearch(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO) - : - search(pos, ss+1, -(alpha+1), -alpha, d); - doFullDepthSearch = (value > alpha); - } - ss->reduction = DEPTH_ZERO; // Restore original reduction + Depth d = newDepth - ss->reduction; + alpha = SpNode ? sp->alpha : alpha; + + value = d < ONE_PLY ? -qsearch(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO) + : - search(pos, ss+1, -(alpha+1), -alpha, d); + + ss->reduction = DEPTH_ZERO; + doFullDepthSearch = (value > alpha); } // Step 16. Full depth search @@ -1173,29 +1167,23 @@ split_point_start: // At split points actual search starts from here alpha = sp->alpha; } - if (value > bestValue && !(SpNode && thread.cutoff_occurred())) + if (value > bestValue) { bestValue = value; + ss->bestMove = move; - if (SpNode) - sp->bestValue = value; + if ( !RootNode + && PvNode + && value > alpha + && value < beta) // We want always alpha < beta + alpha = value; - if (!RootNode && value > alpha) + if (SpNode && !thread.cutoff_occurred()) { - if (PvNode && value < beta) // We want always alpha < beta - { - alpha = value; - - if (SpNode) - sp->alpha = value; - } - else if (SpNode) - sp->is_betaCutoff = true; - - ss->bestMove = move; - - if (SpNode) - sp->ss->bestMove = move; + sp->bestValue = value; + sp->ss->bestMove = move; + sp->alpha = alpha; + sp->is_betaCutoff = (value >= beta); } } @@ -1216,7 +1204,6 @@ split_point_start: // At split points actual search starts from here if (isPvMove || value > alpha) { // Update PV - ss->bestMove = move; mp.current().pv_score = value; mp.current().extract_pv_from_tt(pos); @@ -1524,7 +1511,7 @@ split_point_start: // At split points actual search starts from here newAtt = pos.attacks_from(pc, to, occ); // Rule 1. Checks which give opponent's king at most one escape square are dangerous - b = kingAtt & ~pos.pieces_of_color(them) & ~newAtt & ~(1ULL << to); + b = kingAtt & ~pos.pieces(them) & ~newAtt & ~(1ULL << to); if (!(b && (b & (b - 1)))) return true; @@ -1535,7 +1522,7 @@ split_point_start: // At split points actual search starts from here return true; // Rule 3. Creating new double threats with checks - b = pos.pieces_of_color(them) & newAtt & ~oldAtt & ~(1ULL << ksq); + b = pos.pieces(them) & newAtt & ~oldAtt & ~(1ULL << ksq); while (b) { @@ -2002,25 +1989,22 @@ split_point_start: // At split points actual search starts from here void RootMoveList::init(Position& pos, Move searchMoves[]) { - MoveStack mlist[MAX_MOVES]; Move* sm; - - clear(); bestMoveChanges = 0; + clear(); // Generate all legal moves and add them to RootMoveList - MoveStack* last = generate(pos, mlist); - for (MoveStack* cur = mlist; cur != last; cur++) + for (MoveList ml(pos); !ml.end(); ++ml) { - // If we have a searchMoves[] list then verify cur->move + // If we have a searchMoves[] list then verify the move // is in the list before to add it. - for (sm = searchMoves; *sm && *sm != cur->move; sm++) {} + for (sm = searchMoves; *sm && *sm != ml.move(); sm++) {} - if (searchMoves[0] && *sm != cur->move) + if (sm != searchMoves && *sm != ml.move()) continue; RootMove rm; - rm.pv[0] = cur->move; + rm.pv[0] = ml.move(); rm.pv[1] = MOVE_NONE; rm.pv_score = -VALUE_INFINITE; push_back(rm);