mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-20 17:16:33 +08:00
Precompute repetition info (#2132)
Store repetition info in StateInfo instead of recomputing it in three different places. This saves some work in has_game_cycle() where this info is needed for positions before the root. Tested for non-regression at STC: LLR: 2.95 (-2.94,2.94) [-3.00,1.00] Total: 34104 W: 7586 L: 7489 D: 19029 http://tests.stockfishchess.org/tests/view/5cd0676e0ebc5925cf044b56 No functional change.
This commit is contained in:
committed by
Marco Costalba
parent
a8abba0b4d
commit
9c7dc057d1
@@ -879,6 +879,25 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
|||||||
// Update king attacks used for fast check detection
|
// Update king attacks used for fast check detection
|
||||||
set_check_info(st);
|
set_check_info(st);
|
||||||
|
|
||||||
|
// Calculate the repetition info. It is the ply distance from the previous
|
||||||
|
// occurrence of the same position, negative in the 3-fold case, or zero
|
||||||
|
// if the position was not repeated.
|
||||||
|
st->repetition = 0;
|
||||||
|
int end = std::min(st->rule50, st->pliesFromNull);
|
||||||
|
if (end >= 4)
|
||||||
|
{
|
||||||
|
StateInfo* stp = st->previous->previous;
|
||||||
|
for (int i=4; i <= end; i += 2)
|
||||||
|
{
|
||||||
|
stp = stp->previous->previous;
|
||||||
|
if (stp->key == st->key)
|
||||||
|
{
|
||||||
|
st->repetition = stp->repetition ? -i : i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(pos_is_ok());
|
assert(pos_is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -994,6 +1013,8 @@ void Position::do_null_move(StateInfo& newSt) {
|
|||||||
|
|
||||||
set_check_info(st);
|
set_check_info(st);
|
||||||
|
|
||||||
|
st->repetition = 0;
|
||||||
|
|
||||||
assert(pos_is_ok());
|
assert(pos_is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1117,24 +1138,10 @@ bool Position::is_draw(int ply) const {
|
|||||||
if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
|
if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
int end = std::min(st->rule50, st->pliesFromNull);
|
// Return a draw score if a position repeats once earlier but strictly
|
||||||
|
// after the root, or repeats twice before or at the root.
|
||||||
if (end < 4)
|
if (st->repetition && st->repetition < ply)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
StateInfo* stp = st->previous->previous;
|
|
||||||
int cnt = 0;
|
|
||||||
|
|
||||||
for (int i = 4; i <= end; i += 2)
|
|
||||||
{
|
|
||||||
stp = stp->previous->previous;
|
|
||||||
|
|
||||||
// Return a draw score if a position repeats once earlier but strictly
|
|
||||||
// after the root, or repeats twice before or at the root.
|
|
||||||
if ( stp->key == st->key
|
|
||||||
&& ++cnt + (ply > i) == 2)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1146,26 +1153,15 @@ bool Position::is_draw(int ply) const {
|
|||||||
bool Position::has_repeated() const {
|
bool Position::has_repeated() const {
|
||||||
|
|
||||||
StateInfo* stc = st;
|
StateInfo* stc = st;
|
||||||
while (true)
|
int end = std::min(st->rule50, st->pliesFromNull);
|
||||||
|
while (end-- >= 4)
|
||||||
{
|
{
|
||||||
int i = 4, end = std::min(stc->rule50, stc->pliesFromNull);
|
if (stc->repetition)
|
||||||
|
return true;
|
||||||
if (end < i)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
StateInfo* stp = stc->previous->previous;
|
|
||||||
|
|
||||||
do {
|
|
||||||
stp = stp->previous->previous;
|
|
||||||
|
|
||||||
if (stp->key == stc->key)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
i += 2;
|
|
||||||
} while (i <= end);
|
|
||||||
|
|
||||||
stc = stc->previous;
|
stc = stc->previous;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1212,13 +1208,8 @@ bool Position::has_game_cycle(int ply) const {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// For repetitions before or at the root, require one more
|
// For repetitions before or at the root, require one more
|
||||||
StateInfo* next_stp = stp;
|
if (stp->repetition)
|
||||||
for (int k = i + 2; k <= end; k += 2)
|
return true;
|
||||||
{
|
|
||||||
next_stp = next_stp->previous->previous;
|
|
||||||
if (next_stp->key == stp->key)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ struct StateInfo {
|
|||||||
Square epSquare;
|
Square epSquare;
|
||||||
|
|
||||||
// Not copied when making a move (will be recomputed anyhow)
|
// Not copied when making a move (will be recomputed anyhow)
|
||||||
|
int repetition;
|
||||||
Key key;
|
Key key;
|
||||||
Bitboard checkersBB;
|
Bitboard checkersBB;
|
||||||
Piece capturedPiece;
|
Piece capturedPiece;
|
||||||
|
|||||||
Reference in New Issue
Block a user