@@ -450,9 +450,6 @@ DirtyPiece Position::do_move(Move m,
450450 assert (m.is_ok ());
451451 assert (&newSt != st);
452452
453- // Update the bloom filter
454- ++filter[st->key ];
455-
456453 Key k = st->key ^ Zobrist::side;
457454
458455 // Copy some fields of the old state to our new StateInfo object except the
@@ -585,6 +582,27 @@ DirtyPiece Position::do_move(Move m,
585582 if (tt)
586583 prefetch (tt->first_entry (key ()));
587584
585+ // Calculate the repetition info. It is the ply distance from the first
586+ // occurrence of the same position, or zero if the position was not repeated.
587+ st->repetition = 0 ;
588+ // Restore rule 60 by adding back the checks
589+ int end = std::min (st->rule60 + std::max (0 , st->check10 [WHITE] - 10 )
590+ + std::max (0 , st->check10 [BLACK] - 10 ),
591+ st->pliesFromNull );
592+ if (end >= 4 )
593+ {
594+ StateInfo* stp = st->previous ->previous ;
595+ for (int i = 4 ; i <= end; i += 2 )
596+ {
597+ stp = stp->previous ->previous ;
598+ if (stp->key == st->key )
599+ {
600+ st->repetition = stp->repetition ? -(stp->repetition + i) : i;
601+ break ;
602+ }
603+ }
604+ }
605+
588606 assert (pos_is_ok ());
589607
590608 assert (dp.pc != NO_PIECE);
@@ -621,9 +639,6 @@ void Position::undo_move(Move m) {
621639 st = st->previous ;
622640 --gamePly;
623641
624- // Update the bloom filter
625- --filter[st->key ];
626-
627642 assert (pos_is_ok ());
628643}
629644
@@ -635,9 +650,6 @@ void Position::do_null_move(StateInfo& newSt, const TranspositionTable& tt) {
635650 assert (!checkers ());
636651 assert (&newSt != st);
637652
638- // Update the bloom filter
639- ++filter[st->key ];
640-
641653 std::memcpy (&newSt, st, sizeof (StateInfo));
642654
643655 newSt.previous = st;
@@ -663,9 +675,6 @@ void Position::undo_null_move() {
663675
664676 st = st->previous ;
665677 sideToMove = ~sideToMove;
666-
667- // Update the bloom filter
668- --filter[st->key ];
669678}
670679
671680
@@ -976,65 +985,50 @@ Value Position::detect_chases(int d, int ply) {
976985// perpetual check repetition or perpetual chase repetition that allows a player to claim a game result.
977986bool Position::rule_judge (Value& result, int ply) {
978987
979- // Restore rule 60 by adding back the checks
980- int end = std::min (st->rule60 + std::max (0 , st->check10 [WHITE] - 10 )
981- + std::max (0 , st->check10 [BLACK] - 10 ),
982- st->pliesFromNull );
983-
984- if (end >= 4 && filter[st->key ] >= 1 )
988+ // Return a score if a position repeats once earlier but strictly
989+ // after the root, or repeats twice before or at the root.
990+ if (st->repetition && ply > st->repetition )
985991 {
986- int cnt = 0 ;
992+ int length = std::abs (st-> repetition ) ;
987993 StateInfo* stp = st->previous ->previous ;
988994 bool checkThem = st->checkersBB && stp->checkersBB ;
989995 bool checkUs = st->previous ->checkersBB && stp->previous ->checkersBB ;
990996
991- for (int i = 4 ; i <= end ; i += 2 )
997+ for (int i = 4 ; i <= length ; i += 2 )
992998 {
993999 stp = stp->previous ->previous ;
9941000 checkThem &= bool (stp->checkersBB );
1001+ if (i + 1 <= length)
1002+ checkUs &= bool (stp->previous ->checkersBB );
1003+ }
9951004
996- // Return a score if a position repeats once earlier but strictly
997- // after the root, or repeats twice before or at the root.
998- if (stp->key == st->key && (++cnt == 2 || ply > i))
999- {
1000- if (!checkThem && !checkUs)
1001- {
1002- // Copy the current position to a rollback struct, so we don't need to do those moves again
1003- Position rollback;
1004- memcpy ((void *) &rollback, (const void *) this , offsetof (Position, filter));
1005-
1006- // Chasing detection
1007- result = rollback.detect_chases (i, ply);
1008- }
1009- else
1010- // Checking detection
1011- result = !checkUs ? mate_in (ply) : !checkThem ? mated_in (ply) : VALUE_DRAW;
1005+ if (!checkThem && !checkUs)
1006+ {
1007+ // Copy the current position to a rollback struct, so we don't need to do those moves again
1008+ Position rollback;
1009+ memcpy ((void *) &rollback, (const void *) this , offsetof (Position, idBoard));
10121010
1013- // 3 folds and 2 fold draws can be judged immediately
1014- if (result == VALUE_DRAW || cnt == 2 )
1015- return true ;
1011+ // Chasing detection
1012+ result = rollback.detect_chases (length, ply);
1013+ }
1014+ else
1015+ // Checking detection
1016+ result = !checkUs ? mate_in (ply) : !checkThem ? mated_in (ply) : VALUE_DRAW;
10161017
1017- // 2 fold mates need further investigations
1018- if (filter[st->key ] <= 1 )
1019- {
1020- // Not exceeding rule 60 and have the same previous step
1021- if (st->rule60 < 120 && st->previous ->key == stp->previous ->key )
1022- {
1023- // Even if we entering this loop again, it will not lead to a 3 fold repetition
1024- StateInfo* prev = st->previous ;
1025- while ((prev = prev->previous ) != stp)
1026- if (filter[prev->key ] > 1 )
1027- break ;
1028- if (prev == stp)
1029- return true ;
1030- }
1031- // We know there can't be another fold
1018+ // 3 folds and 2 fold draws can be judged immediately
1019+ if (result == VALUE_DRAW || st->repetition < 0 )
1020+ return true ;
1021+ // 2 fold mates need further investigations
1022+ // Not exceeding rule 60 and have the same previous step
1023+ else if (st->rule60 < 120 && st->previous ->key == stp->previous ->key )
1024+ {
1025+ // Even if we entering this loop again, it will not lead to a 3 fold repetition
1026+ StateInfo* prev = st->previous ;
1027+ while ((prev = prev->previous ) != stp)
1028+ if (prev->repetition )
10321029 break ;
1033- }
1034- }
1035-
1036- if (i + 1 <= end)
1037- checkUs &= bool (stp->previous ->checkersBB );
1030+ if (prev == stp)
1031+ return true ;
10381032 }
10391033 }
10401034
0 commit comments