存储玩家回合Zobrist哈希
Storing player turn in Zobrist hash
我目前正在实现一个中文Checkers最小最大算法中的换位表。在中国跳棋中,没有棋子被捕获,棋盘在功能上有81个空格大。玩家轮流在棋盘上移动棋子。
该过程的一部分涉及为董事会状态创建哈希。到目前为止,我已经有了一个有效的方法,可以为每个板状态创建(希望)唯一的散列:
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)
}
更重要的是,我在applyMove函数(和undoMove函数)中增量执行此操作:
applyMove(int to, int from) {
//Undo the 'from' piece in the hash
myHash ^= randoms[from][board[from]];
// Apply the move
std::swap(board[from], board[to]);
//Add the 'to' piece to the hash
myHash ^= randoms[to][board[to]];
// Update whose turn it is
swapTurn();
}
这是因为XOR函数的可逆性。
我现在遇到的问题是,哈希函数不存储轮到谁。也就是说,你可以有两个相同的游戏板,但它们在最小-最大算法中会返回不同的值,因为一个试图最大化分数,另一个试图最小化分数
基本上,我的问题是:我如何将玩家的回合存储在增量生成的哈希函数中,同时保持完美反转的能力(最好是成本低廉)?假设玩家的回合是一个整数而不是布尔值,因为游戏最终将有6名玩家而不是两名玩家。
您可以使用填充有伪随机值的turns[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]];
值得一提的是,您可以将turn状态存储在哈希的开头。。。
inline bool GetTurn(int hash){
return (bool)(hash & 1);
}
并且数组中的Zobrist散列密钥的最低有效位都为0,例如[[0x2348dec2, 0x93857e34, ....] ...]
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 使用Qt C++计算类似Git的SHA1哈希
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 用C++将哈希表写入文件并从文件中恢复
- c++找不到具有相同哈希的无序集合元素
- 哈希文件递归并保存到矢量Cryptopp中
- 对 pair<pair<int,int>pair<int,int unordered_map进行哈希处理>>
- 直接在 unordered_map 的方法中使用哈希,而不是生成哈希的用户定义对象
- 如何为字符串生成唯一但一致的 N 位哈希(小于 64 位)?
- 使用对象的基类部分模板专用化对对象进行哈希处理::哈希
- boost::包含提升单元的元组的哈希值
- 使用 Key 对 C++ 中的哈希映射进行排序. 无法排序
- C++中的并发哈希表
- 哈希映射使用 nullptr c++ 初始化节点的动态数组
- 在具有开放寻址的哈希表中插入节点 [优化逻辑]
- 与C++哈希表的基础知识混淆
- 如何为位集找到/实现一个好的哈希函数
- 对于短字符串来说,这是一个很好的哈希函数吗?
- 存储玩家回合Zobrist哈希