mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 08:43:09 +00:00
In qsearch store the cut move in TT
And upon reentering the same position try it as first. Normally qsearch moves order is already very good, first move is the cut off in almost 90% of cases. With this patch, we get a cut off on TT move of 98%. Another good side effect is that we don't generate captures and/or checks when we already have a TT move. Unfortunatly we found a TT move only in 1% of cases. So real impact of this patch is relatively low. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
4634be8ba6
commit
e68ebe618c
3 changed files with 14 additions and 25 deletions
|
@ -50,7 +50,6 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////
|
////
|
||||||
//// Functions
|
//// Functions
|
||||||
////
|
////
|
||||||
|
@ -445,9 +444,9 @@ Move MovePicker::pick_move_from_list() {
|
||||||
bestIndex = (movesPicked < 4 ? find_best_index() : movesPicked);
|
bestIndex = (movesPicked < 4 ? find_best_index() : movesPicked);
|
||||||
move = moves[bestIndex].move;
|
move = moves[bestIndex].move;
|
||||||
moves[bestIndex] = moves[movesPicked++];
|
moves[bestIndex] = moves[movesPicked++];
|
||||||
// Remember to change the line below if we decide to hash the qsearch!
|
// Maybe postpone the legality check until after futility pruning?
|
||||||
// Maybe also postpone the legality check until after futility pruning?
|
if ( move != ttMove
|
||||||
if (/* move != ttMove && */ pos.pl_move_is_legal(move, pinned))
|
&& pos.pl_move_is_legal(move, pinned))
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -460,8 +459,8 @@ Move MovePicker::pick_move_from_list() {
|
||||||
while (movesPicked < numOfMoves)
|
while (movesPicked < numOfMoves)
|
||||||
{
|
{
|
||||||
move = moves[movesPicked++].move;
|
move = moves[movesPicked++].move;
|
||||||
// Remember to change the line below if we decide to hash the qsearch!
|
if ( move != ttMove
|
||||||
if (/* move != ttMove && */ pos.pl_move_is_legal(move, pinned))
|
&& pos.pl_move_is_legal(move, pinned))
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -473,20 +472,10 @@ Move MovePicker::pick_move_from_list() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// MovePicker::current_move_type() returns the type of the just
|
|
||||||
/// picked next move. It can be used in search to further differentiate
|
|
||||||
/// according to the current move type: capture, non capture, escape, etc.
|
|
||||||
MovePicker::MovegenPhase MovePicker::current_move_type() const {
|
|
||||||
|
|
||||||
return PhaseTable[phaseIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// MovePicker::init_phase_table() initializes the PhaseTable[],
|
/// MovePicker::init_phase_table() initializes the PhaseTable[],
|
||||||
/// MainSearchPhaseIndex, EvasionPhaseIndex, QsearchWithChecksPhaseIndex
|
/// MainSearchPhaseIndex, EvasionPhaseIndex, QsearchWithChecksPhaseIndex
|
||||||
/// QsearchNoCapturesPhaseIndex, QsearchWithoutChecksPhaseIndex and
|
/// and QsearchWithoutChecksPhaseIndex. It is only called once during
|
||||||
/// NoMovesPhaseIndex variables. It is only called once during program
|
/// program startup, and never again while the program is running.
|
||||||
/// startup, and never again while the program is running.
|
|
||||||
|
|
||||||
void MovePicker::init_phase_table() {
|
void MovePicker::init_phase_table() {
|
||||||
|
|
||||||
|
@ -511,12 +500,14 @@ void MovePicker::init_phase_table() {
|
||||||
|
|
||||||
// Quiescence search with checks
|
// Quiescence search with checks
|
||||||
QsearchWithChecksPhaseIndex = i - 1;
|
QsearchWithChecksPhaseIndex = i - 1;
|
||||||
|
PhaseTable[i++] = PH_TT_MOVE;
|
||||||
PhaseTable[i++] = PH_QCAPTURES;
|
PhaseTable[i++] = PH_QCAPTURES;
|
||||||
PhaseTable[i++] = PH_QCHECKS;
|
PhaseTable[i++] = PH_QCHECKS;
|
||||||
PhaseTable[i++] = PH_STOP;
|
PhaseTable[i++] = PH_STOP;
|
||||||
|
|
||||||
// Quiescence search without checks
|
// Quiescence search without checks
|
||||||
QsearchWithoutChecksPhaseIndex = i - 1;
|
QsearchWithoutChecksPhaseIndex = i - 1;
|
||||||
|
PhaseTable[i++] = PH_TT_MOVE;
|
||||||
PhaseTable[i++] = PH_QCAPTURES;
|
PhaseTable[i++] = PH_QCAPTURES;
|
||||||
PhaseTable[i++] = PH_STOP;
|
PhaseTable[i++] = PH_STOP;
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,6 @@ public:
|
||||||
Move get_next_move(Lock &lock);
|
Move get_next_move(Lock &lock);
|
||||||
int number_of_moves() const;
|
int number_of_moves() const;
|
||||||
int current_move_score() const;
|
int current_move_score() const;
|
||||||
MovegenPhase current_move_type() const;
|
|
||||||
Bitboard discovered_check_candidates() const;
|
Bitboard discovered_check_candidates() const;
|
||||||
|
|
||||||
static void init_phase_table();
|
static void init_phase_table();
|
||||||
|
|
|
@ -1516,6 +1516,7 @@ namespace {
|
||||||
return value_from_tt(tte->value(), ply);
|
return value_from_tt(tte->value(), ply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Move ttMove = (tte ? tte->move() : MOVE_NONE);
|
||||||
|
|
||||||
// Evaluate the position statically
|
// Evaluate the position statically
|
||||||
EvalInfo ei;
|
EvalInfo ei;
|
||||||
|
@ -1559,7 +1560,7 @@ namespace {
|
||||||
// Initialize a MovePicker object for the current position, and prepare
|
// Initialize a MovePicker object for the current position, and prepare
|
||||||
// to search the moves. Because the depth is <= 0 here, only captures,
|
// to search the moves. Because the depth is <= 0 here, only captures,
|
||||||
// queen promotions and checks (only if depth == 0) will be generated.
|
// queen promotions and checks (only if depth == 0) will be generated.
|
||||||
MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth);
|
MovePicker mp = MovePicker(pos, pvNode, ttMove, EmptySearchStack, depth);
|
||||||
Move move;
|
Move move;
|
||||||
int moveCount = 0;
|
int moveCount = 0;
|
||||||
Bitboard dcCandidates = mp.discovered_check_candidates();
|
Bitboard dcCandidates = mp.discovered_check_candidates();
|
||||||
|
@ -1636,22 +1637,20 @@ namespace {
|
||||||
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
||||||
|
|
||||||
// Update transposition table
|
// Update transposition table
|
||||||
|
Move m = ss[ply].pv[ply];
|
||||||
if (!pvNode)
|
if (!pvNode)
|
||||||
{
|
{
|
||||||
Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
|
Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
|
||||||
if (bestValue < beta)
|
if (bestValue < beta)
|
||||||
TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_UPPER);
|
TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_UPPER);
|
||||||
else
|
else
|
||||||
TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_LOWER);
|
TT.store(pos, value_to_tt(bestValue, ply), d, m, VALUE_TYPE_LOWER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update killers only for good check moves
|
// Update killers only for good check moves
|
||||||
Move m = ss[ply].currentMove;
|
|
||||||
if (alpha >= beta && ok_to_history(pos, m)) // Only non capture moves are considered
|
if (alpha >= beta && ok_to_history(pos, m)) // Only non capture moves are considered
|
||||||
{
|
|
||||||
// Wrong to update history when depth is <= 0
|
|
||||||
update_killers(m, ss[ply]);
|
update_killers(m, ss[ply]);
|
||||||
}
|
|
||||||
return bestValue;
|
return bestValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue