我正在研究國際象棋引擎,目前我正在實施轉位表(一組已經評估過的棋盤位置)。總的想法是,當做出移動時,我檢查換位表的匹配位置。如果存在,我跳過昂貴的評估過程,只需從轉置表中提取以前計算的結果。如果它不存在,我會進行所需的計算,然後將其添加到轉位表中以備將來參考。如何引用引用類型字典鍵的屬性?
對我來說,這聽起來像一個哈希集或字典的工作。我決定了字典。我希望關鍵是成爲代表我的董事會的班級,並且該值應該是遇到位置次數的整數。計數的原因是能夠檢測到三次重複繪製。如果同一位置已經遇到過三次或更多次,玩家可以選擇打平。使用字典而不是哈希集合,通過將它與轉置表相結合,可以大大簡化對三次重複繪製的檢測。
爲了做到這一點,我已經讓表示電路板狀態的類覆蓋了Equals()和GetHashCode()。它工作得很好,現在我能夠跟蹤以前遇到的所有歷史狀態。
我的問題是我需要能夠訪問字典中的鍵對象的屬性。我可以通過使用.ContainsKey(...)方法和我的Equals()/ GetHashCode()邏輯)查看是否存在匹配,但現在我需要提取前面提到的計算值(作爲我的板的公共屬性存儲狀態對象)。
我能想出:
BoardState board = TranspositionTable.Keys.FirstOrDefault(tt => tt.GetHashCode() == this.GetHashCode());
這工作,但感覺笨重給我。換位表的全部內容是加速對數百萬連續棋盤狀態的遞歸搜索。查詢每場比賽的字典聽起來都是違反直覺的。有一個更好的方法嗎?
編輯:
由於它已經指出的那樣,我的哈希不能是完美的,由於有效的板狀態的數量巨大。 My Equals()覆蓋會檢查第二個備選生成的散列,以減少衝突的可能性。我上面的'解決方案'是有缺陷的,因爲它依賴於不完美的哈希。我應該使用:
BoardState board = TranspositionTable.Keys.FirstOrDefault(tt => tt.Equals(this));
我的一個愚蠢的疏忽。不過,我不是一個查詢字典的粉絲。
字典中的關鍵字究竟是什麼?可以使'GetHashCode()'的結果成爲關鍵嗎?如果是這樣,那麼這變得更加「自然」來處理...... – Yahia 2013-02-11 17:52:18
@Yahia哈希代碼,由於其本質,不是唯一的,所以你需要支持一個對象列表作爲值並使用'Equals'用該散列碼查找*真*相等的對象。 – Servy 2013-02-11 17:53:10
@Servy,這是真的......但OP似乎很滿意匹配散列碼的任何結果(根據顯示的代碼)... – Yahia 2013-02-11 17:54:33