You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

国际象棋Zobrist Hashing为何单独处理王车易位、吃过路兵等状态?

Zobrist哈希的核心设计目标是:让所有规则层面不等价的对局状态,对应不同的哈希值(64位随机数下碰撞概率低到可以忽略)。你之前理解的「棋子+格位」的随机数,只覆盖了棋盘上棋子位置这一个状态维度,漏掉了其他同样会影响合法走法、胜负判定的独立状态,自然会出现哈希碰撞,这几个额外随机数就是用来补全这些维度的。


各个额外随机数的作用逻辑

1. 标识当前走子方为黑方的随机数

棋盘上棋子位置完全一致的两个状态,轮到白方走和轮到黑方走是完全不等价的。
举个最极端的例子:白王正处于被黑将军的状态,如果轮到白方走,当前局面是白方必须应将的常规局面;如果轮到黑方走,说明黑方已经完成将杀,直接获胜。这两个状态棋子位置100%相同,但结果天差地别,不做区分的话置换表会直接读写错误数据。
实现的时候只需要在黑方走棋的回合给全局哈希异或上这个随机数,换白方走的时候再异或一次抵消即可,开销为0。

2. 4个王车易位权限对应的随机数

不要觉得「王和车都在初始位置就代表有易位权」——只要王曾经移动过,哪怕之后挪回初始位置,也会永久失去易位资格;对应侧的车曾经移动过再挪回原位,同理。
这种场景下棋子位置和拥有易位权的初始状态完全一致,但合法走法少了易位选项,属于完全不同的局面。4个随机数刚好对应白方王翼、白方后翼、黑方王翼、黑方后翼四个独立的易位权限,某一侧权限消失时异或对应随机数即可,增量更新非常方便。

3. 8个吃过路兵列对应的随机数

吃过路兵是只有在对方刚把兵从初始行推两格的那个回合才生效的特殊走法。举个例子:黑兵刚从d7走到d5时,e5位的白兵拥有吃过路兵的权利;但如果黑兵是更早的回合走到d5的,哪怕所有棋子位置和前一种情况完全一样,白兵也没有这个吃子权限。
之所以只编码列不编码具体格位,是因为合法的过路兵目标位置是固定的:只要存在可吃的过路兵,它一定位于刚移动的兵所在列、距离己方兵线一行的位置,知道列就能确定唯一位置,没必要多生成冗余随机数。


其他棋类实现时的通用判断标准

你不需要死记硬背要加哪些随机数,只要卡一个判断原则就不会错:

如果两个局面棋子位置完全相同,但存在至少一种合法走法序列,会导向不同的胜负/和棋结果,那么区分这两个局面的状态维度,就必须加入Zobrist随机数数组。

常见的容易遗漏的必要维度包括:

  • 当前轮次的走子方(所有双人回合制棋类都需要)
  • 临时/永久生效的特殊走法权限(比如围棋的当前禁着劫点、将棋的持驹打入相关限制)
  • 直接影响合法走法的特殊规则状态

如果某个状态只影响终局计数(比如国际象棋的50步和棋回合数),不影响走法生成和局面静态估值,可以根据自己的置换表需求选择是否编码,不会导致核心逻辑错误。

另外要注意:所有额外状态的编码逻辑和棋子位置编码完全一致,状态生效时异或对应随机数,状态消失时再异或一次就能抵消,增量更新的性能开销和移动棋子没有区别。


内容的提问来源于stack exchange,提问作者Carmellose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 18:33:31