gpt4 book ai didi

c# - 如何引用引用类型字典键的属性?

转载 作者:行者123 更新时间:2023-11-30 12:31:00 31 4
gpt4 key购买 nike

我正在研究国际象棋引擎,目前正在实现换位表(一组已根据过去的棋步评估过的棋盘位置)。一般的想法是,当移动时,我检查换位表以找到匹配的位置。如果存在,我将跳过代价高昂的评估过程,直接从换位表中提取之前计算的结果。如果不存在,我会进行所需的计算,然后将其添加到换位表中以备将来引用。

对我来说,这听起来像是哈希集或字典的工作。我决定看字典。我希望键是代表我的板的类,而值是遇到该位置的次数的整数计数。计数的原因是为了能够检测三次重复绘制。如果同一局面出现三次或更多次,玩家可以选择平局。使用字典而不是哈希集,通过将其与我的换位表相结合,我可以极大地简化三次重复绘制的检测。

为了做到这一点,我让代表棋盘状态的类覆盖了 Equals() 和 GetHashCode()。它工作得很好,我现在能够跟踪游戏之前遇到的所有历史状态。

我的问题是我需要能够访问字典中键对象的属性。我可以查看是否存在匹配(通过使用 .ContainsKey(...) 方法和我的 Equals()/GetHashCode() 逻辑),但现在我需要提取前面提到的计算值(存储为我的板的公共(public)属性状态对象)来自 key 。

我能够想出:

BoardState board = TranspositionTable.Keys.FirstOrDefault(tt => tt.GetHashCode() == this.GetHashCode());

这行得通,但我觉得很笨拙。换位表的全部意义在于加速数百万个连续棋盘状态的递归搜索。为每个匹配项查询字典听起来有悖常理。有更好的方法吗?

编辑:

正如有人指出的那样,由于有效的棋盘状态数量众多,我的哈希不可能是完美的。我的 Equals() 覆盖检查第二个交替生成的哈希值以减少冲突的可能性。我上面的“解决方案”是有缺陷的,因为它依赖于不完美的散列。我应该使用:

BoardState board = TranspositionTable.Keys.FirstOrDefault(tt => tt.Equals(this));

我的一个愚蠢的疏忽。不过,我不喜欢查询字典。

最佳答案

一个选择是在字典的值中保留对键的引用,以及字典的实际值,如下所示:

Dictionary<BoardState, Tuple<BoardState, int>>

然后每当你添加一个对象时,将相同的对象添加到与键相同的值:

Dictionary<BoardState, Tuple<BoardState, int>> boards = 
new Dictionary<BoardState,Tuple<BoardState,int>>();
BoardState board = new BoardState();
boards.Add(board, Tuple.Create(board, 1));

另一种选择(这可能是更好的设计)是将您的棋盘状态对象分解为两种不同的类型。有一个真的只代表棋盘的状态(这应该是不可变的),另一个保存关于该状态的其他信息,包括它发生的时间和任何其他可能适用的可变属性到您的具体应用。这将阻止您访问字典键。

关于c# - 如何引用引用类型字典键的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14817847/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com