Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在Zobrist散列中存储玩家回合_C++_Algorithm_Hash_Hash Function_Game Ai - Fatal编程技术网

C++ 在Zobrist散列中存储玩家回合

C++ 在Zobrist散列中存储玩家回合,c++,algorithm,hash,hash-function,game-ai,C++,Algorithm,Hash,Hash Function,Game Ai,我目前正在中国Checkers minimax算法中实现一个换位表。在中国跳棋中,没有棋子被捕获,棋盘在功能上有81个空格。玩家轮流在棋盘上移动棋子 该过程的一部分涉及为board状态创建哈希。到目前为止,我已经有了一个有效的方法,可以为每个板状态创建(希望是)唯一的散列: myHash = 0; //randoms[81][3] is an array filled completely with pseudorandom values for (int x = 0; x < 81

我目前正在中国Checkers minimax算法中实现一个换位表。在中国跳棋中,没有棋子被捕获,棋盘在功能上有81个空格。玩家轮流在棋盘上移动棋子

该过程的一部分涉及为board状态创建哈希。到目前为止,我已经有了一个有效的方法,可以为每个板状态创建(希望是)唯一的散列:

 myHash = 0;
 //randoms[81][3] is an array filled completely with pseudorandom values
 for (int x = 0; x < 81; x++) {
      myHash ^= randoms[x][board[x]]; 
      //board[x] is the piece at space x (1=player1 piece, 2=player2 piece, 0=empty)
 }
这是因为XOR函数具有可逆性

我现在遇到的问题是,哈希函数不存储轮到谁了。也就是说,您可以有两个相同的游戏板,但它们在minimax算法中会返回不同的值,因为一个尝试最大化分数,另一个尝试最小化分数


基本上,我的问题是:如何在增量生成的散列函数中存储玩家的回合,同时保持完美(最好是便宜)反转的能力?假设玩家的回合是整数而不是布尔值,因为游戏最终将有6名玩家而不是两名玩家。

您可以使用填充伪随机值的
回合[6]
数组:

unsigned n = 6;  // number of players;

myHash ^= turns[active_player];           // 'undo' the old active player
active_player = (active_player + 1) % n;  // new active player's index
myHash ^= turns[active_player];           // 'add' new active player
这类似于工件位置增量更新,适用于
n
∈ [2,6]


作为旁注

通常,Zobrist散列是通过扫描片段的位置来完成的,排除空方块。空方块的位置没有显式散列

因此,您可以使用更小(更便于缓存)的阵列。比如:

std::uint64_t randoms[81][2];  // two players

for (unsigned x(0); x < 81; ++x)
  if (board[x])
    myHash ^= randoms[x][board[x]]; 
std::uint64_t randoms[81][2];//两名球员
for(无符号x(0);x<81;++x)
如果(电路板[x])
myHash^=randoms[x][board[x]];

无论如何,您可以在散列的开头将回合状态存储为一个位

inline bool GetTurn(int hash){
  return (bool)(hash & 1);
}

并且让数组中的Zobrist散列键的最低有效位都是0,例如,
[[0x2348dec2,0x93857e34,…]

谢谢,这应该可以很好地工作!此外,我没有考虑到事实上,我只需要散列填充方格,这肯定会节省一些空间。
inline bool GetTurn(int hash){
  return (bool)(hash & 1);
}