Artificial intelligence 为棋盘生成唯一标识符

Artificial intelligence 为棋盘生成唯一标识符,artificial-intelligence,checksum,chess,Artificial Intelligence,Checksum,Chess,我在寻找一种类似于棋盘校验和的东西,棋子在特定的位置。我想看看一个动态编程或记忆解决方案对于一个AI棋手来说是否可行。唯一标识符将用于轻松检查两块板是否相等,或用作阵列中的索引。感谢您的帮助。如果两个游戏通过不同的移动或移动顺序实现相同的配置,它们仍然应该是“相等的”。e、 g.只要位置相同,就不必区分哪个典当在特定位置。您似乎并不是真的想要散列,而是唯一且正确地区分这些板状态 一种方法是使用64x12square by piecetype成员矩阵。您可以将其存储为位向量,然后比较向量以进行检查

我在寻找一种类似于棋盘校验和的东西,棋子在特定的位置。我想看看一个动态编程或记忆解决方案对于一个AI棋手来说是否可行。唯一标识符将用于轻松检查两块板是否相等,或用作阵列中的索引。感谢您的帮助。

如果两个游戏通过不同的移动或移动顺序实现相同的配置,它们仍然应该是“相等的”。e、 g.只要位置相同,就不必区分哪个典当在特定位置。您似乎并不是真的想要散列,而是唯一且正确地区分这些板状态

一种方法是使用64x12
square by piecetype
成员矩阵。您可以将其存储为位向量,然后比较向量以进行检查。e、 g.向量中的前64个地址可能会显示棋盘上包含棋子的位置。接下来的64个显示包含骑士的位置。您可以让前6个部分显示白色片段的成员资格,最后6个部分显示黑色片段的成员资格

二进制成员矩阵伪码:

bool[] memberships = zeros(64*12);
move(pawn,a3,a2);

def move(piece,location,oldlocation):
    memberships(pawn,location) = 1;
    memberships(pawn,oldlocation) = 0;
half[] memberships = zeros(64);
memberships[8] = 1;        // white pawn at location a2
memberships[0] = 2;        // white rook at location a1
...
memberships[63] = 11;      // black knight at location g8
memberships[64] = 12;      // black rook at location h8
这很麻烦,因为您必须小心如何实现它。e、 确保每个玩家最多只能有一个国王。优点是只需要768位来存储一个状态

另一种方法是长度为64的整数向量,表示电路板位置的矢量化地址。在这种情况下,前8个地址可能代表电路板第一行的状态

非二进制成员矩阵伪码:

bool[] memberships = zeros(64*12);
move(pawn,a3,a2);

def move(piece,location,oldlocation):
    memberships(pawn,location) = 1;
    memberships(pawn,oldlocation) = 0;
half[] memberships = zeros(64);
memberships[8] = 1;        // white pawn at location a2
memberships[0] = 2;        // white rook at location a1
...
memberships[63] = 11;      // black knight at location g8
memberships[64] = 12;      // black rook at location h8
非二进制向量的好处在于,您没有足够的自由将多个片段意外地分配到一个位置。缺点是现在存储每个状态的空间更大。较大的表示形式在进行相等比较时会比较慢。(在我的示例中,假设每个向量位置存储一个16位半字,与二进制向量的768位相比,我们得到64*16=1014位来存储一个状态)

无论哪种方式,您都可能希望列举每个部件和电路板位置

enumerate piece {
    empty = 0;
    white_pawn = 1;
    white_rook = 2;
    ...
    black_knight = 11;
    black_rook = 12;
}
enumerate location {
    a1 = 0;
    ...
}

检验相等性只是比较两个向量。

有64个正方形。国际象棋中有十二种不同的数字可以占据一个正方形,加上没有数字占据它的可能性。等于13。您需要4位来表示这13位(2^4=16)。因此,您将得到32个字节来明确地存储棋盘

如果您想简化处理,可以存储64个字节,即每平方码存储一个字节,因为字节更易于读取和写入

编辑:我已经阅读了一些关于国际象棋的更多内容,并得出以下结论:如果自上次捕获或典当移动以来的所有棋盘都相同,那么两个棋盘是相同的。这是因为三重重复规则。如果第三次棋盘在游戏中看起来完全一样,可以要求平局。因此,尽管在两场比赛中看到同一个棋盘,但在一场比赛中做出某种动作以避免平局可能被认为是不幸的,而在另一场比赛中则没有这种危险

这取决于你,你想怎么做。由于之前要存储的电路板数量可变,因此您需要一个长度可变的唯一标识符。好吧,也许你放轻松点,对这件事视而不见,只存储最后五个动作,直接检测可能导致位置第三次重复的重复动作,这是最常见的原因

如果你想在棋盘上存储移动:有64x63=4032个可思考的移动(需要12位),但其中很多是非法的。如果我计算正确,有1728个合法移动(例如A1->A2=legal,A1->D2非法),可以容纳11位。不过,我还是会选择12位,以便通过存储A1->A2的0/1和H7->H8的62/63,尽可能简化解释

然后是50步规则。你不必在这里存储移动。只有上次捕获或典当后的移动次数从0移动到50(这就足够了;不管是50、51还是更多)。所以,这个还有六位

最后:黑人还是白人?可通行的典当?可浇铸的车?为此增加一些位(或扩展13个占用以节省一些位)


再次编辑:因此,如果您想使用该棋盘与其他匹配的棋盘进行比较,则“两个棋盘仅相同,如果自上次捕获或典当移动以来的所有先前棋盘也相同”适用。但是,如果您只想在同一游戏中检测位置的重复,则只需使用15个占用空间x 64个正方形加上一位作为移动对象就可以了。

您可以使用校验和,如md5、sha,只需将棋盘单元格作为文本传递,如:

TKBQKBHT
........
........
........
tkbqkbht
并获取生成文本的校验和

一块电路板与另一块电路板之间的校验和将不同,没有任何相关值,此时创建唯一字符串(或位数组)可能是最好的方法:

TKBQKBHT........................tkbqkbht

因为它也将是唯一的,并且很容易与其他的进行比较。

一种广泛用于董事会位置的校验和是

对于任何一个国际象棋位置,它几乎是唯一的索引号,要求两个相似的位置生成完全不同的索引。这些索引号用于更快、节省空间的换位表/开卷

您需要一组随机生成的位字符串:

  • 每一个正方形每件一个
  • 一个用于指示要移动的一侧
  • 四是铸造权
  • 八个用于有效的临时广场(如有)的文件
如果要获取某个位置的Zobrist哈希代码,必须
xor
链接到给定功能的所有随机数(详细信息:和)

例如,起始位置:

[Hash for White Rook on a1] xor [White Knight on b1] xor ... ( all pieces )
... xor [White castling long] xor ... ( all castling rights )
XOR
允许在make期间快速增量更新哈希键/