mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-06 10:53:50 +08:00
clean up code
**Non functional changes:** in search.cpp: - an unnecessary pair of parenthesis in the IIR condition has been removed. - refactored the stalemate trap detection code in movepick.cpp: - use the variables `from`, `to`, `piece`, `pieceType` and `capturedPiece` instead of calling the same functions multiple times in `MovePicker::score()`. - rename `MovePicker::other_piece_types_mobile()`. **Functional changes:** - make sure the processed move is always legal in `MovePicker::other_piece_types_mobile()`. passed non regression STC: https://tests.stockfishchess.org/tests/view/6829da686ec7634154f99faf LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 95680 W: 24962 L: 24820 D: 45898 Ptnml(0-2): 221, 9622, 28025, 9738, 234 Passed non regression LTC: https://tests.stockfishchess.org/tests/view/682a102c6ec7634154f9a086 LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 117666 W: 30065 L: 29957 D: 57644 Ptnml(0-2): 45, 10173, 38291, 10277, 47 Run of 10k games on the stalemate opening book: https://tests.stockfishchess.org/tests/view/682b114e6ec7634154f9aa2d Elo: 0.76 ± 0.9 (95%) LOS: 95.3% Total: 10000 W: 4637 L: 4615 D: 748 Ptnml(0-2): 0, 75, 4828, 97, 0 nElo: 5.83 ± 6.8 (95%) PairsRatio: 1.29 closes https://github.com/official-stockfish/Stockfish/pull/6080 Bench: 2422771
This commit is contained in:
committed by
Joost VandeVondele
parent
347e328fdb
commit
54fb42ddf8
@@ -126,11 +126,11 @@ void MovePicker::score() {
|
|||||||
|
|
||||||
static_assert(Type == CAPTURES || Type == QUIETS || Type == EVASIONS, "Wrong type");
|
static_assert(Type == CAPTURES || Type == QUIETS || Type == EVASIONS, "Wrong type");
|
||||||
|
|
||||||
|
Color us = pos.side_to_move();
|
||||||
|
|
||||||
[[maybe_unused]] Bitboard threatenedPieces, threatByLesser[QUEEN + 1];
|
[[maybe_unused]] Bitboard threatenedPieces, threatByLesser[QUEEN + 1];
|
||||||
if constexpr (Type == QUIETS)
|
if constexpr (Type == QUIETS)
|
||||||
{
|
{
|
||||||
Color us = pos.side_to_move();
|
|
||||||
|
|
||||||
threatByLesser[KNIGHT] = threatByLesser[BISHOP] = pos.attacks_by<PAWN>(~us);
|
threatByLesser[KNIGHT] = threatByLesser[BISHOP] = pos.attacks_by<PAWN>(~us);
|
||||||
threatByLesser[ROOK] =
|
threatByLesser[ROOK] =
|
||||||
pos.attacks_by<KNIGHT>(~us) | pos.attacks_by<BISHOP>(~us) | threatByLesser[KNIGHT];
|
pos.attacks_by<KNIGHT>(~us) | pos.attacks_by<BISHOP>(~us) | threatByLesser[KNIGHT];
|
||||||
@@ -143,21 +143,21 @@ void MovePicker::score() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto& m : *this)
|
for (auto& m : *this)
|
||||||
|
{
|
||||||
|
const Square from = m.from_sq();
|
||||||
|
const Square to = m.to_sq();
|
||||||
|
const Piece pc = pos.moved_piece(m);
|
||||||
|
const PieceType pt = type_of(pc);
|
||||||
|
const Piece capturedPiece = pos.piece_on(to);
|
||||||
|
|
||||||
if constexpr (Type == CAPTURES)
|
if constexpr (Type == CAPTURES)
|
||||||
m.value =
|
m.value = (*captureHistory)[pc][to][type_of(capturedPiece)]
|
||||||
7 * int(PieceValue[pos.piece_on(m.to_sq())])
|
+ 7 * int(PieceValue[capturedPiece]) + 1024 * bool(pos.check_squares(pt) & to);
|
||||||
+ 1024 * bool(pos.check_squares(type_of(pos.moved_piece(m))) & m.to_sq())
|
|
||||||
+ (*captureHistory)[pos.moved_piece(m)][m.to_sq()][type_of(pos.piece_on(m.to_sq()))];
|
|
||||||
|
|
||||||
else if constexpr (Type == QUIETS)
|
else if constexpr (Type == QUIETS)
|
||||||
{
|
{
|
||||||
Piece pc = pos.moved_piece(m);
|
|
||||||
PieceType pt = type_of(pc);
|
|
||||||
Square from = m.from_sq();
|
|
||||||
Square to = m.to_sq();
|
|
||||||
|
|
||||||
// histories
|
// histories
|
||||||
m.value = 2 * (*mainHistory)[pos.side_to_move()][m.from_to()];
|
m.value = 2 * (*mainHistory)[us][m.from_to()];
|
||||||
m.value += 2 * (*pawnHistory)[pawn_structure_index(pos)][pc][to];
|
m.value += 2 * (*pawnHistory)[pawn_structure_index(pos)][pc][to];
|
||||||
m.value += (*continuationHistory[0])[pc][to];
|
m.value += (*continuationHistory[0])[pc][to];
|
||||||
m.value += (*continuationHistory[1])[pc][to];
|
m.value += (*continuationHistory[1])[pc][to];
|
||||||
@@ -184,15 +184,15 @@ void MovePicker::score() {
|
|||||||
else // Type == EVASIONS
|
else // Type == EVASIONS
|
||||||
{
|
{
|
||||||
if (pos.capture_stage(m))
|
if (pos.capture_stage(m))
|
||||||
m.value = PieceValue[pos.piece_on(m.to_sq())] + (1 << 28);
|
m.value = PieceValue[capturedPiece] + (1 << 28);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m.value = (*mainHistory)[pos.side_to_move()][m.from_to()]
|
m.value = (*mainHistory)[us][m.from_to()] + (*continuationHistory[0])[pc][to];
|
||||||
+ (*continuationHistory[0])[pos.moved_piece(m)][m.to_sq()];
|
|
||||||
if (ply < LOW_PLY_HISTORY_SIZE)
|
if (ply < LOW_PLY_HISTORY_SIZE)
|
||||||
m.value += 2 * (*lowPlyHistory)[ply][m.from_to()] / (1 + ply);
|
m.value += 2 * (*lowPlyHistory)[ply][m.from_to()] / (1 + ply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the next move satisfying a predicate function.
|
// Returns the next move satisfying a predicate function.
|
||||||
@@ -221,7 +221,6 @@ top:
|
|||||||
case QSEARCH_TT :
|
case QSEARCH_TT :
|
||||||
case PROBCUT_TT :
|
case PROBCUT_TT :
|
||||||
++stage;
|
++stage;
|
||||||
cur = moves + 1;
|
|
||||||
return ttMove;
|
return ttMove;
|
||||||
|
|
||||||
case CAPTURE_INIT :
|
case CAPTURE_INIT :
|
||||||
@@ -237,12 +236,10 @@ top:
|
|||||||
|
|
||||||
case GOOD_CAPTURE :
|
case GOOD_CAPTURE :
|
||||||
if (select([&]() {
|
if (select([&]() {
|
||||||
if (!pos.see_ge(*cur, -cur->value / 18))
|
if (pos.see_ge(*cur, -cur->value / 18))
|
||||||
{
|
return true;
|
||||||
std::swap(*endBadCaptures++, *cur);
|
std::swap(*endBadCaptures++, *cur);
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}))
|
}))
|
||||||
return *(cur - 1);
|
return *(cur - 1);
|
||||||
|
|
||||||
@@ -315,23 +312,17 @@ top:
|
|||||||
|
|
||||||
void MovePicker::skip_quiet_moves() { skipQuiets = true; }
|
void MovePicker::skip_quiet_moves() { skipQuiets = true; }
|
||||||
|
|
||||||
bool MovePicker::other_piece_types_mobile(PieceType pt) {
|
// this function must be called after all quiet moves and captures have been generated
|
||||||
|
bool MovePicker::can_move_king_or_pawn() {
|
||||||
assert(stage == GOOD_QUIET || stage == BAD_QUIET || stage == EVASION);
|
assert(stage == GOOD_QUIET || stage == BAD_QUIET || stage == EVASION);
|
||||||
|
|
||||||
// verify all generated captures and quiets
|
|
||||||
for (ExtMove* m = moves; m < endMoves; ++m)
|
for (ExtMove* m = moves; m < endMoves; ++m)
|
||||||
{
|
{
|
||||||
if (*m && type_of(pos.moved_piece(*m)) != pt)
|
PieceType movedPieceType = type_of(pos.moved_piece(*m));
|
||||||
{
|
if ((movedPieceType == PAWN || movedPieceType == KING) && pos.legal(*m))
|
||||||
if (type_of(pos.moved_piece(*m)) != KING)
|
return true;
|
||||||
return true;
|
|
||||||
if (pos.legal(*m))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovePicker::mark_current_illegal() { *(cur - 1) = Move::none(); }
|
|
||||||
|
|
||||||
} // namespace Stockfish
|
} // namespace Stockfish
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ class MovePicker {
|
|||||||
MovePicker(const Position&, Move, int, const CapturePieceToHistory*);
|
MovePicker(const Position&, Move, int, const CapturePieceToHistory*);
|
||||||
Move next_move();
|
Move next_move();
|
||||||
void skip_quiet_moves();
|
void skip_quiet_moves();
|
||||||
bool other_piece_types_mobile(PieceType pt);
|
bool can_move_king_or_pawn();
|
||||||
void mark_current_illegal();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename Pred>
|
template<typename Pred>
|
||||||
|
|||||||
@@ -910,7 +910,7 @@ Value Search::Worker::search(
|
|||||||
// Step 10. Internal iterative reductions
|
// Step 10. Internal iterative reductions
|
||||||
// For PV nodes without a ttMove as well as for deep enough cutNodes, we decrease depth.
|
// For PV nodes without a ttMove as well as for deep enough cutNodes, we decrease depth.
|
||||||
// (*Scaler) Especially if they make IIR less aggressive.
|
// (*Scaler) Especially if they make IIR less aggressive.
|
||||||
if ((!allNode && depth >= (PvNode ? 5 : 7)) && !ttData.move)
|
if (!allNode && depth >= (PvNode ? 5 : 7) && !ttData.move)
|
||||||
depth--;
|
depth--;
|
||||||
|
|
||||||
// Step 11. ProbCut
|
// Step 11. ProbCut
|
||||||
@@ -1002,10 +1002,8 @@ moves_loop: // When in check, search starts here
|
|||||||
|
|
||||||
// Check for legality
|
// Check for legality
|
||||||
if (!pos.legal(move))
|
if (!pos.legal(move))
|
||||||
{
|
|
||||||
mp.mark_current_illegal();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
// At root obey the "searchmoves" option and skip moves not listed in Root
|
// At root obey the "searchmoves" option and skip moves not listed in Root
|
||||||
// Move List. In MultiPV mode we also skip PV moves that have been already
|
// Move List. In MultiPV mode we also skip PV moves that have been already
|
||||||
// searched and those of lower "TB rank" if we are in a TB root position.
|
// searched and those of lower "TB rank" if we are in a TB root position.
|
||||||
@@ -1074,15 +1072,17 @@ moves_loop: // When in check, search starts here
|
|||||||
int seeHist = std::clamp(captHist / 31, -137 * depth, 125 * depth);
|
int seeHist = std::clamp(captHist / 31, -137 * depth, 125 * depth);
|
||||||
if (!pos.see_ge(move, -158 * depth - seeHist))
|
if (!pos.see_ge(move, -158 * depth - seeHist))
|
||||||
{
|
{
|
||||||
bool skip = true;
|
bool mayStalemateTrap =
|
||||||
if (depth > 2 && !capture && givesCheck && alpha < 0
|
depth > 2 && givesCheck && alpha < 0
|
||||||
&& pos.non_pawn_material(us) == PieceValue[movedPiece]
|
&& !capture // we consider that captures will likely destroy the stalemate configuration
|
||||||
&& PieceValue[movedPiece] >= RookValue
|
&& pos.non_pawn_material(us) == PieceValue[movedPiece]
|
||||||
&& !(PseudoAttacks[KING][pos.square<KING>(us)] & move.from_sq()))
|
&& PieceValue[movedPiece] >= RookValue
|
||||||
// if the opponent captures last mobile piece it might be stalemate
|
// it can't be stalemate if we moved a piece adjacent to the king
|
||||||
skip = mp.other_piece_types_mobile(type_of(movedPiece));
|
&& !(attacks_bb<KING>(pos.square<KING>(us)) & move.from_sq())
|
||||||
|
&& !mp.can_move_king_or_pawn();
|
||||||
|
|
||||||
if (skip)
|
// avoid pruning sacrifices of our last piece for stalemate
|
||||||
|
if (!mayStalemateTrap)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1873,8 +1873,8 @@ void update_all_stats(const Position& pos,
|
|||||||
int moveCount) {
|
int moveCount) {
|
||||||
|
|
||||||
CapturePieceToHistory& captureHistory = workerThread.captureHistory;
|
CapturePieceToHistory& captureHistory = workerThread.captureHistory;
|
||||||
Piece moved_piece = pos.moved_piece(bestMove);
|
Piece movedPiece = pos.moved_piece(bestMove);
|
||||||
PieceType captured;
|
PieceType capturedPiece;
|
||||||
|
|
||||||
int bonus = std::min(143 * depth - 89, 1496) + 302 * (bestMove == ttMove);
|
int bonus = std::min(143 * depth - 89, 1496) + 302 * (bestMove == ttMove);
|
||||||
int malus = std::min(737 * depth - 179, 3141) - 30 * moveCount;
|
int malus = std::min(737 * depth - 179, 3141) - 30 * moveCount;
|
||||||
@@ -1890,8 +1890,8 @@ void update_all_stats(const Position& pos,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Increase stats for the best move in case it was a capture move
|
// Increase stats for the best move in case it was a capture move
|
||||||
captured = type_of(pos.piece_on(bestMove.to_sq()));
|
capturedPiece = type_of(pos.piece_on(bestMove.to_sq()));
|
||||||
captureHistory[moved_piece][bestMove.to_sq()][captured] << bonus * 1213 / 1024;
|
captureHistory[movedPiece][bestMove.to_sq()][capturedPiece] << bonus * 1213 / 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra penalty for a quiet early move that was not a TT move in
|
// Extra penalty for a quiet early move that was not a TT move in
|
||||||
@@ -1902,9 +1902,9 @@ void update_all_stats(const Position& pos,
|
|||||||
// Decrease stats for all non-best capture moves
|
// Decrease stats for all non-best capture moves
|
||||||
for (Move move : capturesSearched)
|
for (Move move : capturesSearched)
|
||||||
{
|
{
|
||||||
moved_piece = pos.moved_piece(move);
|
movedPiece = pos.moved_piece(move);
|
||||||
captured = type_of(pos.piece_on(move.to_sq()));
|
capturedPiece = type_of(pos.piece_on(move.to_sq()));
|
||||||
captureHistory[moved_piece][move.to_sq()][captured] << -malus * 1388 / 1024;
|
captureHistory[movedPiece][move.to_sq()][capturedPiece] << -malus * 1388 / 1024;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user