How can I refer to the properties of a dictionary key of a reference type?

I am working on a chess engine, and now I am implementing a table of transpositions (a set of positions already evaluated on the boards from previous moves). The general idea is that when moving, I check the transpose table for the corresponding position. If it exists, I skip the expensive evaluation process and simply pull the previously calculated results from the transposition table. If it does not exist, I do the necessary calculations, and then add it to the transpose table for future reference.

For me, this sounds like a task for a hash or a dictionary. I decided to use a dictionary. I wanted the key to be the class representing my board, and the value, which should be int count, how many times the position was encountered. The reason for counting is the ability to detect triple repetition. If the same position occurs three or more times, the player has the opportunity to call a draw. Using a dictionary instead of a hash allows me to greatly simplify the detection of triple repetition by combining it with my transpose table.

To do this, I made a class that represents the state of the board, overrides Equals () and GetHashCode (). It works great, and now I can track all the historical conditions in which the game previously met.

My problem is that I need to have access to the properties of the key object in the dictionary. I see if there is a match (using the .ContainsKey (...) method and my logic Equals () / GetHashCode ()), but now I need to get the previously mentioned calculated values ​​(saved as a state property of my board as a state object) from the key .

I was able to come up with:

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

It works, but it seems awkward to me. The whole point of the transposition table is to speed up the recursive search for millions of consecutive board states. Querying a dictionary for each match just sounds counter-intuitive. Is there a better way to do this?

EDIT:

As already noted, my hash may not be ideal due to the sheer number of actual board states. My Equals () overrides the verification of the second alternatively generated hash to reduce the potential for collisions. My above β€œdecision” is erroneous because it relies on an imperfect hash. I should have used:

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

Stupid blunder on my part. However, I am not a fan of search dictionaries.

+4
source share
1 answer

One option is to simply keep the key reference in the dictionary value, as well as the actual dictionary value, for example:

 Dictionary<BoardState, Tuple<BoardState, int>> 

Then whenever you add an object, add the same object to the value with respect to the key:

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

Another option (which is probably the best design) is to split the board state object into two different types. Have one that really represents the state of the board (this should be unchanged), and another that contains other information about this state, including the time at which it occurred, and any other mutable attributes that may apply to your specific application. This will prevent you from accessing the dictionary key.

+2
source

All Articles