mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 00:33:09 +00: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:
parent
a8abba0b4d
commit
9c7dc057d1
2 changed files with 33 additions and 41 deletions
|
@ -879,6 +879,25 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
|||
// Update king attacks used for fast check detection
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -994,6 +1013,8 @@ void Position::do_null_move(StateInfo& newSt) {
|
|||
|
||||
set_check_info(st);
|
||||
|
||||
st->repetition = 0;
|
||||
|
||||
assert(pos_is_ok());
|
||||
}
|
||||
|
||||
|
@ -1117,24 +1138,10 @@ bool Position::is_draw(int ply) const {
|
|||
if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
|
||||
return true;
|
||||
|
||||
int end = std::min(st->rule50, st->pliesFromNull);
|
||||
|
||||
if (end < 4)
|
||||
return false;
|
||||
|
||||
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 a draw score if a position repeats once earlier but strictly
|
||||
// after the root, or repeats twice before or at the root.
|
||||
if (st->repetition && st->repetition < ply)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1146,26 +1153,15 @@ bool Position::is_draw(int ply) const {
|
|||
bool Position::has_repeated() const {
|
||||
|
||||
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 (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);
|
||||
if (stc->repetition)
|
||||
return true;
|
||||
|
||||
stc = stc->previous;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1212,13 +1208,8 @@ bool Position::has_game_cycle(int ply) const {
|
|||
continue;
|
||||
|
||||
// For repetitions before or at the root, require one more
|
||||
StateInfo* next_stp = stp;
|
||||
for (int k = i + 2; k <= end; k += 2)
|
||||
{
|
||||
next_stp = next_stp->previous->previous;
|
||||
if (next_stp->key == stp->key)
|
||||
return true;
|
||||
}
|
||||
if (stp->repetition)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ struct StateInfo {
|
|||
Square epSquare;
|
||||
|
||||
// Not copied when making a move (will be recomputed anyhow)
|
||||
int repetition;
|
||||
Key key;
|
||||
Bitboard checkersBB;
|
||||
Piece capturedPiece;
|
||||
|
|
Loading…
Add table
Reference in a new issue