Carbec wrote: ↑Sat Feb 05, 2022 9:14 amI don't understand why it returns true if only 2 repetitions, and not 3.
Because it's drawish enough in practice. The only downside is if the engine actually has a win after that repeating move, but didn't see it the first time, then it will avoid the whole line. Then again, if it didn't see it the first time, it won't see the win in another try anyway.
Another thing, why not increment index by 4, since we must have the same player to play.
Increment by 2, I think, and yes, that's what I do.
hgm wrote: ↑Sat Feb 05, 2022 10:32 am
Indeed it would be better to lop in steps of 2 through the history.
I just feed all the positions from the history to the TT with a score of 0 and protect them against being overwritten. Because I do a TT lookup anyway checking for repetitions is now free. No loops over the history during the search necessary.
But being able to repeat a history position neither guarantees a draw nor prevents you from still being able to win.
Repeating an already repeated history position does guarantee a draw, so what you could do is put those in the TT as draw.
That is pretty much true for all positions in the tree: playing the move with the worst heuristic evaluation score doen't guarantee a loss, and doesn't prevent you from being able to win. Yet it is more advisable to play the move with the best evaluation score.
Assuming that repeating a position from the game history for the first time is a draw is a very reasonable heuristic. Because you already were in that position, and could not find anything better. And apparently neither could the opponent. Continuing searching it when it occurs in the tree will not allow you to see more that when you searched it as root. (In fact when you have a good TT it would just copy the result from there.) During the game the moves that eventually led to the repeat were already searched better than you can hope to achieve in the repeating node.
hgm wrote: ↑Sat Feb 05, 2022 10:32 am
Indeed it would be better to lop in steps of 2 through the history.
I just feed all the positions from the history to the TT with a score of 0 and protect them against being overwritten. Because I do a TT lookup anyway checking for repetitions is now free. No loops over the history during the search necessary.
But being able to repeat a history position neither guarantees a draw nor prevents you from still being able to win.
Repeating an already repeated history position does guarantee a draw, so what you could do is put those in the TT as draw.
That is pretty much true for all positions in the tree: playing the move with the worst heuristic evaluation score doen't guarantee a loss, and doesn't prevent you from being able to win. Yet it is more advisable to play the move with the best evaluation score.
Assuming that repeating a position from the game history for the first time is a draw is a very reasonable heuristic. Because you already were in that position, and could not find anything better. And apparently neither could the opponent. Continuing searching it when it occurs in the tree will not allow you to see more that when you searched it as root. (In fact when you have a good TT it would just copy the result from there.) During the game the moves that eventually led to the repeat were already searched better than you can hope to achieve in the repeating node.
On modern architectures the rec. throughput of popcnt is 0.25 meaning that one clock cycle can do 4 popcounts for 4 uint64_t registers.
Its an instruction thats as fast as normal addition - but no loop and no branch jump is required.
hgm wrote: ↑Sat Feb 05, 2022 10:32 am
Indeed it would be better to lop in steps of 2 through the history.
I just feed all the positions from the history to the TT with a score of 0 and protect them against being overwritten. Because I do a TT lookup anyway checking for repetitions is now free. No loops over the history during the search necessary.
But being able to repeat a history position neither guarantees a draw nor prevents you from still being able to win.
Repeating an already repeated history position does guarantee a draw, so what you could do is put those in the TT as draw.
That is pretty much true for all positions in the tree: playing the move with the worst heuristic evaluation score doen't guarantee a loss, and doesn't prevent you from being able to win. Yet it is more advisable to play the move with the best evaluation score.
The difference is that other positions in the TT are not stored with infinite depth.
Assuming that repeating a position from the game history for the first time is a draw is a very reasonable heuristic. Because you already were in that position, and could not find anything better. And apparently neither could the opponent.
The opponent may have made a bad move, or the engine may now be able to find a better move since the TT will have more information.
Also, the engine might not even have played the preceding moves.
It doesn't matter whether the stored depth is infinite, or just larger than you need. In both cases you will get a hash cutoff. And when you have seen the position before you would have searched it at larger depth than you want to have now.
hgm wrote: ↑Mon Feb 14, 2022 5:52 pm
I don't understand your last remark.
In engine-engine games, treating a history position as draw will lead to problems only in rare cases. As you pointed out, the engines will normally not see more than what they saw the first time the position was reached.
But the situation is completely different if you give the engine a position with history for analysis, e.g. from a human-human game. Human play is far from optimal, and winning or losing may require repeating a position from the game history. Treating history positions as draws will hide such wins and losses from the engine. This is the situation that leads to bug reports.
I think in general your position tends to be that an engine should not only play sane moves in positions it reaches in its own games but also in positions that are given to it.
syzygy wrote: ↑Sun Feb 20, 2022 1:46 amI think in general your position tends to be that an engine should not only play sane moves in positions it reaches in its own games but also in positions that are given to it.
Then just give the FEN to it, including the 50 moves counter. Problem solved.
Indeed, I was talking purely from the viewpoint of Elo, determined in engine-engine matches. For analysis it could be an issue. The solution suggested by Ras would not always work, because there could be positions in the game history that have been reached twice already, and now have to be avoided when playing for a win. You want to ignore only the positions from the game history that occurred once in that case, not those that occurred twice.