// 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);
++ int end = captures_to_hand() ? st->pliesFromNull : 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());
}
bool Position::has_repeated() const {
StateInfo* stc = st;
- while (true)
- int end = std::min(st->rule50, st->pliesFromNull);
++ int end = captures_to_hand() ? st->pliesFromNull : 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;
}
int j;
-- int end = std::min(st->rule50, st->pliesFromNull);
++ int end = captures_to_hand() ? st->pliesFromNull : std::min(st->rule50, st->pliesFromNull);
- if (end < 3)
+ if (end < 3 || var->nFoldValue != VALUE_DRAW)
return false;
Key originalKey = st->key;