X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsearch.cpp;h=41992efbc55b5625649ecfe380e81775af703356;hb=0cfb30e5be9e66766b3b8e5870b5737b48b1b632;hp=9244ce3dc7bbb8d13402ec25171498229f514216;hpb=a9782b94e640d3a35b597758ff1d5f0e56465666;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index 9244ce3d..41992efb 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -300,7 +300,7 @@ namespace { if (moveIsCheck && pos.see_sign(m) >= 0) result += CheckExtension[PvNode]; - if (type_of_piece(pos.piece_on(move_from(m))) == PAWN) + if (piece_type(pos.piece_on(move_from(m))) == PAWN) { Color c = pos.side_to_move(); if (relative_rank(c, move_to(m)) == RANK_7) @@ -316,7 +316,7 @@ namespace { } if ( captureOrPromotion - && type_of_piece(pos.piece_on(move_to(m))) != PAWN + && piece_type(pos.piece_on(move_to(m))) != PAWN && ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) - piece_value_midgame(pos.piece_on(move_to(m))) == VALUE_ZERO) && !move_is_special(m)) @@ -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; } @@ -736,7 +733,14 @@ namespace { if (PvNode && thread.maxPly < ss->ply) thread.maxPly = ss->ply; - if (SpNode) + // Step 1. Initialize node and poll. Polling can abort search + if (!SpNode) + { + ss->currentMove = ss->bestMove = threatMove = (ss+1)->excludedMove = MOVE_NONE; + (ss+1)->skipNullMove = false; (ss+1)->reduction = DEPTH_ZERO; + (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE; + } + else { sp = ss->sp; tte = NULL; @@ -745,11 +749,6 @@ namespace { goto split_point_start; } - // Step 1. Initialize node and poll. Polling can abort search - ss->currentMove = ss->bestMove = threatMove = (ss+1)->excludedMove = MOVE_NONE; - (ss+1)->skipNullMove = false; (ss+1)->reduction = DEPTH_ZERO; - (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE; - if (pos.thread() == 0 && ++NodesSincePoll > NodesBetweenPolls) { NodesSincePoll = 0; @@ -776,7 +775,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 +974,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 +1002,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 +1105,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 +1121,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 +1169,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 +1206,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,18 +1513,18 @@ 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; // Rule 2. Queen contact check is very dangerous - if ( type_of_piece(pc) == QUEEN + if ( piece_type(pc) == QUEEN && bit_is_set(kingAtt, to)) 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) { @@ -1666,7 +1655,7 @@ split_point_start: // At split points actual search starts from here // value of the threatening piece, don't prune moves which defend it. if ( pos.move_is_capture(threat) && ( piece_value_midgame(pos.piece_on(tfrom)) >= piece_value_midgame(pos.piece_on(tto)) - || type_of_piece(pos.piece_on(tfrom)) == KING) + || piece_type(pos.piece_on(tfrom)) == KING) && pos.move_attacks_square(m, tto)) return true; @@ -2002,25 +1991,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);