3

我目前正在我的国际象棋引擎中添加转置表,并且在增量更新 Zobrist 键时遇到了问题。我做了一些研究并实现了基本想法,但它的表现并不像我预期的那样。我遇到的问题是等效的棋盘位置并不总是具有相同的键。例如,在起始位置,如果两个玩家都移动了一个马然后将其移回,那么关键将与起始位置的不同。但是,再次执行此操作(移动骑士)并返回起始位置导致原始密钥。因此,这种序列的周期似乎是每个玩家 4 步,而它应该只是 2。

有没有人遇到过这样的问题或可以想到解决方案?我已经包含了我的制作/取消制作方法的相关部分。我不包括边移动、易位权等;它们不应该影响我提出的具体案例。HashValue 存储随机值,第一个索引是棋子类型,第二个索引是正方形。

void Make(Move m) {
    ZobristKey ^= HashValue[Piece[m.From].Type][m.From];
    ZobristKey ^= HashValue[Piece[m.From].Type][m.To];
    ZobristKey ^= HashValue[Piece[m.To].Type][m.To];
    //rest of make move
}

void Unmake(Move m) {
    ZobristKey ^= HashValue[m.Captured.Type][m.To];
    ZobristKey ^= HashValue[Element[m.To].Type][m.To];
    ZobristKey ^= HashValue[Element[m.To].Type][m.From];
    //rest of unmake
}
4

1 回答 1

3
Make_a_move() {
    hashval ^= Zobrist_array[oldpos][piece];
    hashval ^= Zobrist_array[newpos][piece];
    /* if there is a capture */
    hashval ^= Zobrist_array[otherpos][otherpiece];
    }

Undo_a_move() {
    hashval ^= Zobrist_array[oldpos][piece];
    hashval ^= Zobrist_array[newpos][piece];
    /* if there was a capture */
    hashval ^= Zobrist_array[otherpos][otherpiece];
    }

Castling 可以看作是两个动作的总和(显然没有捕获)

升级可以被视为从棋盘上移除一个棋子(从 2 或 7 位置)并添加新棋子(在 1 或 8 位置)

于 2012-04-09T00:21:10.457 回答