鍵只用了每個角色的首字母

三次重複需要一種方法來判斷「這是同一個局面」。Mistboard 把每個局面轉成一個字串,並統計每個字串出現了幾次。

function repetitionKey(position):
    parts = []
    for sq, p in position.pieces (sorted by sq):
        # red chariot on a1: "a1" + "r" + "c"
        parts.append(sq + p.color[0] + p.role[0])
    return position.turn + "|" + join(parts, ",")

after every move:
    seen[repetitionKey(position)] += 1
    if it reaches 3: draw (or a perpetual-check loss)

role[0] 是角色名的首字母,而象棋的七種角色裡有兩種以 c 開頭。a1 上的紅車和 b3 上的紅炮分別寫成 a1rc 和 b3rc。兩者互換後,寫出來仍然是 a1rc 和 b3rc。

左:開局。右:紅方 a1 的車和 b3 的炮互換了位置。舊的鍵分不出兩者。

十四步合法著法,判出一盤和棋

紅方用五步完成互換,同時黑方把一個車走出去再走回來;然後雙方各把一個馬跳出去再跳回來:

走完舊計數實際計數
開局1開局局面:1
互換,每方 5 步2互換局面:1
馬跳出再跳回3,判和互換局面:2

十四步合法著法,網站就判了和棋。沒有棋手回報過這個問題;它是在給揭棋加上重複局面規則時,閱讀這段程式碼發現的。

修復:把角色名完整寫出

# red chariot on a1: "a1:r.chariot"
parts.append(sq + ":" + p.color[0] + "." + p.role)

一個測試會走完這十四步,並檢查對局仍在繼續。迷霧國際象棋(王 king 和馬 knight 都是 k)和鴨子象棋裡也有同樣的簡寫;兩者都已修復。

對網站意味著什麼

已結束的對局:沒有一盤改變。用修正後的鍵重放,全部 29 盤象棋重複局面和棋、2 盤長將判負、2 盤鴨子象棋和棋和 19 盤迷霧國際象棋和棋,結果都一樣。

新對局:象棋、迷霧象棋、迷霧國際象棋和鴨子象棋,只有在同一局面真正出現三次時,才會因重複局面結束。

謎題:謎題挖掘器的查重會同時識別新舊兩種寫法,所以已發布的謎題不會被當成新題再出現。

用縮寫拼成的鍵需要一項檢查,而這項檢查從任何單個縮寫上都看不出來:沒有兩個名字縮寫成同一個東西。手寫的字母表在有人為車選定 r 的那一刻,就做了這項檢查。role[0] 從來沒有做過。