反復局面(Repetitions)は、探索中に同じ局面が繰り返し現れる現象である。 将棋では特に千日手判定に直結するため、探索実装で重要である。
探索では、手順を進めていくうちに以前と同じ局面へ戻ることがある。 このとき、
が同じなら、将棋では同一局面として扱う。
探索器はこれを検出して、
などを判断する必要がある。
典型的には、手順履歴に沿ってゾブリストハッシュのキーを並べておき、 同じキーが過去に出てきたかを確認する。
bool isRepetition(const std::vector<uint64_t>& history, uint64_t currentKey) {
for (int i = (int)history.size() - 4; i >= 0; i -= 2) {
if (history[i] == currentKey) {
return true;
}
}
return false;
}
同じ手番で比較するため、2 手ずつさかのぼる形が使われることが多い。
チェスでは三fold repetition だが、将棋では千日手の扱いが異なる。 特に重要なのは、
である。
そのため、単に「同じ局面が出たら引き分け値」とするだけでは不十分で、 将棋ルールに合わせた判定が必要になる。
反復局面を検出したら、
などを返す実装が考えられる。
ここは GUI や大会ルールとの整合も重要である。
将棋では、受けを続けると同じ局面へ戻ることが比較的起こりやすい。 また、詰み回避や王手ラッシュの探索では、反復検出がないと無限ループ的な挙動になりやすい。
そのため、
を組み合わせた実装が重要である。