В компьютерных шахматах много исследований, и способ создания уникального хэша для позиции - это хорошо известная проблема с универсальным решением, используемым практически каждым шахматным движком.
Что вам нужно сделать, это использовать Zobrist Hashing , чтобы создать уникальный (не совсем уникальный, но мы увидим позже, почему это не проблема на практике) ключ для каждой позиции. Алгоритм , применяемый к шахматам, объясняется здесь .
Когда вы запускаете свою программу, вы создаете то, что мы называем ключами зобриста. Это 64-битные случайные целые числа для каждой пары кусок / квадрат. В C вы бы имели двухмерный массив, подобный этому:
unsigned long long zobKeys[NUMBER_OF_PIECES][NUMBER_OF_SQUARES];
Каждый из этих ключей инициализируется хорошим генератором случайных чисел (Предупреждение: генератор случайных чисел, предоставляемый с gcc или VC ++, недостаточно хорош, используйте реализацию Mersenne Twister ).
Когда доска пуста, вы произвольно устанавливаете ее хеш-ключ на 0, затем, когда вы добавляете фигуру на доску, скажем, «Ладья» на А1, вы также обновляете хеш-ключ, делая XOR клавишу «Зобрист» для ладьи на А1 с хеш-ключ доски. Как это (в C):
boardHash = boardHash ^ zobKeys[ROOK][A1];
Если вы позже удалите ладью из этого квадрата, вам нужно будет повернуть вспять то, что вы только что сделали, поскольку XOR можно повернуть вспять, применив его снова, вы можете просто использовать ту же команду еще раз, когда удаляете фигуру:
boardHash = boardHash ^ zobKeys[ROOK][A1];
Если вы перемещаете фигуру, скажем, ладью на турнире A1, в B1, вам нужно сделать два XOR, один для удаления ладьи на A1 и один для добавления ладьи на B2.
boardHash = boardHash ^ zobKeys[ROOK][A1] ^ boardHash ^ zobKeys[ROOK][B1];
Таким образом, каждый раз, когда вы модифицируете доску, вы также изменяете хеш. Это очень эффективно. Вы также можете вычислять хеш из scatch каждый раз, сохраняя zobKeys, соответствующие всем фигурам на доске. Вам также понадобится XOR положение пешки, которую можно взять в пассивном режиме, и статус способностей ладьи с обеих сторон. Вы делаете это так же, создавая ключи зобриса для каждого возможного значения.
Этот алгоритм не гарантирует, что каждая позиция имеет уникальный хеш, однако, если вы используете хороший генератор псевдослучайных чисел, вероятность столкновения настолько мала, что даже если вы позволите вашему двигателю играть всю жизнь шансов на столкновение практически нет.
редактировать: я просто красный, что вы пытаетесь реализовать это для варианта шахмат, который имеет вне фигур. Хеширование Zobrist - все еще правильное решение для вас. Вам нужно будет найти способ включить эту информацию в хеш. Например, вы можете иметь несколько ключей для готовых вещей:
unsigned long long offTheBoardZobKeys[NUMBER_OF_PIECE][MAXIMUM_NUMBER_OF_ON_PIECE_TYPE];
Если у вас есть 2 лапы с доски и вы положили одну из этих пешек на a2, вам придется сделать 2 операции:
// remove one pawn from the off-the-board
boardHash = boardHash ^ offTheBoardZobKeys[WHITE_PAWN][numberOfWhitePawsOffTheBoard];
// Put a pawn on a2
boardHash = boardHash ^ zobKeys[WHITE_PAWN][A2];