【问题标题】:Generating unique position key for every chess position为每个国际象棋位置生成唯一的位置密钥
【发布时间】:2020-03-07 06:08:34
【问题描述】:

我正在尝试创建一个国际象棋引擎。有人告诉我,我们可以通过散列单个棋子键来为任何国际象棋位置生成唯一键。它就像特定方格上的特定棋子具有唯一的 64 位密钥。然后我们应该对位置中存在的每个片段的片段键进行异或。

忽略关于国际象棋位置的castling和en Passant square信息,这是我被告知生成位置键的方式(用C语言)

typedef unsigned long long U64;
#define RAND_64 (   (U64) rand() + \
                    (U64) rand() << 15 + \
                    (U64) rand() << 31 + \
                    (U64) rand() << 45 \
                )

这是从上面声明的 RAND 64 生成片段密钥的方式...

int index, index2;
U64 pieceKeys[12][64]; // For 12 pieces on every possible square.

for(index = 0; index<12; index++) {
    for(index2 = 0; index2<64; index2++) { 
        pieceKeys[index][index2] = RAND_64;
    }
}

我的问题是,这里不可能为 2 块上的 2 块生成相同的块密钥。如果发生这种情况,那么当我们通过对片段键进行 XOR 来创建位置键时就会产生歧义。

我说的对吗?如果是这样,我该如何解决这个潜在的问题?

【问题讨论】:

  • 这里没有实际的执行代码,除了数组数组的声明。也许您可以展示 RAND_64 如何在您编写的代码中用作问题的一部分。
  • 好的,我也会添加那部分
  • Chess 上有一个与此相关的问题(这可能是比这里更好的地方):engines - How to generate hash keys for chess positions
  • 我只是想在那个论坛上提问。但我发现像 C 语言这样的东西没有标签。散列等。所以我认为这可能是更好的地方。
  • 由于您使用(三个)rand() 填充 Zobrist 表,因此两个条目将获得相同的值并非不可能(但极不可能)。但是,您可以测试这些重复项,并从 rand() 中为每个碰巧具有重复值的单元格提取一组新值。

标签: c random hash chess


【解决方案1】:

只有 6 种不同类型的棋子,然后是黑色和白色。用 1 位表示黑色或白色,3 位表示棋子类型,7 位表示平方数,例如:

// square numbes are 0x0000 thru 0x007F
#define BLACK 0x0080
#define WHITE 0x0000

#define KING   0x0100
#define QUEEN  0x0200
#define ROOK   0x0400
#define BISHOP 0x0800
#define KNIGHT 0x1000
#define PAWN   0x2000

#define PIECE_MASK    0x3F00
#define SQUARE_MASK   0x007F

并使用位掩码来确定它们:

int color= board[x][y] & BLACK; // non zero if black; zero if white
int is_king= board[x][y] & KING;
int squarenum= board[x][y] & SQUARE_MASK;

int piece= board[x][y] & PIECE_MASK;
switch (piece>>8) {
    case 1: //King
    case 2: //Queen
    case 4: //Rook
    case 8: //Bishop
    case 16://Knight
    case 32://Pawn
}

【讨论】:

  • 变量 square 应该在“int color = square & BLACK;”中表示什么?
  • 那当然是一块板子。将其替换为 board[x][y]。
  • 你肯定只需要 6 位来表示每件的位置吗?并且您使用 6 位而不是 3 位作为片段类型。所以每个片段总共只需要 10 位。乘以 32 块,你得到 320 位的棋盘位置,再加上 1 位来编码在那个位置是黑色还是白色。这没有冲突。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-20
相关资源
最近更新 更多