package com.captstudios.games.tafl.core.es.model.ai.optimization.transposition;
import java.util.LinkedHashMap;
import java.util.Map;
import com.captstudios.games.tafl.core.enums.EvaluationType;
public class TranspositionTable {
private class LruCache extends LinkedHashMap<TranspositionTableEntry, TranspositionTableEntry> {
private static final long serialVersionUID = -7590996424683869190L;
private final int maxEntries;
TranspositionTableEntry evictedKey;
TranspositionTableEntry evictedValue;
public LruCache(final int maxEntries) {
super(maxEntries + 1, 1.0f, true);
this.maxEntries = maxEntries;
}
@Override
protected boolean removeEldestEntry(final Map.Entry<TranspositionTableEntry, TranspositionTableEntry> eldest) {
if (super.size() > maxEntries) {
evictedKey = eldest.getKey();
evictedValue = eldest.getValue();
return true;
}
return false;
}
}
LruCache lruCache;
TranspositionTableEntry lookUp;
TranspositionTableEntry recycledKey;
TranspositionTableEntry recycledValue;
public TranspositionTable(int size) {
lruCache = new LruCache(size);
lookUp = new TranspositionTableEntry();
}
/**
* Verify whether there is a stored evaluation for a given board.
* If so, return TRUE and copy the appropriate values into the
* output parameter
*/
public TranspositionTableEntry lookupBoard(int hash) {
lookUp.hash = hash;
return lruCache.get(lookUp);
}
/** Store a good evaluation found through alphabeta for a certain board
* position
*/
public boolean storeBoard(int hash, int eval, EvaluationType evalType) {
TranspositionTableEntry key = recycledKey;
TranspositionTableEntry value = recycledValue;
if (key == null) {
key = new TranspositionTableEntry();
value = new TranspositionTableEntry();
}
key.hash = hash;
value.hash = hash;
value.eval = eval;
value.evalType = evalType;
lruCache.put(key, value);
if (lruCache.evictedKey != null) {
recycledKey = lruCache.evictedKey;
recycledValue = lruCache.evictedValue;
lruCache.evictedKey = null;
lruCache.evictedValue = null;
}
return true;
}
}