def seek_position(self, position): # Calculate the position hash. hasher = ZobristHasher(ZobristHasher.POLYGLOT_RANDOM_ARRAY) key = hasher.hash_position(position) # Do a binary search. start = 0 end = len(self) while end >= start: middle = (start + end) / 2 self.seek_entry(middle) raw_entry = self.next_raw() if raw_entry[0] < key: start = middle + 1 elif raw_entry[0] > key: end = middle - 1 else: # Position found. Move back to the first occurence. self.seek_entry(-1, 1) while raw_entry[0] == key and middle > start: middle -= 1 self.seek_entry(middle) raw_entry = self.next_raw() if middle == start and raw_entry[0] == key: self.seek_entry(-1, 1) return raise KeyError()
def get_entries_for_position(self, position): hasher = ZobristHasher(ZobristHasher.POLYGLOT_RANDOM_ARRAY) position_hash = hasher.hash_position(position) # Seek the position. Stop iteration if no entry exists. try: self.seek_position(position) except KeyError: raise StopIteration() # Iterate. while True: entry = self.next() if entry["position_hash"] == position_hash: yield entry else: break
def __hash__(self): hasher = ZobristHasher(ZobristHasher.POLYGLOT_RANDOM_ARRAY) return hasher.hash_position(self)